Merge ~mitchdz/ubuntu/+source/ec2-hibinit-agent:add-IMDSv2-mantic into ubuntu/+source/ec2-hibinit-agent:ubuntu/devel

Proposed by Mitchell Dzurick
Status: Merged
Merged at revision: c00b1e8a33c7fdf460987acad479c86d21d8b077
Proposed branch: ~mitchdz/ubuntu/+source/ec2-hibinit-agent:add-IMDSv2-mantic
Merge into: ubuntu/+source/ec2-hibinit-agent:ubuntu/devel
Diff against target: 191 lines (+169/-0)
3 files modified
debian/changelog (+7/-0)
debian/patches/lp1941785-Add-support-for-IMDSv2.patch (+161/-0)
debian/patches/series (+1/-0)
Reviewer Review Type Date Requested Status
Athos Ribeiro (community) Approve
Ubuntu Sponsors Pending
git-ubuntu import Pending
Review via email: mp+443022@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Hi, Thanks for submitting this one!

From the upstream commit in [1], I see that this is actually a backport (you had to edit the patch so it applies, right?). In this case, you can state that in the patch DEP3 header "Origin" field by replacing "upstream" with "backport".

Also, could you provide a PPA with a build of this package?

Finally, is there any specific reasons not to upgrade this to the latest upstream version (1.0.5) instead of backporting this patch here?

[1] https://github.com/aws/amazon-ec2-hibinit-agent/commit/9d9bca5c61fa9256289e68c88bd3747af2f62e28

review: Needs Information
Revision history for this message
Mitchell Dzurick (mitchdz) wrote :

Thank you Athos! I updated the DEP3 header. My PPA is in the MP message

- https://launchpad.net/~mitchdz/+archive/ubuntu/ec2-hibinit-agent-add-imdsv2-support

A discussion up upgrading to meet upstream did happen, and we decided to just backport this change for a few reasons: This package is not updated frequently, there's only a request to support the new metadata format, and our package has diverged from upstream, so it makes sense to make minimal changes here.

Revision history for this message
Mitchell Dzurick (mitchdz) wrote :

FYI in the main bug [1] I do have a Test Case in the Bug Description

[1] https://bugs.launchpad.net/ubuntu/+source/ec2-hibinit-agent/+bug/1941785

Revision history for this message
Mitchell Dzurick (mitchdz) wrote :

For a little extra information,

After creating an EC2 instance configured correctly you can add my PPA to test, and if you see `Running: swapoff /swap-hibinit` from the agent service and upgrade then that likely means everything is good.

$ sudo add-apt-repository ppa:mitchdz/ec2-hibinit-agent-add-imdsv2-support
$ sudo apt update -y && sudo apt upgrade -y
$ systemctl status hibinit-agent
○ hibinit-agent.service - EC2 instance hibernation setup agent
     Loaded: loaded (/lib/systemd/system/hibinit-agent.service; enabled; preset: enabled)
     Active: inactive (dead) since Wed 2023-05-17 17:53:54 UTC; 20s ago
   Duration: 1.209s
       Docs: file:/usr/share/doc/ec2-hibinit-agent/README
    Process: 2511 ExecStart=/usr/bin/hibinit-agent -c /etc/hibinit-config.cfg (code=exited, status=0/SUCCESS)
        CPU: 1.000s

May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: GRUB configuration is updated
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Setting swap device to 66305 with offset 749568
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: GRUB configuration is updated
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Setting swap device to 66305 with offset 749568
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Done updating the swap offset. Turning swapoff
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Done updating the swap offset. Turning swapoff
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Running: swapoff /swap-hibinit
May 17 17:53:54 ip-172-31-3-141 hibinit-agent[2513]: Running: swapoff /swap-hibinit
May 17 17:53:54 ip-172-31-3-141 systemd[1]: hibinit-agent.service: Deactivated successfully.
May 17 17:53:54 ip-172-31-3-141 systemd[1]: hibinit-agent.service: Consumed 1.000s CPU time.

From this point, start a daemon process and then initiate hibernation, start the machine, and the daemon process should still be running. I do provide an example daemon process to use in the parent bug report.

Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Thanks for clarifying things here Mitchell!

IMHO, we should consider either moving to the new upstream version or re-evaluating this package.

For instance, the agent/hibinit-agent file being patched still has calls to os.errno which was removed from python since 3.7 [1] (focal has python 3.8). There are also several lines in the codebase where tabs are used instead of spaces (not by design, but by mistake) which can hinder the intended code paths.

I added a few more comments inline below. The patch LGTM given those are addressed. I still need to test this before we upload it though.

[1] https://docs.python.org/3.7/whatsnew/3.7.html#changes-in-the-python-api

Revision history for this message
Mitchell Dzurick (mitchdz) :
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Hi Mitchell, thanks for addressing my comments.

Here are my test results for mantic:

- I launched 2 EC2 instances with the same configuration

- I installed the fixed package from your PPA in one of them

- Then I started hibernation for both of them

- The instances eventually stopped, with both the affected and the fixed package. However, the instance with fixed package stops way earlier. The affected one hangs in the "stopping" state for a long time before it is stopped. While it hangs there, I can still ssh into it.

- After the affected instance finally halted, I re-started it and verified that the state was not preserved.

- After the fixed instance halted, I re-started it and verified that the state was indeed preserved.

review: Approve
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

Uploaded:

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ec2-hibinit-agent_1.0.0-0ubuntu14.dsc: done.
  Uploading ec2-hibinit-agent_1.0.0-0ubuntu14.debian.tar.xz: done.
  Uploading ec2-hibinit-agent_1.0.0-0ubuntu14_source.buildinfo: done.
  Uploading ec2-hibinit-agent_1.0.0-0ubuntu14_source.changes: done.
Successfully uploaded packages.

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 87ea519..e3aaae8 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,10 @@
6+ec2-hibinit-agent (1.0.0-0ubuntu14) mantic; urgency=medium
7+
8+ * d/p/lp1941785-Add-support-for-IMDSv2.patch: add IMDSv2 support
9+ (LP: #1941785)
10+
11+ -- Mitchell Dzurick <mitchell.dzurick@canonical.com> Tue, 16 May 2023 06:58:08 -0700
12+
13 ec2-hibinit-agent (1.0.0-0ubuntu13) lunar; urgency=medium
14
15 * d/p/fix-setuptools-package-discovery.patch: fix FTBFS with recent
16diff --git a/debian/patches/lp1941785-Add-support-for-IMDSv2.patch b/debian/patches/lp1941785-Add-support-for-IMDSv2.patch
17new file mode 100644
18index 0000000..6855eb2
19--- /dev/null
20+++ b/debian/patches/lp1941785-Add-support-for-IMDSv2.patch
21@@ -0,0 +1,161 @@
22+Description: Add support for IMDSv2
23+Author: Frederick Lefebvre <fredlef@amazon.com>
24+Origin: backport, https://github.com/aws/amazon-ec2-hibinit-agent/commit/9d9bca5c61fa9256289e68c88bd3747af2f62e28
25+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/ec2-hibinit-agent/+bug/1941785
26+Last-Update: 2023-05-16
27+---
28+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
29+--- a/agent/hibinit-agent
30++++ b/agent/hibinit-agent
31+@@ -18,6 +18,7 @@
32+ import sys
33+ import syslog
34+ import math
35++import requests
36+ from subprocess import check_call, check_output, STDOUT
37+ from threading import Thread
38+ from math import ceil
39+@@ -25,11 +26,6 @@
40+
41+
42+ try:
43+- from urllib.request import urlopen, Request
44+-except ImportError:
45+- from urllib2 import urlopen, Request, HTTPError
46+-
47+-try:
48+ from ConfigParser import ConfigParser, NoSectionError, NoOptionError
49+ except:
50+ from configparser import ConfigParser, NoSectionError, NoOptionError
51+@@ -41,7 +37,12 @@
52+ log_to_syslog = True
53+ log_to_stderr = True
54+ SWAP_FILE = '/swap-hibinit'
55+-URL = "http://169.254.169.254/latest/meta-data/hibernation/configured"
56++
57++DEFAULT_STATE_DIR = '/var/lib/hibinit-agent'
58++HIB_ENABLED_FILE = "hibernation-enabled"
59++IMDS_BASEURL = 'http://169.254.169.254'
60++IMDS_API_TOKEN_PATH = 'latest/api/token'
61++IMDS_SPOT_ACTION_PATH = 'latest/meta-data/hibernation/configured'
62+
63+ def log(message):
64+ if log_to_syslog:
65+@@ -314,6 +315,9 @@
66+ get_int('swap', 'percentage-of-ram'), args.swap_ram_percentage, 100)
67+ self.swap_mb = self.merge(
68+ get_int('swap', 'target-size-mb'), args.swap_target_size_mb, 4000)
69++ self.state_dir = get('core', 'state-dir')
70++ if self.state_dir is None:
71++ self.state_dir = DEFAULT_STATE_DIR
72+
73+
74+ def merge(self, cf_value, arg_value, def_val):
75+@@ -337,31 +341,55 @@
76+ def __str__(self):
77+ return str(self.__dict__)
78+
79+-def hibernationEnabled():
80+- """Returns a boolean indicating whether hibernation is enabled or not."""
81+- response = None
82+- try:
83+- response = urlopen(URL)
84+- data = response.read()
85+- if data.lower() in ('false', b'false'):
86+- return False
87+- except:
88+- return False
89+- finally:
90+- if response:
91+- response.close()
92+- return True
93++def get_imds_token(seconds=21600):
94++ """ Get a token to access instance metadata. """
95++ log("Requesting new IMDSv2 token.")
96++ request_header = {'X-aws-ec2-metadata-token-ttl-seconds': str(seconds)}
97++ token_url = '{}/{}'.format(IMDS_BASEURL, IMDS_API_TOKEN_PATH)
98++ response = requests.put(token_url, headers=request_header)
99++ response.close()
100++ if response.status_code != 200:
101++ return None
102++
103++ return response.text
104++
105++def create_state_dir(state_dir):
106++ """ Create agent run dir if it doesn't exists."""
107++ if not os.path.isdir(state_dir):
108++ os.makedirs(state_dir)
109++
110++def hibernation_enabled(state_dir):
111++ """Returns a boolean indicating whether hibernation is enabled or not.
112++ Hibernation can't be enabled/disabled the instance launch. If we find
113++ hibernation to be enabled, we create a semephore file so that we don't
114++ have to probe IMDS again. That is useful when a instance is rebooted
115++ after/if the IMDS http endpoint has been disabled.
116++ """
117++ hib_sem_file = os.path.join(state_dir, HIB_ENABLED_FILE)
118++ if os.path.isfile(hib_sem_file):
119++ log("Found {!r}, configuring hibernation".format(hib_sem_file))
120++ return True
121++
122++ imds_token = get_imds_token()
123++ if imds_token is None:
124++ # IMDS http endpoint is disabled
125++ return False
126++
127++ request_header = {'X-aws-ec2-metadata-token': imds_token}
128++ response = requests.get("{}/{}".format(IMDS_BASEURL, IMDS_SPOT_ACTION_PATH),
129++ headers=request_header)
130++ response.close()
131++ if response.status_code != 200 or response.text.lower() == "false":
132++ return False
133++
134++ log("Hibernation Configured Flag found")
135++ os.mknod(hib_sem_file)
136++
137++ return True
138++
139+
140+ def main():
141+
142+- if not hibernationEnabled():
143+- log("Instance Launch has not enabled Hibernation Configured Flag. hibinit-agent exiting!!")
144+- exit(0)
145+- # Validate if disk space>total RAM
146+- ram_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
147+- if get_rootfs_size()<=(math.ceil(float(ram_bytes)/(1024*1024*1024))):
148+- log("Insufficient disk space. Cannot create setup for hibernation. Please allocate a larger root device")
149+- exit(1)
150+ # Parse arguments
151+ parser = argparse.ArgumentParser(description="An EC2 background process that creates a setup for instance hibernation "
152+ "at instance launch and also registers ACPI sleep event/actions")
153+@@ -388,6 +416,17 @@
154+ log_to_syslog = config.log_to_syslog
155+
156+ log("Effective config: %s" % config)
157++ create_state_dir(config.state_dir)
158++
159++ # Let's first check if we even need to run
160++ if not hibernation_enabled(config.state_dir):
161++ log("Instance Launch has not enabled Hibernation Configured Flag. hibinit-agent exiting!!")
162++ exit(0)
163++ # Validate if disk space>total RAM
164++ ram_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
165++ if get_rootfs_size()<=(math.ceil(float(ram_bytes)/(1024*1024*1024))):
166++ log("Insufficient disk space. Cannot create setup for hibernation. Please allocate a larger root device")
167++ exit(1)
168+
169+ target_swap_size = config.swap_mb * 1024 * 1024
170+ swap_percentage_size = ram_bytes * config.swap_percentage // 100
171+--- a/etc/hibinit-config.cfg
172++++ b/etc/hibinit-config.cfg
173+@@ -11,6 +11,9 @@
174+ # filesystems.
175+ touch-swap = False
176+
177++# Location where to create any state files
178++state-dir = "/var/lib/hibinit-agent"
179++
180+ [swap]
181+ # If there's no swap then we create it to be equal to the specified
182+ # percentage of RAM or to the target size, whichever is greater
183diff --git a/debian/patches/series b/debian/patches/series
184index f419db3..043841d 100644
185--- a/debian/patches/series
186+++ b/debian/patches/series
187@@ -9,3 +9,4 @@ detect-hibernate-cmd-by-default.patch
188 0010-Update-grub-configuration-when-it-needs-an-update.patch
189 lp1968805-Swapon-with-maximum-priority-before-hibernation.patch
190 fix-setuptools-package-discovery.patch
191+lp1941785-Add-support-for-IMDSv2.patch

Subscribers

People subscribed via source and target branches