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
1diff --git a/debian/changelog b/debian/changelog
2index 6e04bd0..eaa086d 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,17 @@
6+hibagent (1.0.1-0ubuntu1.20.04.2) focal; urgency=medium
7+
8+ * Use imdsv2 and do nothing if ODH is configured (LP: #2043739).
9+ - d/p/disable-hibernate-test.patch: disable a test that only works on an
10+ actual EC2 instance.
11+ - d/p/use-imdsv2: use IMDSv2 instead of IMDSv1. This is important because
12+ IMDSv1 is an insecure protocol.
13+ - d/control: add python3-requests as Depends.
14+ - d/p/do-nothing-if-ODH-is-configured.patch: do nothing if ODH is configured
15+ this fixes an issue when this package and ec2-hibinit-agent are installed
16+ and configured at the same time.
17+
18+ -- Mitchell Dzurick <mitchell.dzurick@canonical.com> Thu, 16 Nov 2023 16:19:12 -0700
19+
20 hibagent (1.0.1-0ubuntu1.20.04.1) focal; urgency=medium
21
22 * d/p/lp1896638-set-resume-device-by-partition-uuid: Set resume device
23diff --git a/debian/control b/debian/control
24index 25d37a7..74f1d40 100644
25--- a/debian/control
26+++ b/debian/control
27@@ -7,6 +7,7 @@ Build-Depends: debhelper (>= 9),
28 dh-python,
29 python3-all,
30 python3-pytest,
31+ python3-requests,
32 python3-setuptools
33 Standards-Version: 3.9.6
34 X-Python3-Version: >= 3.3
35diff --git a/debian/patches/disable-hibernate-test.patch b/debian/patches/disable-hibernate-test.patch
36new file mode 100644
37index 0000000..9e3c5e7
38--- /dev/null
39+++ b/debian/patches/disable-hibernate-test.patch
40@@ -0,0 +1,18 @@
41+IDescription: Skip test needing EC2 instance
42+ The polling test now actually needs to be run on an EC2 instance as it tries
43+ to contact an HTTP endpoint on a hardcoded link-local IP that matches the monitoring
44+ system at AWS. We don't have this in our builders or autopkgtests.
45+Author: Simon Chopin <schopin@ubuntu.com>
46+Last-Update: 2023-02-16
47+---
48+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
49+--- a/test/hibagent_test.py
50++++ b/test/hibagent_test.py
51+@@ -261,6 +261,7 @@
52+ except:
53+ pass
54+
55++ @unittest.skip("can only run on an actual EC2 instance")
56+ def test_itn_polls(self):
57+ fi = FakeInitializer()
58+ poller = hibagent.ItnPoller("http://localhost:%d/blah" % self.server.port,
59diff --git a/debian/patches/do-nothing-if-ODH-is-configured.patch b/debian/patches/do-nothing-if-ODH-is-configured.patch
60new file mode 100644
61index 0000000..8be4ec2
62--- /dev/null
63+++ b/debian/patches/do-nothing-if-ODH-is-configured.patch
64@@ -0,0 +1,77 @@
65+Description: Update the Spot hibernate agent to do nothing if ODH is configured
66+Author: Jeongin Cho <achojeon@amazon.com>
67+Origin: upstream, https://github.com/aws/ec2-hibernate-linux-agent/commit/2ee4ae3fd1333fb3c9aab25bf02b109c3b7b8d9f
68+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/hibagent/+bug/2043739
69+Last-Update: 2023-11-16
70+---
71+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
72+--- a/agent/hibagent
73++++ b/agent/hibagent
74+@@ -18,6 +18,7 @@
75+ import struct
76+ import sys
77+ import syslog
78++import requests
79+ from subprocess import check_call, check_output
80+ from threading import Thread
81+ from math import ceil
82+@@ -39,6 +40,9 @@
83+ log_to_syslog = True
84+ log_to_stderr = True
85+
86++IMDS_BASEURL = 'http://169.254.169.254'
87++IMDS_API_TOKEN_PATH = 'latest/api/token'
88++IMDS_SPOT_ACTION_PATH = 'latest/meta-data/hibernation/configured'
89+
90+ def log(message):
91+ if log_to_syslog:
92+@@ -511,6 +515,37 @@
93+ log("Failed to adjust pm_freeze_timeout to %d. Error: %s" % (timeout, str(e)))
94+ exit(1)
95+
96++def get_imds_token(seconds=21600):
97++ """ Get a token to access instance metadata. """
98++ log("Requesting new IMDSv2 token.")
99++ request_header = {'X-aws-ec2-metadata-token-ttl-seconds': '{}'.format(seconds)}
100++ token_url = '{}/{}'.format(IMDS_BASEURL, IMDS_API_TOKEN_PATH)
101++ response = requests.put(token_url, headers=request_header)
102++ response.close()
103++ if response.status_code != requests.codes.ok:
104++ return None
105++
106++ return response.text
107++
108++def hibernation_enabled():
109++ """Returns a boolean indicating whether hibernation-option.configured is enabled or not."""
110++
111++ imds_token = get_imds_token()
112++ if imds_token is None:
113++ log("IMDS_V2 http endpoint is disabled")
114++ # IMDS http endpoint is disabled
115++ return False
116++
117++ request_header = {'X-aws-ec2-metadata-token': imds_token}
118++ response = requests.get("{}/{}".format(IMDS_BASEURL, IMDS_SPOT_ACTION_PATH),
119++ headers=request_header)
120++ response.close()
121++ if response.status_code != requests.codes.ok or response.text.lower() == "false":
122++ return False
123++
124++ log("Hibernation Configured Flag found")
125++
126++ return True
127+
128+ def main():
129+ # Parse arguments
130+@@ -550,6 +585,11 @@
131+
132+ log("Effective config: %s" % config)
133+
134++ # Let's first check if we need to kill the Spot Hibernate Agent
135++ if hibernation_enabled():
136++ log("Spot Instance Launch has enabled Hibernation Configured Flag. hibagent exiting!!")
137++ exit(0)
138++
139+ target_swap_size = config.swap_mb * 1024 * 1024
140+ ram_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
141+ swap_percentage_size = ram_bytes * config.swap_percentage // 100
142diff --git a/debian/patches/series b/debian/patches/series
143index 68b33b1..e3435d5 100644
144--- a/debian/patches/series
145+++ b/debian/patches/series
146@@ -8,3 +8,6 @@ add-lsb-init-info.patch
147 fix-enable-ec2-spot-hibernation.patch
148 lp1896638-set-resume-device-by-partition-uuid.patch
149 lp2013336-do-not-modify-GRUB-config-on-GRUB2-systems.patch
150+use-imdsv2.patch
151+do-nothing-if-ODH-is-configured.patch
152+disable-hibernate-test.patch
153diff --git a/debian/patches/use-imdsv2.patch b/debian/patches/use-imdsv2.patch
154new file mode 100644
155index 0000000..6c91a91
156--- /dev/null
157+++ b/debian/patches/use-imdsv2.patch
158@@ -0,0 +1,44 @@
159+Description: IMDS V2 updates
160+Author: shivasan@ <shivasan@amazon.com>
161+Origin: upstream, https://github.com/aws/ec2-hibernate-linux-agent/commit/559558f28de4456f14b38539eed967df6e1f9217
162+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/hibagent/+bug/2043739
163+Last-Update: 2023-11-16
164+---
165+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
166+--- a/agent/hibagent
167++++ b/agent/hibagent
168+@@ -315,16 +315,28 @@
169+
170+ def poll_for_termination(self):
171+ # noinspection PyBroadException
172+- response = None
173++ response1 = None
174++ response2 = None
175+ try:
176+- response = urlopen(self.url)
177+- res_str = response.read()
178+- return b"hibernate" in res_str
179++ request1 = Request("http://169.254.169.254/latest/api/token")
180++ request1.add_header('X-aws-ec2-metadata-token-ttl-seconds', '21600')
181++ request1.get_method = lambda:"PUT"
182++ response1 = urlopen(request1)
183++
184++ token = response1.read()
185++
186++ request2 = Request(self.url)
187++ request2.add_header('X-aws-ec2-metadata-token', token)
188++ response2 = urlopen(request2)
189++ res = response2.read()
190++ return b"hibernate" in res
191+ except:
192+ return False
193+ finally:
194+- if response:
195+- response.close()
196++ if response1:
197++ response1.close()
198++ if response2:
199++ response2.close()
200+
201+ def do_hibernate(self):
202+ log("Attempting to hibernate")

Subscribers

People subscribed via source and target branches