Merge ~calvinmwadime/ubuntu/+source/walinuxagent:bionic-2.9.1.1 into ubuntu/+source/walinuxagent:ubuntu/bionic-devel
- Git
- lp:~calvinmwadime/ubuntu/+source/walinuxagent
- bionic-2.9.1.1
- Merge into ubuntu/bionic-devel
Status: | Work in progress | ||||
---|---|---|---|---|---|
Proposed branch: | ~calvinmwadime/ubuntu/+source/walinuxagent:bionic-2.9.1.1 | ||||
Merge into: | ubuntu/+source/walinuxagent:ubuntu/bionic-devel | ||||
Diff against target: |
769 lines (+415/-51) 13 files modified
debian/changelog (+29/-0) debian/control (+13/-5) debian/docs (+0/-1) debian/install (+3/-3) debian/patches/disable_udev_overrides.patch (+16/-0) debian/patches/fix_cgroup_v2_mounting_and_systemd_process.patch (+232/-0) debian/patches/fix_systemd_networkd_lease_file_path (+66/-0) debian/patches/series (+3/-2) debian/patches/update_dhcp_client_ubuntu_supported_versions.patch (+39/-0) debian/rules (+9/-12) debian/walinuxagent.manpages (+1/-0) debian/watch (+4/-3) dev/null (+0/-25) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lucas Kanashiro (community) | Needs Fixing | ||
Ubuntu Sponsors | Pending | ||
Review via email: mp+461121@code.launchpad.net |
Commit message
Description of the change
Lukas Märdian (slyon) wrote : | # |
Please address comments from https:/
Unmerged commits
- 9a2106f... by Calvin Mwadime Makokha
-
debian/changelog: Update version
- de5dc3e... by Calvin Mwadime Makokha
-
d/install: move remaining things to /usr
- 4bc466b... by Calvin Mwadime Makokha
-
d/control: fix lintian priority-
extra-is- replaced- by-priority- optional - a5ec50e... by Calvin Mwadime Makokha
-
d/control: add iproute2 build depdency (test only)
- b4817c2... by Calvin Mwadime Makokha
-
d/rules: stop using the old systemd dh sequence
Matching our switch to dh_installsystemd we need to stop calling
for the older systemd-sequence in dh.This fixes:
error: The systemd-sequence is no longer provided in compat >= 11,
please rely on dh_installsystemd instead - 88304be... by Calvin Mwadime Makokha
-
d/control: drop old unneeded X-Python3-Version statement
- c9c0e6a... by Calvin Mwadime Makokha
-
d/rules, d/install: install services once
Since "7d793bf debian: Remove upstart config" --no-restart-
on-upgrade
behavior was lost. Add it back with the new name --no-stop-on-upgrade.
Furthermore the install was a mix of the upstream putting files
under /lib and then debian/install putting it under /usr/lib leading
to file-in-root-and- usr warnings.
Furthermore dh_systemd_enable and the formerly dropped dh_installinit
have been consumed into dh_installsystemd for systemd units.
Finally dh_installsystemd will drop the executable bit which is
wrong in the upstream archive and triggers executable-not-elf- or-script.
So overall to hopefully do it right we do:
- ephemeral-disk-warning. service gets installed by d/install
- walinuxagent.service gets installed badly by upstream and removed in
d/rules
- both services are then picked up and configured by dh_installsystemd - eb9ef58... by Calvin Mwadime Makokha
-
d/control, d/compat: switch to compat level 13
- 638ab36... by Calvin Mwadime Makokha
-
d/manpages: add man pages.
- 2b6ece0... by Calvin Mwadime Makokha
-
debian/patches: Update the cgroup handling to include v2
WALA only supported cgroup v1 systems. This causes failures when running some
commands on cgroup v2 systems. Newer ubuntu versions are support cgroup v2 by
default
Preview Diff
1 | diff --git a/debian/changelog b/debian/changelog |
2 | index 42e8156..d25a30e 100644 |
3 | --- a/debian/changelog |
4 | +++ b/debian/changelog |
5 | @@ -1,3 +1,32 @@ |
6 | +walinuxagent (2.9.1.1-0ubuntu1) bionic; urgency=medium |
7 | + |
8 | + [ Calvin Mwadime ] |
9 | + * New upstream version 2.9.1.1 (LP: #2035331) |
10 | + * debian/watch: Fix package version regex pattern |
11 | + * debian/docs: Remove the changelog |
12 | + * debian/install: add new udev rules |
13 | + * debian/patches: |
14 | + - Remove deprecated patches |
15 | + - Update list of supported ubuntu versions |
16 | + - Correctly point to the right dhcp client lease file |
17 | + - Update the cgroup handling to include v2 |
18 | + * disable_udev_overrides.patch: Remove udev overrides in setup.py |
19 | + * debian: Make python unit tests work |
20 | + * debian: Remove upstart config |
21 | + * debian/control: Remove isc-dhcp-client |
22 | + * debian/manpages: Added manpages |
23 | + |
24 | + [ Christian Ehrhardt ] |
25 | + * d/control, d/compat: switch to compat level 13 |
26 | + * d/rules, d/install: install services once |
27 | + * d/control: drop old unneeded X-Python3-Version statement |
28 | + * d/rules: stop using the old systemd dh sequence |
29 | + * d/control: add iproute2 build dependency (test only) |
30 | + * d/control: fix lintian priority-extra-is-replaced-by-priority-optional |
31 | + * d/install: move remaining things to /usr |
32 | + |
33 | + -- Calvin Mwadime <calvin.mwadime@canonical.com> Thu, 30 Nov 2023 11:07:05 +0300 |
34 | + |
35 | walinuxagent (2.2.45-0ubuntu1~18.04.3) bionic; urgency=medium |
36 | |
37 | * Add patch to fix handling of gen2 disks |
38 | diff --git a/debian/compat b/debian/compat |
39 | deleted file mode 100644 |
40 | index 45a4fb7..0000000 |
41 | --- a/debian/compat |
42 | +++ /dev/null |
43 | @@ -1 +0,0 @@ |
44 | -8 |
45 | diff --git a/debian/control b/debian/control |
46 | index 89403a4..cb3f700 100644 |
47 | --- a/debian/control |
48 | +++ b/debian/control |
49 | @@ -1,23 +1,31 @@ |
50 | Source: walinuxagent |
51 | Section: python |
52 | -Priority: extra |
53 | +Priority: optional |
54 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
55 | XSBC-Original-Maintainer: Microsoft Corporation <walinuxagent@microsoft.com> |
56 | -Build-Depends: debhelper (>= 8), |
57 | - dh-systemd, |
58 | +Build-Depends: debhelper-compat (= 13), |
59 | + dh-python, |
60 | + debhelper (>= 9.20160709) | dh-systemd, |
61 | + go-md2man, |
62 | + iproute2, |
63 | python3-all, |
64 | python3-setuptools, |
65 | python3-pyasn1, |
66 | python3-mock, |
67 | + python3-nose, |
68 | + python3-nose-timer, |
69 | + python3-wrapt, |
70 | + pylint, |
71 | + python3-distro, |
72 | + python3-coverage, |
73 | + iptables, |
74 | openssl (>= 1.0), |
75 | Standards-Version: 3.9.8 |
76 | -X-Python3-Version: >= 3.2 |
77 | Homepage: http://go.microsoft.com/fwlink/?LinkId=250998 |
78 | |
79 | Package: walinuxagent |
80 | Architecture: amd64 arm64 |
81 | Depends: cloud-init (>= 0.7.3~bzr826-0ubuntu2), |
82 | - isc-dhcp-client, |
83 | openssh-server (>= 1:5.9p1), |
84 | openssl (>= 1.0), |
85 | passwd (>= 4.1.4.2), |
86 | diff --git a/debian/docs b/debian/docs |
87 | index ae1ac0d..5cc071c 100644 |
88 | --- a/debian/docs |
89 | +++ b/debian/docs |
90 | @@ -2,4 +2,3 @@ debian/99-cloud-init-disable-diskprovisioning.conf |
91 | NOTICE |
92 | README.md |
93 | MANIFEST |
94 | -Changelog |
95 | diff --git a/debian/ephemeral-disk-warning.conf b/debian/ephemeral-disk-warning.conf |
96 | deleted file mode 100644 |
97 | index 7f60cfe..0000000 |
98 | --- a/debian/ephemeral-disk-warning.conf |
99 | +++ /dev/null |
100 | @@ -1,55 +0,0 @@ |
101 | -# ephemeral-disk-warning - warns user that the disk is really, really ephemeral |
102 | -# |
103 | -# On Azure, the ephemeral disk is extremely ephemeral; the ephemeral disk is |
104 | -# unsafe between boots. This places a file on /mnt that warns the user |
105 | -# that the disk is a dangerous place for storing data of any importance. |
106 | - |
107 | -env RESOURCE_DISK=/dev/disk/azure/resource-part1 |
108 | - |
109 | -start on (stopped rc RUNLEVEL=[2345] and stopped cloud-config) |
110 | -task |
111 | -script |
112 | - if [ ! -e $RESOURCE_DISK ]; then |
113 | - logger "Disk $RESOURCE_DISK does not exist, skipping ephemeral warning" |
114 | - exit 0 |
115 | - fi |
116 | - |
117 | - ephemeral_kdev=$(readlink -f $RESOURCE_DISK) |
118 | - ephemeral_mp=$(awk '$1==kd {print$2}' "kd=$ephemeral_kdev" /proc/mounts) |
119 | - warn_file="$ephemeral_mp/DATALOSS_WARNING_README.txt" |
120 | - |
121 | - if [ -z "$ephemeral_mp" ]; then |
122 | - logger "Unable to discover mount point of $ephemeral_kdev. Ephemeral warning will not be written" |
123 | - exit 0 |
124 | - else |
125 | - logger "Ephemeral disk $ephemeral_kdev located at $ephemeral_mp" |
126 | - fi |
127 | - |
128 | - if [ ! -e "$warn_file" ]; then |
129 | - cat >> $warn_file <<EOF |
130 | -WARNING: THIS IS A TEMPORARY DISK. |
131 | - |
132 | -Any data stored on this drive is SUBJECT TO LOSS and THERE IS NO WAY TO |
133 | -RECOVER IT. |
134 | - |
135 | -Please do not use this disk for storing any personal or application data. |
136 | - |
137 | -For additional details to please refer to the MSDN documentation at: |
138 | -http://msdn.microsoft.com/en-us/library/windowsazure/jj672979.aspx |
139 | - |
140 | -To remove this warning run: |
141 | - sudo chattr -i $warn_file |
142 | - sudo rm $warn_file |
143 | - |
144 | -This warning is written each boot; to disable it: |
145 | - echo "manual" | sudo tee /etc/init/ephemeral-disk-warning.override |
146 | - sudo systemctl disable ephemeral-disk-warning.service |
147 | - |
148 | -EOF |
149 | - chmod 0444 $warn_file |
150 | - chattr +i $warn_file |
151 | - logger "Added ephemeral disk warning to $warn_file" |
152 | - fi |
153 | - logger "WARNING: $ephemeral_mp is an ephemeral disk. See $warn_file for more information" |
154 | - |
155 | -end script |
156 | diff --git a/debian/install b/debian/install |
157 | index 8915177..98c4b97 100644 |
158 | --- a/debian/install |
159 | +++ b/debian/install |
160 | @@ -1,6 +1,6 @@ |
161 | -config/66-azure-storage.rules lib/udev/rules.d |
162 | -debian/ephemeral-disk-warning.service lib/systemd/system |
163 | -debian/ephemeral-disk-warning.conf etc/init |
164 | +config/66-azure-storage.rules usr/lib/udev/rules.d |
165 | +config/99-azure-product-uuid.rules usr/lib/udev/rules.d |
166 | +debian/ephemeral-disk-warning.service usr/lib/systemd/system |
167 | debian/ephemeral-disk-warning usr/sbin |
168 | debian/67-azure-console.rules lib/udev/rules.d |
169 | debian/68-azure-nm-unmanaged.rules lib/udev/rules.d |
170 | diff --git a/debian/patches/disable_import_test.patch b/debian/patches/disable_import_test.patch |
171 | deleted file mode 100644 |
172 | index 558a7be..0000000 |
173 | --- a/debian/patches/disable_import_test.patch |
174 | +++ /dev/null |
175 | @@ -1,43 +0,0 @@ |
176 | -Index: walinuxagent-2.2.32/config/waagent.conf |
177 | -=================================================================== |
178 | ---- walinuxagent-2.2.32.orig/config/waagent.conf |
179 | -+++ walinuxagent-2.2.32/config/waagent.conf |
180 | -@@ -3,7 +3,7 @@ |
181 | - # |
182 | - |
183 | - # Enable instance creation |
184 | --Provisioning.Enabled=y |
185 | -+Provisioning.Enabled=n |
186 | - |
187 | - # Enable extension handling. Do not disable this unless you do not need password reset, |
188 | - # backup, monitoring, or any extension handling whatsoever. |
189 | -@@ -13,10 +13,10 @@ Extensions.Enabled=y |
190 | - Provisioning.UseCloudInit=n |
191 | - |
192 | - # Password authentication for root account will be unavailable. |
193 | --Provisioning.DeleteRootPassword=y |
194 | -+Provisioning.DeleteRootPassword=n |
195 | - |
196 | - # Generate fresh host key pair. |
197 | --Provisioning.RegenerateSshHostKeyPair=y |
198 | -+Provisioning.RegenerateSshHostKeyPair=n |
199 | - |
200 | - # Supported values are "rsa", "dsa", "ecdsa", "ed25519", and "auto". |
201 | - # The "auto" option is supported on OpenSSH 5.9 (2011) and later. |
202 | -@@ -41,14 +41,14 @@ Provisioning.ExecuteCustomData=n |
203 | - Provisioning.AllowResetSysUser=n |
204 | - |
205 | - # Format if unformatted. If 'n', resource disk will not be mounted. |
206 | --ResourceDisk.Format=y |
207 | -+ResourceDisk.Format=n |
208 | - |
209 | - # File system on the resource disk |
210 | - # Typically ext3 or ext4. FreeBSD images should use 'ufs2' here. |
211 | - ResourceDisk.Filesystem=ext4 |
212 | - |
213 | - # Mount point for the resource disk |
214 | --ResourceDisk.MountPoint=/mnt/resource |
215 | -+ResourceDisk.MountPoint=/mnt |
216 | - |
217 | - # Create and use swapfile on resource disk. |
218 | - ResourceDisk.EnableSwap=n |
219 | diff --git a/debian/patches/disable_udev_overrides.patch b/debian/patches/disable_udev_overrides.patch |
220 | index 7c344d0..cc25ba0 100644 |
221 | --- a/debian/patches/disable_udev_overrides.patch |
222 | +++ b/debian/patches/disable_udev_overrides.patch |
223 | @@ -10,3 +10,19 @@ |
224 | VarLibDhcpDirectories = ["/var/lib/dhclient", "/var/lib/dhcpcd", "/var/lib/dhcp"] |
225 | EtcDhcpClientConfFiles = ["/etc/dhcp/dhclient.conf", "/etc/dhcp3/dhclient.conf"] |
226 | global LibDir |
227 | + |
228 | +Description: Remove udev overrides in setup.py |
229 | +Forwaded: not-needed |
230 | +Author: Calvin Mwadime Makokha <calvin.mwadime@canonical.com> |
231 | +Index: walinuxagent/setup.py |
232 | +=================================================================== |
233 | +--- walinuxagent.orig/setup.py |
234 | ++++ walinuxagent/setup.py |
235 | +@@ -82,8 +82,7 @@ def set_openbsd_rc_files(data_files, des |
236 | + |
237 | + def set_udev_files(data_files, dest="/etc/udev/rules.d/", src=None): |
238 | + if src is None: |
239 | +- src = ["config/66-azure-storage.rules", |
240 | +- "config/99-azure-product-uuid.rules"] |
241 | ++ src = [] |
242 | + data_files.append((dest, src)) |
243 | diff --git a/debian/patches/fix-udev-rules-for-azure.patch b/debian/patches/fix-udev-rules-for-azure.patch |
244 | deleted file mode 100644 |
245 | index 497c74b..0000000 |
246 | --- a/debian/patches/fix-udev-rules-for-azure.patch |
247 | +++ /dev/null |
248 | @@ -1,69 +0,0 @@ |
249 | -From d33f1f810728dbe4e2891149936195d1ec7aaa27 Mon Sep 17 00:00:00 2001 |
250 | -From: Thomas Stringer <thstring@microsoft.com> |
251 | -Date: Mon, 20 Jul 2020 14:24:22 -0400 |
252 | -Subject: [PATCH] Fix handling of gen2 disks with udev rules (#1954) |
253 | - |
254 | ---- |
255 | - config/66-azure-storage.rules | 40 ++++++++++++++++++++--------------- |
256 | - 1 file changed, 23 insertions(+), 17 deletions(-) |
257 | - |
258 | -Origin: upstream, https://github.com/Azure/WALinuxAgent/commit/d33f1f810728dbe4e2891149936195d1ec7aaa27 |
259 | -Bug: https://github.com/Azure/WALinuxAgent/issues/1867 |
260 | -Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/walinuxagent/+bug/1971141 |
261 | -Applied-Upstream: https://github.com/Azure/WALinuxAgent/commit/d33f1f810728dbe4e2891149936195d1ec7aaa27 (v2.7.0.6) |
262 | -Last-Updated: 2022-05-12 |
263 | - |
264 | ---- a/config/66-azure-storage.rules |
265 | -+++ b/config/66-azure-storage.rules |
266 | -@@ -1,28 +1,34 @@ |
267 | --ACTION=="add|change", SUBSYSTEM=="block", ENV{ID_VENDOR}=="Msft", ENV{ID_MODEL}=="Virtual_Disk", GOTO="azure_disk" |
268 | --GOTO="azure_end" |
269 | -+# Azure specific rules. |
270 | -+ACTION!="add|change", GOTO="walinuxagent_end" |
271 | -+SUBSYSTEM!="block", GOTO="walinuxagent_end" |
272 | -+ATTRS{ID_VENDOR}!="Msft", GOTO="walinuxagent_end" |
273 | -+ATTRS{ID_MODEL}!="Virtual_Disk", GOTO="walinuxagent_end" |
274 | - |
275 | --LABEL="azure_disk" |
276 | --# Root has a GUID of 0000 as the second value |
277 | --# The resource/resource has GUID of 0001 as the second value |
278 | --ATTRS{device_id}=="?00000000-0000-*", ENV{fabric_name}="root", GOTO="azure_names" |
279 | --ATTRS{device_id}=="?00000000-0001-*", ENV{fabric_name}="resource", GOTO="azure_names" |
280 | --ATTRS{device_id}=="?00000001-0001-*", ENV{fabric_name}="BEK", GOTO="azure_names" |
281 | --# Wellknown SCSI controllers |
282 | -+# Match the known ID parts for root and resource disks. |
283 | -+ATTRS{device_id}=="?00000000-0000-*", ENV{fabric_name}="root", GOTO="wa_azure_names" |
284 | -+ATTRS{device_id}=="?00000000-0001-*", ENV{fabric_name}="resource", GOTO="wa_azure_names" |
285 | -+ |
286 | -+# Gen2 disk. |
287 | - ATTRS{device_id}=="{f8b3781a-1e82-4818-a1c3-63d806ec15bb}", ENV{fabric_scsi_controller}="scsi0", GOTO="azure_datadisk" |
288 | -+# Create symlinks for data disks attached. |
289 | - ATTRS{device_id}=="{f8b3781b-1e82-4818-a1c3-63d806ec15bb}", ENV{fabric_scsi_controller}="scsi1", GOTO="azure_datadisk" |
290 | - ATTRS{device_id}=="{f8b3781c-1e82-4818-a1c3-63d806ec15bb}", ENV{fabric_scsi_controller}="scsi2", GOTO="azure_datadisk" |
291 | - ATTRS{device_id}=="{f8b3781d-1e82-4818-a1c3-63d806ec15bb}", ENV{fabric_scsi_controller}="scsi3", GOTO="azure_datadisk" |
292 | --GOTO="azure_end" |
293 | -+GOTO="walinuxagent_end" |
294 | - |
295 | --# Retrieve LUN number for datadisks |
296 | -+# Parse out the fabric n ame based off of scsi indicators. |
297 | - LABEL="azure_datadisk" |
298 | --ENV{DEVTYPE}=="partition", PROGRAM="/bin/sh -c 'readlink /sys/class/block/%k/../device|cut -d: -f4'", ENV{fabric_name}="$env{fabric_scsi_controller}/lun$result", GOTO="azure_names" |
299 | --PROGRAM="/bin/sh -c 'readlink /sys/class/block/%k/device|cut -d: -f4'", ENV{fabric_name}="$env{fabric_scsi_controller}/lun$result", GOTO="azure_names" |
300 | --GOTO="azure_end" |
301 | -+ENV{DEVTYPE}=="partition", PROGRAM="/bin/sh -c 'readlink /sys/class/block/%k/../device|cut -d: -f4'", ENV{fabric_name}="$env{fabric_scsi_controller}/lun$result" |
302 | -+ENV{DEVTYPE}=="disk", PROGRAM="/bin/sh -c 'readlink /sys/class/block/%k/device|cut -d: -f4'", ENV{fabric_name}="$env{fabric_scsi_controller}/lun$result" |
303 | -+ |
304 | -+ENV{fabric_name}=="scsi0/lun0", ENV{fabric_name}="root" |
305 | -+ENV{fabric_name}=="scsi0/lun1", ENV{fabric_name}="resource" |
306 | -+# Don't create a symlink for the cd-rom. |
307 | -+ENV{fabric_name}=="scsi0/lun2", GOTO="walinuxagent_end" |
308 | - |
309 | --# Create the symlinks |
310 | --LABEL="azure_names" |
311 | -+# Create the symlinks. |
312 | -+LABEL="wa_azure_names" |
313 | - ENV{DEVTYPE}=="disk", SYMLINK+="disk/azure/$env{fabric_name}" |
314 | - ENV{DEVTYPE}=="partition", SYMLINK+="disk/azure/$env{fabric_name}-part%n" |
315 | - |
316 | --LABEL="azure_end" |
317 | -+LABEL="walinuxagent_end" |
318 | diff --git a/debian/patches/fix_cgroup_v2_mounting_and_systemd_process.patch b/debian/patches/fix_cgroup_v2_mounting_and_systemd_process.patch |
319 | new file mode 100644 |
320 | index 0000000..cbcdec2 |
321 | --- /dev/null |
322 | +++ b/debian/patches/fix_cgroup_v2_mounting_and_systemd_process.patch |
323 | @@ -0,0 +1,232 @@ |
324 | +Description: WALA was only supporting cgroup v1 which is not the default |
325 | + in the latest ubuntu versions, which had cgroup v2 on. This led to |
326 | + some tasks failing like periodic collection of the logs |
327 | +Forwarded: yes, https://github.com/Azure/WALinuxAgent/pull/2989 |
328 | +Author: Calvin Mwadime Makokha <calvinmwadime@canonical.com> |
329 | + |
330 | +--- walinuxagent-2.9.1.1.orig/azurelinuxagent/common/cgroup.py |
331 | ++++ walinuxagent-2.9.1.1/azurelinuxagent/common/cgroup.py |
332 | +@@ -220,16 +220,25 @@ class CpuCgroup(CGroup): |
333 | + with open(os.path.join(self.path, 'cpu.stat')) as cpu_stat: |
334 | + # |
335 | + # Sample file: |
336 | +- # |
337 | ++ # In CGroup v1 |
338 | + # # cat /sys/fs/cgroup/cpuacct/azure.slice/walinuxagent.service/cpu.stat |
339 | + # nr_periods 51660 |
340 | + # nr_throttled 19461 |
341 | + # throttled_time 1529590856339 |
342 | ++ # In CGroup v2 |
343 | ++ # # cat /sys/fs/cgroup/azure.slice/walinuxagent.service/cpu.stat |
344 | ++ # nr_periods 51660 |
345 | ++ # nr_throttled 19461 |
346 | ++ # throttled_usec 152959085 |
347 | + # |
348 | + for line in cpu_stat: |
349 | + match = re.match(r'throttled_time\s+(\d+)', line) |
350 | ++ multiplier = 1 |
351 | ++ if match is None: |
352 | ++ match = re.match(r'throttled_usec\s+(\d+)', line) |
353 | ++ multiplier = 100 |
354 | + if match is not None: |
355 | +- return int(match.groups()[0]) |
356 | ++ return int(match.groups()[0] * multiplier) |
357 | + raise Exception("Cannot find throttled_time") |
358 | + except (IOError, OSError) as e: |
359 | + if e.errno == errno.ENOENT: |
360 | +--- walinuxagent-2.9.1.1.orig/azurelinuxagent/common/cgroupapi.py |
361 | ++++ walinuxagent-2.9.1.1/azurelinuxagent/common/cgroupapi.py |
362 | +@@ -171,10 +171,14 @@ class SystemdCgroupsApi(CGroupsApi): |
363 | + The values returned can be None if the process is not in a cgroup for that controller (e.g. the controller is not mounted). |
364 | + """ |
365 | + # The contents of the file are similar to |
366 | ++ # In Cgroup v1 |
367 | + # # cat /proc/1218/cgroup |
368 | + # 10:memory:/system.slice/walinuxagent.service |
369 | + # 3:cpu,cpuacct:/system.slice/walinuxagent.service |
370 | + # etc |
371 | ++ # In Cgroup v2 |
372 | ++ # # cat /proc/1218/cgroup |
373 | ++ # 10::/system.slice/walinuxagent.service |
374 | + cpu_path = None |
375 | + memory_path = None |
376 | + for line in fileutil.read_file("/proc/{0}/cgroup".format(process_id)).splitlines(): |
377 | +@@ -186,6 +190,13 @@ class SystemdCgroupsApi(CGroupsApi): |
378 | + memory_path = path |
379 | + else: |
380 | + cpu_path = path |
381 | ++ else: |
382 | ++ match = re.match(r'\d+::(?P<path>.+)', line) |
383 | ++ if match: |
384 | ++ path = match.group('path').lstrip('/') if match.group('path') != '/' else None |
385 | ++ cpu_path = path |
386 | ++ memory_path = path |
387 | ++ |
388 | + |
389 | + return cpu_path, memory_path |
390 | + |
391 | +@@ -197,6 +208,20 @@ class SystemdCgroupsApi(CGroupsApi): |
392 | + cpu_cgroup_relative_path, memory_cgroup_relative_path = self.get_process_cgroup_relative_paths(process_id) |
393 | + |
394 | + cpu_mount_point, memory_mount_point = self.get_cgroup_mount_points() |
395 | ++ if cpu_mount_point is None or memory_mount_point is None: |
396 | ++ logger.warn("Cgroup v1 mount points not found") |
397 | ++ cgroup2_mount_point, cgroup2_controllers = self.get_cgroup2_controllers() |
398 | ++ if cgroup2_mount_point is not None: |
399 | ++ controller_missing = False |
400 | ++ if "memory" not in cgroup2_controllers or "-memory" in cgroup2_controllers: |
401 | ++ logger.warn("Memory controller not active in cgroup v2") |
402 | ++ controller_missing = True |
403 | ++ if "cpu" not in cgroup2_controllers or "-cpu" in cgroup2_controllers: |
404 | ++ logger.warn("CPU controller not active in cgroup v2") |
405 | ++ controller_missing = True |
406 | ++ if not controller_missing: |
407 | ++ cpu_mount_point = cgroup2_mount_point |
408 | ++ memory_mount_point = cgroup2_mount_point |
409 | + |
410 | + cpu_cgroup_path = os.path.join(cpu_mount_point, cpu_cgroup_relative_path) \ |
411 | + if cpu_mount_point is not None and cpu_cgroup_relative_path is not None else None |
412 | +@@ -239,7 +264,8 @@ class SystemdCgroupsApi(CGroupsApi): |
413 | + if match is not None: |
414 | + mount_point = match.group('path') |
415 | + controllers = None |
416 | +- controllers_file = os.path.join(mount_point, 'cgroup.controllers') |
417 | ++ # Check for enabled controllers only |
418 | ++ controllers_file = os.path.join(mount_point, 'cgroup.subtree_control') |
419 | + if os.path.exists(controllers_file): |
420 | + controllers = fileutil.read_file(controllers_file) |
421 | + return mount_point, controllers |
422 | +--- walinuxagent-2.9.1.1.orig/azurelinuxagent/common/cgroupconfigurator.py |
423 | ++++ walinuxagent-2.9.1.1/azurelinuxagent/common/cgroupconfigurator.py |
424 | +@@ -76,7 +76,7 @@ CPUQuota={cpu_quota} |
425 | + MemoryAccounting=yes |
426 | + """ |
427 | + _LOGCOLLECTOR_CPU_QUOTA = "5%" |
428 | +-LOGCOLLECTOR_MEMORY_LIMIT = 30 * 1024 ** 2 # 30Mb |
429 | ++LOGCOLLECTOR_MEMORY_LIMIT = 40 * 1024 ** 2 # 40Mb |
430 | + |
431 | + _AGENT_DROP_IN_FILE_SLICE = "10-Slice.conf" |
432 | + _AGENT_DROP_IN_FILE_SLICE_CONTENTS = """ |
433 | +@@ -299,24 +299,37 @@ class CGroupConfigurator(object): |
434 | + # check v1 controllers |
435 | + # |
436 | + cpu_controller_root, memory_controller_root = self._cgroups_api.get_cgroup_mount_points() |
437 | ++ controller_missing = False |
438 | + |
439 | + if cpu_controller_root is not None: |
440 | + logger.info("The CPU cgroup controller is mounted at {0}", cpu_controller_root) |
441 | + else: |
442 | + _log_cgroup_warning("The CPU cgroup controller is not mounted") |
443 | ++ controller_missing = True |
444 | + |
445 | + if memory_controller_root is not None: |
446 | + logger.info("The memory cgroup controller is mounted at {0}", memory_controller_root) |
447 | + else: |
448 | + _log_cgroup_warning("The memory cgroup controller is not mounted") |
449 | ++ controller_missing = True |
450 | + |
451 | + # |
452 | + # check v2 controllers |
453 | + # |
454 | +- cgroup2_mount_point, cgroup2_controllers = self._cgroups_api.get_cgroup2_controllers() |
455 | +- if cgroup2_mount_point is not None: |
456 | +- _log_cgroup_info("cgroups v2 mounted at {0}. Controllers: [{1}]", cgroup2_mount_point, |
457 | +- cgroup2_controllers) |
458 | ++ if controller_missing: |
459 | ++ cgroup2_mount_point, cgroup2_controllers = self._cgroups_api.get_cgroup2_controllers() |
460 | ++ if cgroup2_mount_point is not None: |
461 | ++ _log_cgroup_info("cgroups v2 mounted at {0}. Controllers: [{1}]", cgroup2_mount_point, |
462 | ++ cgroup2_controllers) |
463 | ++ controller_missing = False |
464 | ++ if "memory" not in cgroup2_controllers or "-memory" in cgroup2_controllers: |
465 | ++ _log_cgroup_warning("Memory controller not active in cgroup v2") |
466 | ++ controller_missing = True |
467 | ++ if "cpu" not in cgroup2_controllers or "-cpu" in cgroup2_controllers: |
468 | ++ _log_cgroup_warning("CPU controller not active in cgroup v2") |
469 | ++ controller_missing = True |
470 | ++ if not controller_missing: |
471 | ++ return cgroup2_mount_point, cgroup2_mount_point |
472 | + |
473 | + return cpu_controller_root, memory_controller_root |
474 | + |
475 | +--- walinuxagent-2.9.1.1.orig/azurelinuxagent/ga/collect_logs.py |
476 | ++++ walinuxagent-2.9.1.1/azurelinuxagent/ga/collect_logs.py |
477 | +@@ -171,12 +171,11 @@ class CollectLogsHandler(ThreadHandlerIn |
478 | + def _collect_logs(self): |
479 | + logger.info("Starting log collection...") |
480 | + |
481 | +- # Invoke the command line tool in the agent to collect logs, with resource limits on CPU. |
482 | +- # Some distros like ubuntu20 by default cpu and memory accounting enabled. Thus create nested cgroups under the logcollector slice |
483 | +- # So disabling CPU and Memory accounting prevents from creating nested cgroups, so that all the counters will be present in logcollector Cgroup |
484 | +- |
485 | ++ # Changing both CPUAccounting and MemoryAccounting to yes and adding CPUWeight so that cpu,cpuacct and memory controllers are enabled. |
486 | ++ # According to this https://docs.kernel.org/admin-guide/cgroup-v2.html#controllers some values in cpu.stat are only available if cpu controller |
487 | ++ # is enabled |
488 | + systemd_cmd = [ |
489 | +- "systemd-run", "--property=CPUAccounting=no", "--property=MemoryAccounting=no", |
490 | ++ "systemd-run", "--property=CPUAccounting=yes", "--property=CPUWeight=100", "--property=MemoryAccounting=yes", |
491 | + "--unit={0}".format(logcollector.CGROUPS_UNIT), |
492 | + "--slice={0}".format(cgroupconfigurator.LOGCOLLECTOR_SLICE), "--scope" |
493 | + ] |
494 | + |
495 | +--- a/tests/common/mock_cgroup_environment.py |
496 | ++++ b/tests/common/mock_cgroup_environment.py |
497 | +@@ -80,7 +80,7 @@ Thu 28 May 2020 07:25:55 AM PDT |
498 | + _MOCKED_FILES = [ |
499 | + ("/proc/self/cgroup", os.path.join(data_dir, 'cgroups', 'proc_self_cgroup')), |
500 | + (r"/proc/[0-9]+/cgroup", os.path.join(data_dir, 'cgroups', 'proc_pid_cgroup')), |
501 | +- ("/sys/fs/cgroup/unified/cgroup.controllers", os.path.join(data_dir, 'cgroups', 'sys_fs_cgroup_unified_cgroup.controllers')) |
502 | ++ ("/sys/fs/cgroup/unified/cgroup.subtree_control", os.path.join(data_dir, 'cgroups', 'sys_fs_cgroup_unified_cgroup.controllers')) |
503 | + ] |
504 | + |
505 | + _MOCKED_PATHS = [ |
506 | + |
507 | +--- a/tests/common/test_cgroupconfigurator.py |
508 | ++++ b/tests/common/test_cgroupconfigurator.py |
509 | +@@ -50,7 +50,7 @@ class CGroupConfiguratorSystemdTestCase(AgentTestCase): |
510 | + AgentTestCase.tearDownClass() |
511 | + |
512 | + @contextlib.contextmanager |
513 | +- def _get_cgroup_configurator(self, initialize=True, enable=True, mock_commands=None): |
514 | ++ def _get_cgroup_configurator(self, initialize=True, enable=True, mock_commands=None, mock_files=None): |
515 | + CGroupConfigurator._instance = None |
516 | + configurator = CGroupConfigurator.get_instance() |
517 | + CGroupsTelemetry.reset() |
518 | +@@ -58,6 +58,9 @@ class CGroupConfiguratorSystemdTestCase(AgentTestCase): |
519 | + if mock_commands is not None: |
520 | + for command in mock_commands: |
521 | + mock_environment.add_command(command) |
522 | ++ if mock_files is not None: |
523 | ++ for file in mock_files: |
524 | ++ mock_environment.add_file(*file) |
525 | + configurator.mocks = mock_environment |
526 | + if initialize: |
527 | + if not enable: |
528 | +@@ -115,7 +118,8 @@ cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) |
529 | + cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) |
530 | + cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) |
531 | + ''')] |
532 | +- with self._get_cgroup_configurator(mock_commands=command_mocks) as configurator: |
533 | ++ v2_files = [("/sys/fs/cgroup/unified/cgroup.subtree_control", os.path.join(data_dir, 'cgroups', 'sys_fs_cgroup_unified_cgroup_no_mem_cpu.controllers'))] |
534 | ++ with self._get_cgroup_configurator(mock_commands=command_mocks, mock_files=v2_files) as configurator: |
535 | + tracked = CGroupsTelemetry._tracked |
536 | + |
537 | + self.assertFalse(configurator.enabled(), "Cgroups should not be enabled") |
538 | +@@ -135,7 +139,8 @@ cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,de |
539 | + cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) |
540 | + ''')] |
541 | + |
542 | +- with self._get_cgroup_configurator(mock_commands=command_mocks) as configurator: |
543 | ++ v2_files = [("/sys/fs/cgroup/unified/cgroup.subtree_control", os.path.join(data_dir, 'cgroups', 'sys_fs_cgroup_unified_cgroup_no_mem_cpu.controllers'))] |
544 | ++ with self._get_cgroup_configurator(mock_commands=command_mocks, mock_files=v2_files) as configurator: |
545 | + tracked = CGroupsTelemetry._tracked |
546 | + agent_drop_in_file_cpu_quota = configurator.mocks.get_mapped_path(UnitFilePaths.cpu_quota) |
547 | + |
548 | +--- /dev/null |
549 | ++++ b/tests/data/cgroups/sys_fs_cgroup_unified_cgroup_no_mem_cpu.controllers |
550 | +@@ -0,0 +1,5 @@ |
551 | ++io |
552 | ++pids |
553 | ++perf_event |
554 | ++rdma |
555 | ++freezer |
556 | diff --git a/debian/patches/fix_systemd_networkd_lease_file_path b/debian/patches/fix_systemd_networkd_lease_file_path |
557 | new file mode 100644 |
558 | index 0000000..85fda52 |
559 | --- /dev/null |
560 | +++ b/debian/patches/fix_systemd_networkd_lease_file_path |
561 | @@ -0,0 +1,66 @@ |
562 | +Description: Ubuntu versions >= 18.04 look for systemd-networkd lease files. |
563 | + Currently, the package was configuring systemd-networkd but |
564 | + checking for dhclient lease files. |
565 | +Forwarded: yes, https://github.com/Azure/WALinuxAgent/pull/2979 |
566 | +Author: Calvin Mwadime Makokha <calvin.mwadime@canonical.com> |
567 | + |
568 | +--- a/azurelinuxagent/common/logcollector_manifests.py |
569 | ++++ b/azurelinuxagent/common/logcollector_manifests.py |
570 | +@@ -83,6 +83,7 @@ |
571 | + copy,/var/lib/dhcp/dhclient.eth0.leases |
572 | + copy,/var/lib/dhclient/dhclient-eth0.leases |
573 | + copy,/var/lib/wicked/lease-eth0-dhcp-ipv4.xml |
574 | ++copy,/run/systemd/netif/leases/2 |
575 | + echo, |
576 | + |
577 | + echo,### Gathering Log Files ### |
578 | +--- a/azurelinuxagent/common/osutil/ubuntu.py |
579 | ++++ b/azurelinuxagent/common/osutil/ubuntu.py |
580 | +@@ -16,6 +16,8 @@ |
581 | + # Requires Python 2.6+ and Openssl 1.0+ |
582 | + # |
583 | + |
584 | ++import glob |
585 | ++import textwrap |
586 | + import time |
587 | + |
588 | + import azurelinuxagent.common.logger as logger |
589 | +@@ -132,6 +134,25 @@ |
590 | + def stop_agent_service(self): |
591 | + return shellutil.run("systemctl stop {0}".format(self.service_name), chk_err=False) |
592 | + |
593 | ++ def get_dhcp_lease_endpoint(self): |
594 | ++ pathglob = "/run/systemd/netif/leases/*" |
595 | ++ logger.info("looking for leases in path [{0}]".format(pathglob)) |
596 | ++ endpoint = None |
597 | ++ for lease_file in glob.glob(pathglob): |
598 | ++ with open(lease_file) as f: |
599 | ++ lease = f.read() |
600 | ++ for line in lease.splitlines(): |
601 | ++ if line.startswith("OPTION_245"): |
602 | ++ option_245 = line.split("=")[1] |
603 | ++ options = [int(i, 16) for i in textwrap.wrap(option_245, 2)] |
604 | ++ endpoint = "{0}.{1}.{2}.{3}".format(*options) |
605 | ++ logger.info("found endpoint [{0}]".format(endpoint)) |
606 | ++ if endpoint is not None: |
607 | ++ logger.info("cached endpoint found [{0}]".format(endpoint)) |
608 | ++ else: |
609 | ++ logger.info("cached endpoint not found") |
610 | ++ return endpoint |
611 | ++ |
612 | + |
613 | + class UbuntuOSUtil(Ubuntu16OSUtil): |
614 | + def __init__(self): # pylint: disable=W0235 |
615 | +--- a/azurelinuxagent/pa/deprovision/default.py |
616 | ++++ b/azurelinuxagent/pa/deprovision/default.py |
617 | +@@ -131,6 +131,10 @@ |
618 | + actions.append(DeprovisionAction(fileutil.rm_files, |
619 | + ["/var/lib/NetworkManager/dhclient-*.lease"])) |
620 | + |
621 | ++ # For Ubuntu >= 18.04, using systemd-networkd |
622 | ++ actions.append(DeprovisionAction(fileutil.rm_files, |
623 | ++ ["/run/systemd/netif/leases/*"])) |
624 | ++ |
625 | + def del_ext_handler_files(self, warnings, actions): # pylint: disable=W0613 |
626 | + ext_dirs = [d for d in os.listdir(conf.get_lib_dir()) |
627 | + if os.path.isdir(os.path.join(conf.get_lib_dir(), d)) |
628 | diff --git a/debian/patches/series b/debian/patches/series |
629 | index 6217ba6..8c9f6bb 100644 |
630 | --- a/debian/patches/series |
631 | +++ b/debian/patches/series |
632 | @@ -1,3 +1,4 @@ |
633 | -disable_import_test.patch |
634 | +fix_systemd_networkd_lease_file_path |
635 | +update_dhcp_client_ubuntu_supported_versions.patch |
636 | disable_udev_overrides.patch |
637 | -fix-udev-rules-for-azure.patch |
638 | +fix_cgroup_v2_mounting_and_systemd_process.patch |
639 | diff --git a/debian/patches/update_dhcp_client_ubuntu_supported_versions.patch b/debian/patches/update_dhcp_client_ubuntu_supported_versions.patch |
640 | new file mode 100644 |
641 | index 0000000..c8208c7 |
642 | --- /dev/null |
643 | +++ b/debian/patches/update_dhcp_client_ubuntu_supported_versions.patch |
644 | @@ -0,0 +1,39 @@ |
645 | +Description: Update the latest supported ubuntu version |
646 | +Forwarded: yes, https://github.com/Azure/WALinuxAgent/pull/2980 |
647 | +Author: Calvin Mwadime Makokha <calvin.mwadime@canonical.com> |
648 | + |
649 | +--- a/azurelinuxagent/common/osutil/factory.py |
650 | ++++ b/azurelinuxagent/common/osutil/factory.py |
651 | +@@ -66,15 +66,14 @@ |
652 | + return ClearLinuxUtil() |
653 | + |
654 | + if distro_name == "ubuntu": |
655 | +- if Version(distro_version) in [Version("12.04"), Version("12.10")]: |
656 | ++ ubuntu_version = Version(distro_version) |
657 | ++ if ubuntu_version in [Version("12.04"), Version("12.10")]: |
658 | + return Ubuntu12OSUtil() |
659 | +- if Version(distro_version) in [Version("14.04"), Version("14.10")]: |
660 | ++ if ubuntu_version in [Version("14.04"), Version("14.10")]: |
661 | + return Ubuntu14OSUtil() |
662 | +- if Version(distro_version) in [Version('16.04'), Version('16.10'), Version('17.04')]: |
663 | ++ if ubuntu_version in [Version('16.04'), Version('16.10'), Version('17.04')]: |
664 | + return Ubuntu16OSUtil() |
665 | +- if Version(distro_version) in [Version('18.04'), Version('18.10'), |
666 | +- Version('19.04'), Version('19.10'), |
667 | +- Version('20.04')]: |
668 | ++ if ubuntu_version >= Version('18.04') and ubuntu_version <= Version('24.04'): |
669 | + return Ubuntu18OSUtil() |
670 | + if distro_full_name == "Snappy Ubuntu Core": |
671 | + return UbuntuSnappyOSUtil() |
672 | + |
673 | +--- a/azurelinuxagent/common/osutil/ubuntu.py |
674 | ++++ b/azurelinuxagent/common/osutil/ubuntu.py |
675 | +@@ -88,7 +88,7 @@ class Ubuntu16OSUtil(Ubuntu14OSUtil): |
676 | + |
677 | + class Ubuntu18OSUtil(Ubuntu16OSUtil): |
678 | + """ |
679 | +- Ubuntu 18.04, 18.10, 19.04, 19.10, 20.04 |
680 | ++ Ubuntu >= 18.04 and <= 24.04 |
681 | + """ |
682 | + def __init__(self): |
683 | + super(Ubuntu18OSUtil, self).__init__() |
684 | diff --git a/debian/rules b/debian/rules |
685 | index c06ee11..0e7bd5a 100755 |
686 | --- a/debian/rules |
687 | +++ b/debian/rules |
688 | @@ -12,22 +12,19 @@ get-packaged-orig-source: |
689 | rm -rf orig_source |
690 | |
691 | %: |
692 | - dh $@ --with python3,systemd --buildsystem=pybuild |
693 | + dh $@ --with python3 --buildsystem=pybuild |
694 | |
695 | +execute_before_dh_installman: |
696 | + go-md2man -in=README.md -out=debian/walinuxagent.1 |
697 | |
698 | -override_dh_installinit: |
699 | - dh_installinit --no-restart-on-upgrade --name walinuxagent |
700 | - dh_installinit --no-restart-on-upgrade --name ephemeral-disk-warning |
701 | - |
702 | -override_dh_systemd_enable: |
703 | - dh_systemd_enable --name walinuxagent walinuxagent.service |
704 | - dh_systemd_enable --name ephemeral-disk-warning ephemeral-disk-warning.service |
705 | +override_dh_installsystemd: |
706 | + # remove service placed in the wrong path by upstream install |
707 | + rm -f debian/walinuxagent/lib/systemd/system/walinuxagent.service |
708 | + dh_installsystemd --name walinuxagent --no-stop-on-upgrade walinuxagent.service |
709 | + dh_installsystemd --name walinuxagent --no-stop-on-upgrade ephemeral-disk-warning.service |
710 | |
711 | override_dh_python3: |
712 | dh_python3 -O--buildsystem=pybuild --shebang "/usr/bin/env python3" |
713 | |
714 | override_dh_auto_test: |
715 | - # No test were run on any of the previous versions, temporarily |
716 | - # ignoring the failures as they're not regressions (LP: #1800499) |
717 | - # XXX: Those need to be fixed ASAP. |
718 | - -dh_auto_test -O--buildsystem=pybuild |
719 | + nosetests3 -a '!requires_sudo' tests |
720 | diff --git a/debian/walinuxagent.manpages b/debian/walinuxagent.manpages |
721 | new file mode 100644 |
722 | index 0000000..8b6ead3 |
723 | --- /dev/null |
724 | +++ b/debian/walinuxagent.manpages |
725 | @@ -0,0 +1 @@ |
726 | +debian/walinuxagent.1 |
727 | diff --git a/debian/walinuxagent.upstart b/debian/walinuxagent.upstart |
728 | deleted file mode 100644 |
729 | index a5f8a95..0000000 |
730 | --- a/debian/walinuxagent.upstart |
731 | +++ /dev/null |
732 | @@ -1,25 +0,0 @@ |
733 | -description "Windows Azure Linux agent" |
734 | -author "Ben Howard <ben.howard@canonical.com>" |
735 | - |
736 | -start on runlevel [2345] |
737 | -stop on runlevel [!2345] |
738 | - |
739 | -pre-start script |
740 | - |
741 | - [ -r /etc/default/walinuxagent ] && . /etc/default/walinuxagent |
742 | - |
743 | - if [ "$WALINUXAGENT_ENABLED" != "1" ]; then |
744 | - stop ; exit 0 |
745 | - fi |
746 | - |
747 | - if [ ! -x /usr/sbin/waagent ]; then |
748 | - stop ; exit 0 |
749 | - fi |
750 | - |
751 | - #Load the udf module |
752 | - modprobe -b udf |
753 | - |
754 | -end script |
755 | - |
756 | -exec /usr/bin/python3 /usr/sbin/waagent -daemon |
757 | - |
758 | diff --git a/debian/watch b/debian/watch |
759 | index 1cbe705..7892b9e 100644 |
760 | --- a/debian/watch |
761 | +++ b/debian/watch |
762 | @@ -1,3 +1,4 @@ |
763 | -version=3 |
764 | -opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/<project>-$1\.tar\.gz/ \ |
765 | - https://github.com/Azure/WALinuxAgent/tags .*/?(\d\.\d.\d{1,})\.tar\.gz |
766 | +version=4 |
767 | + opts="searchmode=plain,\ |
768 | + filenamemangle=s/.+?v?(\d+(?:\.\d+)*)/walinuxagent-$1\.tar\.gz/" \ |
769 | + https://api.github.com/repos/Azure/WALinuxAgent/releases https://api.github.com/repos/Azure/WALinuxAgent/tarball/v@ANY_VERSION@ |
See my comments in the mantic MP.