Merge ~mitchdz/ubuntu/+source/hibagent:mitch/focal-imdsv2 into ubuntu/+source/hibagent:ubuntu/focal-devel

Proposed by Mitchell Dzurick
Status: Merged
Merge reported by: Mitchell Dzurick
Merged at revision: afb55f8eedeabfeb09d79f4454375566b938d544
Proposed branch: ~mitchdz/ubuntu/+source/hibagent:mitch/focal-imdsv2
Merge into: ubuntu/+source/hibagent:ubuntu/focal-devel
Diff against target: 202 lines (+157/-0)
6 files modified
debian/changelog (+14/-0)
debian/control (+1/-0)
debian/patches/disable-hibernate-test.patch (+18/-0)
debian/patches/do-nothing-if-ODH-is-configured.patch (+77/-0)
debian/patches/series (+3/-0)
debian/patches/use-imdsv2.patch (+44/-0)
Reviewer Review Type Date Requested Status
git-ubuntu import Pending
Review via email: mp+455813@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 6e04bd0..eaa086d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
1hibagent (1.0.1-0ubuntu1.20.04.2) focal; urgency=medium
2
3 * Use imdsv2 and do nothing if ODH is configured (LP: #2043739).
4 - d/p/disable-hibernate-test.patch: disable a test that only works on an
5 actual EC2 instance.
6 - d/p/use-imdsv2: use IMDSv2 instead of IMDSv1. This is important because
7 IMDSv1 is an insecure protocol.
8 - d/control: add python3-requests as Depends.
9 - d/p/do-nothing-if-ODH-is-configured.patch: do nothing if ODH is configured
10 this fixes an issue when this package and ec2-hibinit-agent are installed
11 and configured at the same time.
12
13 -- Mitchell Dzurick <mitchell.dzurick@canonical.com> Thu, 16 Nov 2023 16:19:12 -0700
14
1hibagent (1.0.1-0ubuntu1.20.04.1) focal; urgency=medium15hibagent (1.0.1-0ubuntu1.20.04.1) focal; urgency=medium
216
3 * d/p/lp1896638-set-resume-device-by-partition-uuid: Set resume device17 * d/p/lp1896638-set-resume-device-by-partition-uuid: Set resume device
diff --git a/debian/control b/debian/control
index 25d37a7..74f1d40 100644
--- a/debian/control
+++ b/debian/control
@@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 9),
7 dh-python,7 dh-python,
8 python3-all,8 python3-all,
9 python3-pytest,9 python3-pytest,
10 python3-requests,
10 python3-setuptools11 python3-setuptools
11Standards-Version: 3.9.612Standards-Version: 3.9.6
12X-Python3-Version: >= 3.313X-Python3-Version: >= 3.3
diff --git a/debian/patches/disable-hibernate-test.patch b/debian/patches/disable-hibernate-test.patch
13new file mode 10064414new file mode 100644
index 0000000..9e3c5e7
--- /dev/null
+++ b/debian/patches/disable-hibernate-test.patch
@@ -0,0 +1,18 @@
1IDescription: Skip test needing EC2 instance
2 The polling test now actually needs to be run on an EC2 instance as it tries
3 to contact an HTTP endpoint on a hardcoded link-local IP that matches the monitoring
4 system at AWS. We don't have this in our builders or autopkgtests.
5Author: Simon Chopin <schopin@ubuntu.com>
6Last-Update: 2023-02-16
7---
8This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
9--- a/test/hibagent_test.py
10+++ b/test/hibagent_test.py
11@@ -261,6 +261,7 @@
12 except:
13 pass
14
15+ @unittest.skip("can only run on an actual EC2 instance")
16 def test_itn_polls(self):
17 fi = FakeInitializer()
18 poller = hibagent.ItnPoller("http://localhost:%d/blah" % self.server.port,
diff --git a/debian/patches/do-nothing-if-ODH-is-configured.patch b/debian/patches/do-nothing-if-ODH-is-configured.patch
0new file mode 10064419new file mode 100644
index 0000000..8be4ec2
--- /dev/null
+++ b/debian/patches/do-nothing-if-ODH-is-configured.patch
@@ -0,0 +1,77 @@
1Description: Update the Spot hibernate agent to do nothing if ODH is configured
2Author: Jeongin Cho <achojeon@amazon.com>
3Origin: upstream, https://github.com/aws/ec2-hibernate-linux-agent/commit/2ee4ae3fd1333fb3c9aab25bf02b109c3b7b8d9f
4Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/hibagent/+bug/2043739
5Last-Update: 2023-11-16
6---
7This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
8--- a/agent/hibagent
9+++ b/agent/hibagent
10@@ -18,6 +18,7 @@
11 import struct
12 import sys
13 import syslog
14+import requests
15 from subprocess import check_call, check_output
16 from threading import Thread
17 from math import ceil
18@@ -39,6 +40,9 @@
19 log_to_syslog = True
20 log_to_stderr = True
21
22+IMDS_BASEURL = 'http://169.254.169.254'
23+IMDS_API_TOKEN_PATH = 'latest/api/token'
24+IMDS_SPOT_ACTION_PATH = 'latest/meta-data/hibernation/configured'
25
26 def log(message):
27 if log_to_syslog:
28@@ -511,6 +515,37 @@
29 log("Failed to adjust pm_freeze_timeout to %d. Error: %s" % (timeout, str(e)))
30 exit(1)
31
32+def get_imds_token(seconds=21600):
33+ """ Get a token to access instance metadata. """
34+ log("Requesting new IMDSv2 token.")
35+ request_header = {'X-aws-ec2-metadata-token-ttl-seconds': '{}'.format(seconds)}
36+ token_url = '{}/{}'.format(IMDS_BASEURL, IMDS_API_TOKEN_PATH)
37+ response = requests.put(token_url, headers=request_header)
38+ response.close()
39+ if response.status_code != requests.codes.ok:
40+ return None
41+
42+ return response.text
43+
44+def hibernation_enabled():
45+ """Returns a boolean indicating whether hibernation-option.configured is enabled or not."""
46+
47+ imds_token = get_imds_token()
48+ if imds_token is None:
49+ log("IMDS_V2 http endpoint is disabled")
50+ # IMDS http endpoint is disabled
51+ return False
52+
53+ request_header = {'X-aws-ec2-metadata-token': imds_token}
54+ response = requests.get("{}/{}".format(IMDS_BASEURL, IMDS_SPOT_ACTION_PATH),
55+ headers=request_header)
56+ response.close()
57+ if response.status_code != requests.codes.ok or response.text.lower() == "false":
58+ return False
59+
60+ log("Hibernation Configured Flag found")
61+
62+ return True
63
64 def main():
65 # Parse arguments
66@@ -550,6 +585,11 @@
67
68 log("Effective config: %s" % config)
69
70+ # Let's first check if we need to kill the Spot Hibernate Agent
71+ if hibernation_enabled():
72+ log("Spot Instance Launch has enabled Hibernation Configured Flag. hibagent exiting!!")
73+ exit(0)
74+
75 target_swap_size = config.swap_mb * 1024 * 1024
76 ram_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
77 swap_percentage_size = ram_bytes * config.swap_percentage // 100
diff --git a/debian/patches/series b/debian/patches/series
index 68b33b1..e3435d5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -8,3 +8,6 @@ add-lsb-init-info.patch
8fix-enable-ec2-spot-hibernation.patch8fix-enable-ec2-spot-hibernation.patch
9lp1896638-set-resume-device-by-partition-uuid.patch9lp1896638-set-resume-device-by-partition-uuid.patch
10lp2013336-do-not-modify-GRUB-config-on-GRUB2-systems.patch10lp2013336-do-not-modify-GRUB-config-on-GRUB2-systems.patch
11use-imdsv2.patch
12do-nothing-if-ODH-is-configured.patch
13disable-hibernate-test.patch
diff --git a/debian/patches/use-imdsv2.patch b/debian/patches/use-imdsv2.patch
11new file mode 10064414new file mode 100644
index 0000000..6c91a91
--- /dev/null
+++ b/debian/patches/use-imdsv2.patch
@@ -0,0 +1,44 @@
1Description: IMDS V2 updates
2Author: shivasan@ <shivasan@amazon.com>
3Origin: upstream, https://github.com/aws/ec2-hibernate-linux-agent/commit/559558f28de4456f14b38539eed967df6e1f9217
4Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/hibagent/+bug/2043739
5Last-Update: 2023-11-16
6---
7This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
8--- a/agent/hibagent
9+++ b/agent/hibagent
10@@ -315,16 +315,28 @@
11
12 def poll_for_termination(self):
13 # noinspection PyBroadException
14- response = None
15+ response1 = None
16+ response2 = None
17 try:
18- response = urlopen(self.url)
19- res_str = response.read()
20- return b"hibernate" in res_str
21+ request1 = Request("http://169.254.169.254/latest/api/token")
22+ request1.add_header('X-aws-ec2-metadata-token-ttl-seconds', '21600')
23+ request1.get_method = lambda:"PUT"
24+ response1 = urlopen(request1)
25+
26+ token = response1.read()
27+
28+ request2 = Request(self.url)
29+ request2.add_header('X-aws-ec2-metadata-token', token)
30+ response2 = urlopen(request2)
31+ res = response2.read()
32+ return b"hibernate" in res
33 except:
34 return False
35 finally:
36- if response:
37- response.close()
38+ if response1:
39+ response1.close()
40+ if response2:
41+ response2.close()
42
43 def do_hibernate(self):
44 log("Attempting to hibernate")

Subscribers

People subscribed via source and target branches