Merge ~lamoura/ubuntu/+source/ubuntu-advantage-tools:upload-27.8-jammy into ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel
- Git
- lp:~lamoura/ubuntu/+source/ubuntu-advantage-tools
- upload-27.8-jammy
- Merge into ubuntu/devel
Status: | Merged |
---|---|
Merged at revision: | 06882843231c960ea65fdd1fcb2d9f06fec8b071 |
Proposed branch: | ~lamoura/ubuntu/+source/ubuntu-advantage-tools:upload-27.8-jammy |
Merge into: | ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel |
Diff against target: |
3242 lines (+1504/-374) 41 files modified
debian/changelog (+21/-0) features/_version.feature (+1/-1) features/attach_validtoken.feature (+6/-6) features/attached_commands.feature (+23/-18) features/attached_enable.feature (+103/-17) features/aws-ids.yaml (+1/-0) features/azure-ids.yaml (+1/-0) features/enable_fips_vm.feature (+48/-37) features/realtime_kernel.feature (+128/-0) features/staging_commands.feature (+1/-1) features/ubuntu_pro.feature (+9/-9) features/ubuntu_pro_fips.feature (+270/-9) features/ubuntu_upgrade.feature (+1/-2) features/unattached_status.feature (+85/-68) help_data.yaml (+10/-0) lib/upgrade_lts_contract.py (+25/-5) tools/refresh-keyrings.sh (+4/-1) tox.ini (+3/-0) uaclient/clouds/identity.py (+2/-0) uaclient/clouds/tests/test_identity.py (+6/-3) uaclient/config.py (+1/-1) uaclient/contract.py (+1/-1) uaclient/entitlements/__init__.py (+2/-0) uaclient/entitlements/base.py (+19/-9) uaclient/entitlements/cis.py (+1/-1) uaclient/entitlements/fips.py (+69/-44) uaclient/entitlements/livepatch.py (+5/-0) uaclient/entitlements/realtime.py (+84/-0) uaclient/entitlements/tests/test_cc.py (+2/-0) uaclient/entitlements/tests/test_fips.py (+60/-35) uaclient/entitlements/tests/test_livepatch.py (+8/-0) uaclient/entitlements/tests/test_repo.py (+17/-7) uaclient/messages.py (+46/-0) uaclient/status.py (+4/-4) uaclient/tests/test_cli_attach.py (+2/-2) uaclient/tests/test_cli_collect_logs.py (+2/-2) uaclient/tests/test_cli_status.py (+49/-39) uaclient/tests/test_upgrade_lts_contract.py (+67/-1) uaclient/tests/test_util.py (+221/-27) uaclient/util.py (+95/-23) uaclient/version.py (+1/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robie Basak | ubuntu-sru | Approve | |
Canonical Server | Pending | ||
Review via email: mp+419498@code.launchpad.net |
Commit message
Description of the change
This MR represents the release of 27.8 for Jammy.
We have already uploaded the new package into our staging PPA:
https:/
And we have already created an SRU bug for it:
https:/
Let us know if there is anything else we need to address here
Sergio Durigan Junior (sergiodj) : | # |
Chad Smith (chad.smith) wrote : | # |
LGTM. Versioning looks good as previous upload to -proposed was rejected.
Sergio Durigan Junior (sergiodj) wrote : | # |
Uploaded:
$ dput ubuntu-
Trying to upload package to ubuntu
Checking signature on .changes
gpg: /home/sergio/
Checking signature on .dsc
gpg: /home/sergio/
Uploading to ubuntu (via ftp to upload.ubuntu.com):
Uploading ubuntu-
Uploading ubuntu-
Uploading ubuntu-
Uploading ubuntu-
Successfully uploaded packages.
Preview Diff
1 | diff --git a/debian/changelog b/debian/changelog | |||
2 | index b44d4d9..a272000 100644 | |||
3 | --- a/debian/changelog | |||
4 | +++ b/debian/changelog | |||
5 | @@ -1,3 +1,24 @@ | |||
6 | 1 | ubuntu-advantage-tools (27.8~22.04.1) jammy; urgency=medium | ||
7 | 2 | |||
8 | 3 | * New upstream release 27.8 (LP: #1969125) | ||
9 | 4 | - entitlements: apply overrides from the contract response | ||
10 | 5 | - fips: | ||
11 | 6 | + unhold fips packages when enabling fips-updates | ||
12 | 7 | + Automatically disable fips service before enabling fips-updates | ||
13 | 8 | + unhold more packages when enabling fips | ||
14 | 9 | - lib: fix upgrade script for unsupported releases (LP: #1968067) | ||
15 | 10 | - realtime: add support for realtime kernel beta service on Jammy | ||
16 | 11 | |||
17 | 12 | -- Lucas Moura <lucas.moura@canonical.com> Wed, 13 Apr 2022 18:17:02 -0300 | ||
18 | 13 | |||
19 | 14 | ubuntu-advantage-tools (27.7.1~22.04.1) jammy; urgency=medium | ||
20 | 15 | |||
21 | 16 | * fips: | ||
22 | 17 | - make fips service incompatible with fips-updates | ||
23 | 18 | - unhold more packages when enabling fips | ||
24 | 19 | |||
25 | 20 | -- Lucas Moura <lucas.moura@canonical.com> Thu, 31 Mar 2022 16:18:36 -0300 | ||
26 | 21 | |||
27 | 1 | ubuntu-advantage-tools (27.7~22.04.1) jammy; urgency=medium | 22 | ubuntu-advantage-tools (27.7~22.04.1) jammy; urgency=medium |
28 | 2 | 23 | ||
29 | 3 | * d/changelog: | 24 | * d/changelog: |
30 | diff --git a/features/_version.feature b/features/_version.feature | |||
31 | index b972500..35b73f7 100644 | |||
32 | --- a/features/_version.feature | |||
33 | +++ b/features/_version.feature | |||
34 | @@ -15,7 +15,7 @@ Feature: UA is expected version | |||
35 | 15 | Scenario Outline: Check ua version | 15 | Scenario Outline: Check ua version |
36 | 16 | Given a `<release>` machine with ubuntu-advantage-tools installed | 16 | Given a `<release>` machine with ubuntu-advantage-tools installed |
37 | 17 | When I run `dpkg-query --showformat='${Version}' --show ubuntu-advantage-tools` with sudo | 17 | When I run `dpkg-query --showformat='${Version}' --show ubuntu-advantage-tools` with sudo |
39 | 18 | Then stdout matches regexp: | 18 | Then I will see the following on stdout |
40 | 19 | """ | 19 | """ |
41 | 20 | {UACLIENT_BEHAVE_CHECK_VERSION} | 20 | {UACLIENT_BEHAVE_CHECK_VERSION} |
42 | 21 | """ | 21 | """ |
43 | diff --git a/features/attach_validtoken.feature b/features/attach_validtoken.feature | |||
44 | index 25f763b..35fd90f 100644 | |||
45 | --- a/features/attach_validtoken.feature | |||
46 | +++ b/features/attach_validtoken.feature | |||
47 | @@ -11,7 +11,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
48 | 11 | And I run `ua status --all` as non-root | 11 | And I run `ua status --all` as non-root |
49 | 12 | Then stdout matches regexp: | 12 | Then stdout matches regexp: |
50 | 13 | """ | 13 | """ |
52 | 14 | SERVICE ENTITLED STATUS DESCRIPTION | 14 | SERVICE +ENTITLED STATUS DESCRIPTION |
53 | 15 | cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages | 15 | cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages |
54 | 16 | cis +yes +n/a +Security compliance and audit tools | 16 | cis +yes +n/a +Security compliance and audit tools |
55 | 17 | esm-apps +yes +n/a +UA Apps: Extended Security Maintenance \(ESM\) | 17 | esm-apps +yes +n/a +UA Apps: Extended Security Maintenance \(ESM\) |
56 | @@ -58,7 +58,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
57 | 58 | """ | 58 | """ |
58 | 59 | And stdout matches regexp: | 59 | And stdout matches regexp: |
59 | 60 | """ | 60 | """ |
61 | 61 | SERVICE ENTITLED STATUS DESCRIPTION | 61 | SERVICE +ENTITLED STATUS DESCRIPTION |
62 | 62 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages | 62 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages |
63 | 63 | """ | 63 | """ |
64 | 64 | And stdout matches regexp: | 64 | And stdout matches regexp: |
65 | @@ -315,7 +315,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
66 | 315 | """ | 315 | """ |
67 | 316 | And stdout matches regexp: | 316 | And stdout matches regexp: |
68 | 317 | """ | 317 | """ |
70 | 318 | SERVICE ENTITLED STATUS DESCRIPTION | 318 | SERVICE +ENTITLED STATUS DESCRIPTION |
71 | 319 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages | 319 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages |
72 | 320 | """ | 320 | """ |
73 | 321 | And stdout matches regexp: | 321 | And stdout matches regexp: |
74 | @@ -375,7 +375,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
75 | 375 | """ | 375 | """ |
76 | 376 | And stdout matches regexp: | 376 | And stdout matches regexp: |
77 | 377 | """ | 377 | """ |
79 | 378 | SERVICE ENTITLED STATUS DESCRIPTION | 378 | SERVICE +ENTITLED STATUS DESCRIPTION |
80 | 379 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages | 379 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages |
81 | 380 | """ | 380 | """ |
82 | 381 | And stdout matches regexp: | 381 | And stdout matches regexp: |
83 | @@ -435,7 +435,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
84 | 435 | """ | 435 | """ |
85 | 436 | And stdout matches regexp: | 436 | And stdout matches regexp: |
86 | 437 | """ | 437 | """ |
88 | 438 | SERVICE ENTITLED STATUS DESCRIPTION | 438 | SERVICE +ENTITLED STATUS DESCRIPTION |
89 | 439 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages | 439 | cc-eal +yes +<cc_status> +Common Criteria EAL2 Provisioning Packages |
90 | 440 | """ | 440 | """ |
91 | 441 | And stdout matches regexp: | 441 | And stdout matches regexp: |
92 | @@ -477,7 +477,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage | |||
93 | 477 | When I run `ua status` with sudo | 477 | When I run `ua status` with sudo |
94 | 478 | Then stdout matches regexp: | 478 | Then stdout matches regexp: |
95 | 479 | """ | 479 | """ |
97 | 480 | SERVICE ENTITLED STATUS DESCRIPTION | 480 | SERVICE +ENTITLED STATUS DESCRIPTION |
98 | 481 | cc-eal +yes +<cc-eal> +Common Criteria EAL2 Provisioning Packages | 481 | cc-eal +yes +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
99 | 482 | """ | 482 | """ |
100 | 483 | And stdout matches regexp: | 483 | And stdout matches regexp: |
101 | diff --git a/features/attached_commands.feature b/features/attached_commands.feature | |||
102 | index dd6cf1a..f3ed252 100644 | |||
103 | --- a/features/attached_commands.feature | |||
104 | +++ b/features/attached_commands.feature | |||
105 | @@ -129,9 +129,9 @@ Feature: Command behaviour when attached to an UA subscription | |||
106 | 129 | 129 | ||
107 | 130 | Examples: ubuntu release | 130 | Examples: ubuntu release |
108 | 131 | | release | valid_services | | 131 | | release | valid_services | |
112 | 132 | | xenial | cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros,\nros-updates. | | 132 | | xenial | cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch,\nrealtime-kernel, ros, ros-updates. | |
113 | 133 | | bionic | cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros,\nros-updates. | | 133 | | bionic | cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch,\nrealtime-kernel, ros, ros-updates. | |
114 | 134 | | focal | cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, ros,\nros-updates, usg. | | 134 | | focal | cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, realtime-kernel,\nros, ros-updates, usg. | |
115 | 135 | 135 | ||
116 | 136 | @series.xenial | 136 | @series.xenial |
117 | 137 | @series.bionic | 137 | @series.bionic |
118 | @@ -148,8 +148,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
119 | 148 | And stderr matches regexp: | 148 | And stderr matches regexp: |
120 | 149 | """ | 149 | """ |
121 | 150 | Cannot disable unknown service 'foobar'. | 150 | Cannot disable unknown service 'foobar'. |
124 | 151 | Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros, | 151 | Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, |
125 | 152 | ros-updates. | 152 | realtime-kernel, ros, ros-updates. |
126 | 153 | """ | 153 | """ |
127 | 154 | And I verify that running `ua disable esm-infra` `as non-root` exits `1` | 154 | And I verify that running `ua disable esm-infra` `as non-root` exits `1` |
128 | 155 | And stderr matches regexp: | 155 | And stderr matches regexp: |
129 | @@ -187,8 +187,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
130 | 187 | And stderr matches regexp: | 187 | And stderr matches regexp: |
131 | 188 | """ | 188 | """ |
132 | 189 | Cannot disable unknown service 'foobar'. | 189 | Cannot disable unknown service 'foobar'. |
135 | 190 | Try cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, ros, | 190 | Try cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, realtime-kernel, |
136 | 191 | ros-updates, usg. | 191 | ros, ros-updates, usg. |
137 | 192 | """ | 192 | """ |
138 | 193 | And I verify that running `ua disable esm-infra` `as non-root` exits `1` | 193 | And I verify that running `ua disable esm-infra` `as non-root` exits `1` |
139 | 194 | And stderr matches regexp: | 194 | And stderr matches regexp: |
140 | @@ -231,7 +231,7 @@ Feature: Command behaviour when attached to an UA subscription | |||
141 | 231 | When I run `ua status --all` as non-root | 231 | When I run `ua status --all` as non-root |
142 | 232 | Then stdout matches regexp: | 232 | Then stdout matches regexp: |
143 | 233 | """ | 233 | """ |
145 | 234 | SERVICE AVAILABLE DESCRIPTION | 234 | SERVICE +AVAILABLE DESCRIPTION |
146 | 235 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages | 235 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
147 | 236 | """ | 236 | """ |
148 | 237 | Then stdout matches regexp: | 237 | Then stdout matches regexp: |
149 | @@ -241,6 +241,7 @@ Feature: Command behaviour when attached to an UA subscription | |||
150 | 241 | fips +<fips> +NIST-certified core packages | 241 | fips +<fips> +NIST-certified core packages |
151 | 242 | fips-updates +<fips> +NIST-certified core packages with priority security updates | 242 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
152 | 243 | livepatch +yes +Canonical Livepatch service | 243 | livepatch +yes +Canonical Livepatch service |
153 | 244 | realtime-kernel +<realtime-kernel> +Beta-version Ubuntu Kernel with PREEMPT_RT patches | ||
154 | 244 | ros +<ros> +Security Updates for the Robot Operating System | 245 | ros +<ros> +Security Updates for the Robot Operating System |
155 | 245 | ros-updates +<ros> +All Updates for the Robot Operating System | 246 | ros-updates +<ros> +All Updates for the Robot Operating System |
156 | 246 | """ | 247 | """ |
157 | @@ -280,10 +281,10 @@ Feature: Command behaviour when attached to an UA subscription | |||
158 | 280 | """ | 281 | """ |
159 | 281 | 282 | ||
160 | 282 | Examples: ubuntu release | 283 | Examples: ubuntu release |
165 | 283 | | release | esm-apps | cc-eal | cis | fips | fips-update | ros | cis_or_usg | | 284 | | release | esm-apps | cc-eal | cis | fips | fips-update | ros | cis_or_usg | realtime-kernel | |
166 | 284 | | xenial | yes | yes | yes | yes | yes | yes | cis | | 285 | | xenial | yes | yes | yes | yes | yes | yes | cis | no | |
167 | 285 | | bionic | yes | yes | yes | yes | yes | yes | cis | | 286 | | bionic | yes | yes | yes | yes | yes | yes | cis | no | |
168 | 286 | | focal | yes | no | yes | yes | yes | no | usg | | 287 | | focal | yes | no | yes | yes | yes | no | usg | no | |
169 | 287 | 288 | ||
170 | 288 | @series.all | 289 | @series.all |
171 | 289 | @uses.config.machine_type.lxd.container | 290 | @uses.config.machine_type.lxd.container |
172 | @@ -361,8 +362,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
173 | 361 | And I run `ua status --all` with sudo | 362 | And I run `ua status --all` with sudo |
174 | 362 | Then stdout matches regexp: | 363 | Then stdout matches regexp: |
175 | 363 | """ | 364 | """ |
178 | 364 | SERVICE ENTITLED STATUS DESCRIPTION | 365 | SERVICE +ENTITLED STATUS DESCRIPTION |
179 | 365 | cc-eal no | 366 | cc-eal +no |
180 | 366 | """ | 367 | """ |
181 | 367 | When I run `ua --version` as non-root | 368 | When I run `ua --version` as non-root |
182 | 368 | Then I will see the uaclient version on stdout with features ` +disable_auto_attach +machine_token_overlay -other` | 369 | Then I will see the uaclient version on stdout with features ` +disable_auto_attach +machine_token_overlay -other` |
183 | @@ -403,8 +404,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
184 | 403 | And stderr matches regexp: | 404 | And stderr matches regexp: |
185 | 404 | """ | 405 | """ |
186 | 405 | Cannot disable unknown service 'foobar'. | 406 | Cannot disable unknown service 'foobar'. |
189 | 406 | Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros, | 407 | Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, |
190 | 407 | ros-updates. | 408 | realtime-kernel, ros, ros-updates. |
191 | 408 | """ | 409 | """ |
192 | 409 | When I run `ua status` with sudo | 410 | When I run `ua status` with sudo |
193 | 410 | Then stdout matches regexp: | 411 | Then stdout matches regexp: |
194 | @@ -449,8 +450,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
195 | 449 | And stderr matches regexp: | 450 | And stderr matches regexp: |
196 | 450 | """ | 451 | """ |
197 | 451 | Cannot disable unknown service 'foobar'. | 452 | Cannot disable unknown service 'foobar'. |
200 | 452 | Try cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, ros, | 453 | Try cc-eal, esm-apps, esm-infra, fips, fips-updates, livepatch, realtime-kernel, |
201 | 453 | ros-updates, usg. | 454 | ros, ros-updates, usg. |
202 | 454 | """ | 455 | """ |
203 | 455 | When I run `ua status` with sudo | 456 | When I run `ua status` with sudo |
204 | 456 | Then stdout matches regexp: | 457 | Then stdout matches regexp: |
205 | @@ -558,6 +559,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
206 | 558 | \(https://ubuntu.com/security/certifications#fips\) | 559 | \(https://ubuntu.com/security/certifications#fips\) |
207 | 559 | - livepatch: Canonical Livepatch service | 560 | - livepatch: Canonical Livepatch service |
208 | 560 | \(https://ubuntu.com/security/livepatch\) | 561 | \(https://ubuntu.com/security/livepatch\) |
209 | 562 | - realtime-kernel: Beta-version Ubuntu Kernel with PREEMPT_RT patches | ||
210 | 563 | \(https://ubuntu.com/realtime-kernel\) | ||
211 | 561 | - ros-updates: All Updates for the Robot Operating System | 564 | - ros-updates: All Updates for the Robot Operating System |
212 | 562 | \(https://ubuntu.com/robotics/ros-esm\) | 565 | \(https://ubuntu.com/robotics/ros-esm\) |
213 | 563 | - ros: Security Updates for the Robot Operating System | 566 | - ros: Security Updates for the Robot Operating System |
214 | @@ -657,6 +660,8 @@ Feature: Command behaviour when attached to an UA subscription | |||
215 | 657 | \(https://ubuntu.com/security/certifications#fips\) | 660 | \(https://ubuntu.com/security/certifications#fips\) |
216 | 658 | - livepatch: Canonical Livepatch service | 661 | - livepatch: Canonical Livepatch service |
217 | 659 | \(https://ubuntu.com/security/livepatch\) | 662 | \(https://ubuntu.com/security/livepatch\) |
218 | 663 | - realtime-kernel: Beta-version Ubuntu Kernel with PREEMPT_RT patches | ||
219 | 664 | \(https://ubuntu.com/realtime-kernel\) | ||
220 | 660 | - ros-updates: All Updates for the Robot Operating System | 665 | - ros-updates: All Updates for the Robot Operating System |
221 | 661 | \(https://ubuntu.com/robotics/ros-esm\) | 666 | \(https://ubuntu.com/robotics/ros-esm\) |
222 | 662 | - ros: Security Updates for the Robot Operating System | 667 | - ros: Security Updates for the Robot Operating System |
223 | diff --git a/features/attached_enable.feature b/features/attached_enable.feature | |||
224 | index 90a62cb..7944100 100644 | |||
225 | --- a/features/attached_enable.feature | |||
226 | +++ b/features/attached_enable.feature | |||
227 | @@ -669,7 +669,7 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
228 | 669 | And stdout is a json matching the `ua_operation` schema | 669 | And stdout is a json matching the `ua_operation` schema |
229 | 670 | And I will see the following on stdout: | 670 | And I will see the following on stdout: |
230 | 671 | """ | 671 | """ |
232 | 672 | {"_schema_version": "0.1", "errors": [{"message": "Cannot enable FIPS when Livepatch is enabled.", "service": "fips", "type": "service"}], "failed_services": ["fips"], "needs_reboot": false, "processed_services": [], "result": "failure", "warnings": []} | 672 | {"_schema_version": "0.1", "errors": [{"message": "Cannot enable FIPS when Livepatch is enabled.", "message_code": "incompatible-service-stops-enable", "service": "fips", "type": "service"}], "failed_services": ["fips"], "needs_reboot": false, "processed_services": [], "result": "failure", "warnings": []} |
233 | 673 | """ | 673 | """ |
234 | 674 | 674 | ||
235 | 675 | @slow | 675 | @slow |
236 | @@ -693,6 +693,7 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
237 | 693 | Then I will see the following on stdout | 693 | Then I will see the following on stdout |
238 | 694 | """ | 694 | """ |
239 | 695 | One moment, checking your subscription first | 695 | One moment, checking your subscription first |
240 | 696 | Disabling incompatible service: Livepatch | ||
241 | 696 | Updating package lists | 697 | Updating package lists |
242 | 697 | Installing FIPS packages | 698 | Installing FIPS packages |
243 | 698 | FIPS enabled | 699 | FIPS enabled |
244 | @@ -761,21 +762,21 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
245 | 761 | And I run `ua status --all` as non-root | 762 | And I run `ua status --all` as non-root |
246 | 762 | Then stdout matches regexp | 763 | Then stdout matches regexp |
247 | 763 | """ | 764 | """ |
249 | 764 | ros yes disabled Security Updates for the Robot Operating System | 765 | ros +yes disabled Security Updates for the Robot Operating System |
250 | 765 | """ | 766 | """ |
251 | 766 | When I run `ua enable ros --assume-yes --beta` with sudo | 767 | When I run `ua enable ros --assume-yes --beta` with sudo |
252 | 767 | And I run `ua status --all` as non-root | 768 | And I run `ua status --all` as non-root |
253 | 768 | Then stdout matches regexp | 769 | Then stdout matches regexp |
254 | 769 | """ | 770 | """ |
256 | 770 | ros yes enabled Security Updates for the Robot Operating System | 771 | ros +yes enabled Security Updates for the Robot Operating System |
257 | 771 | """ | 772 | """ |
258 | 772 | And stdout matches regexp | 773 | And stdout matches regexp |
259 | 773 | """ | 774 | """ |
261 | 774 | esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\) | 775 | esm-apps +yes enabled UA Apps: Extended Security Maintenance \(ESM\) |
262 | 775 | """ | 776 | """ |
263 | 776 | And stdout matches regexp | 777 | And stdout matches regexp |
264 | 777 | """ | 778 | """ |
266 | 778 | esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\) | 779 | esm-infra +yes enabled UA Infra: Extended Security Maintenance \(ESM\) |
267 | 779 | """ | 780 | """ |
268 | 780 | When I verify that running `ua disable esm-apps` `with sudo` and stdin `N` exits `1` | 781 | When I verify that running `ua disable esm-apps` `with sudo` and stdin `N` exits `1` |
269 | 781 | Then stdout matches regexp | 782 | Then stdout matches regexp |
270 | @@ -793,11 +794,11 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
271 | 793 | When I run `ua status --all` as non-root | 794 | When I run `ua status --all` as non-root |
272 | 794 | Then stdout matches regexp | 795 | Then stdout matches regexp |
273 | 795 | """ | 796 | """ |
275 | 796 | ros yes disabled Security Updates for the Robot Operating System | 797 | ros +yes disabled Security Updates for the Robot Operating System |
276 | 797 | """ | 798 | """ |
277 | 798 | And stdout matches regexp | 799 | And stdout matches regexp |
278 | 799 | """ | 800 | """ |
280 | 800 | esm-apps yes disabled UA Apps: Extended Security Maintenance \(ESM\) | 801 | esm-apps +yes disabled UA Apps: Extended Security Maintenance \(ESM\) |
281 | 801 | """ | 802 | """ |
282 | 802 | When I verify that running `ua enable ros --beta` `with sudo` and stdin `N` exits `1` | 803 | When I verify that running `ua enable ros --beta` `with sudo` and stdin `N` exits `1` |
283 | 803 | Then stdout matches regexp | 804 | Then stdout matches regexp |
284 | @@ -818,15 +819,15 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
285 | 818 | When I run `ua status --all` as non-root | 819 | When I run `ua status --all` as non-root |
286 | 819 | Then stdout matches regexp | 820 | Then stdout matches regexp |
287 | 820 | """ | 821 | """ |
289 | 821 | ros yes enabled Security Updates for the Robot Operating System | 822 | ros +yes enabled Security Updates for the Robot Operating System |
290 | 822 | """ | 823 | """ |
291 | 823 | And stdout matches regexp | 824 | And stdout matches regexp |
292 | 824 | """ | 825 | """ |
294 | 825 | esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\) | 826 | esm-apps +yes enabled UA Apps: Extended Security Maintenance \(ESM\) |
295 | 826 | """ | 827 | """ |
296 | 827 | And stdout matches regexp | 828 | And stdout matches regexp |
297 | 828 | """ | 829 | """ |
299 | 829 | esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\) | 830 | esm-infra +yes enabled UA Infra: Extended Security Maintenance \(ESM\) |
300 | 830 | """ | 831 | """ |
301 | 831 | When I run `apt-cache policy` as non-root | 832 | When I run `apt-cache policy` as non-root |
302 | 832 | Then apt-cache policy for the following url has permission `500` | 833 | Then apt-cache policy for the following url has permission `500` |
303 | @@ -840,7 +841,7 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
304 | 840 | And I run `ua status --all` as non-root | 841 | And I run `ua status --all` as non-root |
305 | 841 | Then stdout matches regexp | 842 | Then stdout matches regexp |
306 | 842 | """ | 843 | """ |
308 | 843 | ros-updates yes enabled All Updates for the Robot Operating System | 844 | ros-updates +yes enabled All Updates for the Robot Operating System |
309 | 844 | """ | 845 | """ |
310 | 845 | When I run `apt-cache policy` as non-root | 846 | When I run `apt-cache policy` as non-root |
311 | 846 | Then apt-cache policy for the following url has permission `500` | 847 | Then apt-cache policy for the following url has permission `500` |
312 | @@ -869,11 +870,11 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
313 | 869 | When I run `ua status --all` as non-root | 870 | When I run `ua status --all` as non-root |
314 | 870 | Then stdout matches regexp | 871 | Then stdout matches regexp |
315 | 871 | """ | 872 | """ |
317 | 872 | ros-updates yes enabled All Updates for the Robot Operating System | 873 | ros-updates +yes enabled All Updates for the Robot Operating System |
318 | 873 | """ | 874 | """ |
319 | 874 | And stdout matches regexp | 875 | And stdout matches regexp |
320 | 875 | """ | 876 | """ |
322 | 876 | ros yes enabled Security Updates for the Robot Operating System | 877 | ros +yes enabled Security Updates for the Robot Operating System |
323 | 877 | """ | 878 | """ |
324 | 878 | When I run `ua disable ros-updates --assume-yes` with sudo | 879 | When I run `ua disable ros-updates --assume-yes` with sudo |
325 | 879 | When I run `ua disable ros --assume-yes` with sudo | 880 | When I run `ua disable ros --assume-yes` with sudo |
326 | @@ -883,19 +884,19 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
327 | 883 | When I run `ua status --all` as non-root | 884 | When I run `ua status --all` as non-root |
328 | 884 | Then stdout matches regexp | 885 | Then stdout matches regexp |
329 | 885 | """ | 886 | """ |
331 | 886 | ros-updates yes enabled All Updates for the Robot Operating System | 887 | ros-updates +yes enabled All Updates for the Robot Operating System |
332 | 887 | """ | 888 | """ |
333 | 888 | And stdout matches regexp | 889 | And stdout matches regexp |
334 | 889 | """ | 890 | """ |
336 | 890 | ros yes enabled Security Updates for the Robot Operating System | 891 | ros +yes enabled Security Updates for the Robot Operating System |
337 | 891 | """ | 892 | """ |
338 | 892 | And stdout matches regexp | 893 | And stdout matches regexp |
339 | 893 | """ | 894 | """ |
341 | 894 | esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\) | 895 | esm-apps +yes enabled UA Apps: Extended Security Maintenance \(ESM\) |
342 | 895 | """ | 896 | """ |
343 | 896 | And stdout matches regexp | 897 | And stdout matches regexp |
344 | 897 | """ | 898 | """ |
346 | 898 | esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\) | 899 | esm-infra +yes enabled UA Infra: Extended Security Maintenance \(ESM\) |
347 | 899 | """ | 900 | """ |
348 | 900 | When I run `ua detach` `with sudo` and stdin `y` | 901 | When I run `ua detach` `with sudo` and stdin `y` |
349 | 901 | Then stdout matches regexp: | 902 | Then stdout matches regexp: |
350 | @@ -911,3 +912,88 @@ Feature: Enable command behaviour when attached to an UA subscription | |||
351 | 911 | | release | ros-security-source | ros-updates-source | | 912 | | release | ros-security-source | ros-updates-source | |
352 | 912 | | xenial | https://esm.ubuntu.com/ros/ubuntu xenial-security/main | https://esm.ubuntu.com/ros-updates/ubuntu xenial-updates/main | | 913 | | xenial | https://esm.ubuntu.com/ros/ubuntu xenial-security/main | https://esm.ubuntu.com/ros-updates/ubuntu xenial-updates/main | |
353 | 913 | | bionic | https://esm.ubuntu.com/ros/ubuntu bionic-security/main | https://esm.ubuntu.com/ros-updates/ubuntu bionic-updates/main | | 914 | | bionic | https://esm.ubuntu.com/ros/ubuntu bionic-security/main | https://esm.ubuntu.com/ros-updates/ubuntu bionic-updates/main | |
354 | 915 | |||
355 | 916 | # Overall test for overrides; in the future, when many services | ||
356 | 917 | # have overrides, we can consider removing this | ||
357 | 918 | # FIPS is a good choice because we expect to have it | ||
358 | 919 | @series.focal | ||
359 | 920 | @uses.config.machine_type.aws.generic | ||
360 | 921 | Scenario: Cloud overrides for a generic aws Focal instance | ||
361 | 922 | Given a `focal` machine with ubuntu-advantage-tools installed | ||
362 | 923 | When I create the file `/tmp/machine-token-overlay.json` with the following: | ||
363 | 924 | """ | ||
364 | 925 | { | ||
365 | 926 | "machineTokenInfo": { | ||
366 | 927 | "contractInfo": { | ||
367 | 928 | "resourceEntitlements": [ | ||
368 | 929 | { | ||
369 | 930 | "type": "fips", | ||
370 | 931 | "entitled": true, | ||
371 | 932 | "affordances": { | ||
372 | 933 | "architectures": [ | ||
373 | 934 | "amd64", | ||
374 | 935 | "ppc64el", | ||
375 | 936 | "ppc64le", | ||
376 | 937 | "s390x", | ||
377 | 938 | "x86_64" | ||
378 | 939 | ], | ||
379 | 940 | "series": [ | ||
380 | 941 | "xenial", | ||
381 | 942 | "bionic", | ||
382 | 943 | "focal" | ||
383 | 944 | ] | ||
384 | 945 | }, | ||
385 | 946 | "directives": { | ||
386 | 947 | "additionalPackages": [ | ||
387 | 948 | "ubuntu-fips" | ||
388 | 949 | ], | ||
389 | 950 | "aptKey": "E23341B2A1467EDBF07057D6C1997C40EDE22758", | ||
390 | 951 | "aptURL": "https://esm.ubuntu.com/fips", | ||
391 | 952 | "suites": [ | ||
392 | 953 | "xenial", | ||
393 | 954 | "bionic", | ||
394 | 955 | "focal" | ||
395 | 956 | ] | ||
396 | 957 | }, | ||
397 | 958 | "obligations": { | ||
398 | 959 | "enableByDefault": false | ||
399 | 960 | }, | ||
400 | 961 | "overrides": [ | ||
401 | 962 | { | ||
402 | 963 | "selector": { | ||
403 | 964 | "series": "focal" | ||
404 | 965 | }, | ||
405 | 966 | "directives": { | ||
406 | 967 | "additionalPackages": [ | ||
407 | 968 | "some-package-focal" | ||
408 | 969 | ] | ||
409 | 970 | } | ||
410 | 971 | }, | ||
411 | 972 | { | ||
412 | 973 | "selector": { | ||
413 | 974 | "cloud": "aws" | ||
414 | 975 | }, | ||
415 | 976 | "directives": { | ||
416 | 977 | "additionalPackages": [ | ||
417 | 978 | "some-package-aws" | ||
418 | 979 | ] | ||
419 | 980 | } | ||
420 | 981 | } | ||
421 | 982 | ] | ||
422 | 983 | } | ||
423 | 984 | ] | ||
424 | 985 | } | ||
425 | 986 | } | ||
426 | 987 | } | ||
427 | 988 | """ | ||
428 | 989 | And I append the following on uaclient config: | ||
429 | 990 | """ | ||
430 | 991 | features: | ||
431 | 992 | machine_token_overlay: "/tmp/machine-token-overlay.json" | ||
432 | 993 | """ | ||
433 | 994 | And I attach `contract_token` with sudo | ||
434 | 995 | And I verify that running `ua enable fips --assume-yes` `with sudo` exits `1` | ||
435 | 996 | Then stderr matches regexp: | ||
436 | 997 | """ | ||
437 | 998 | Stderr: E: Unable to locate package some-package-aws | ||
438 | 999 | """ | ||
439 | diff --git a/features/aws-ids.yaml b/features/aws-ids.yaml | |||
440 | index f2376ad..ec6c43c 100644 | |||
441 | --- a/features/aws-ids.yaml | |||
442 | +++ b/features/aws-ids.yaml | |||
443 | @@ -3,3 +3,4 @@ bionic-fips: ami-03b75f613f80bcff1 | |||
444 | 3 | focal: ami-0489b8bdbbf3a3b32 | 3 | focal: ami-0489b8bdbbf3a3b32 |
445 | 4 | xenial: ami-011bcfe2bea365b6a | 4 | xenial: ami-011bcfe2bea365b6a |
446 | 5 | xenial-fips: ami-077e4c339a098fc9f | 5 | xenial-fips: ami-077e4c339a098fc9f |
447 | 6 | focal-fips: ami-02782bf2569bf457c | ||
448 | diff --git a/features/azure-ids.yaml b/features/azure-ids.yaml | |||
449 | index 735223f..10b1155 100644 | |||
450 | --- a/features/azure-ids.yaml | |||
451 | +++ b/features/azure-ids.yaml | |||
452 | @@ -3,3 +3,4 @@ focal: "Canonical:0001-com-ubuntu-pro-focal:pro-20_04-lts" | |||
453 | 3 | xenial: "Canonical:0001-com-ubuntu-pro-xenial:pro-16_04-lts" | 3 | xenial: "Canonical:0001-com-ubuntu-pro-xenial:pro-16_04-lts" |
454 | 4 | bionic-fips: "Canonical:0001-com-ubuntu-pro-bionic-fips:pro-fips-18_04" | 4 | bionic-fips: "Canonical:0001-com-ubuntu-pro-bionic-fips:pro-fips-18_04" |
455 | 5 | xenial-fips: "Canonical:0001-com-ubuntu-pro-xenial-fips:pro-fips-16_04-private" | 5 | xenial-fips: "Canonical:0001-com-ubuntu-pro-xenial-fips:pro-fips-16_04-private" |
456 | 6 | focal-fips: "Canonical:0001-com-ubuntu-pro-focal-fips:pro-fips-20_04" | ||
457 | diff --git a/features/enable_fips_vm.feature b/features/enable_fips_vm.feature | |||
458 | index a055354..03ccd39 100644 | |||
459 | --- a/features/enable_fips_vm.feature | |||
460 | +++ b/features/enable_fips_vm.feature | |||
461 | @@ -462,14 +462,11 @@ Feature: FIPS enablement in lxd VMs | |||
462 | 462 | | focal | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu focal-updates/main | | 462 | | focal | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu focal-updates/main | |
463 | 463 | 463 | ||
464 | 464 | @slow | 464 | @slow |
467 | 465 | @series.xenial | 465 | @series.lts |
466 | 466 | @series.bionic | ||
468 | 467 | @uses.config.machine_type.lxd.vm | 466 | @uses.config.machine_type.lxd.vm |
469 | 468 | Scenario Outline: Attached enable fips-updates on fips enabled vm | 467 | Scenario Outline: Attached enable fips-updates on fips enabled vm |
470 | 469 | Given a `<release>` machine with ubuntu-advantage-tools installed | 468 | Given a `<release>` machine with ubuntu-advantage-tools installed |
471 | 470 | When I attach `contract_token` with sudo | 469 | When I attach `contract_token` with sudo |
472 | 471 | And I run `ua disable livepatch` with sudo | ||
473 | 472 | And I run `DEBIAN_FRONTEND=noninteractive apt-get install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" -y openssh-client openssh-server strongswan` with sudo, retrying exit [100] | ||
474 | 473 | And I run `ua enable fips --assume-yes` with sudo | 470 | And I run `ua enable fips --assume-yes` with sudo |
475 | 474 | Then stdout matches regexp: | 471 | Then stdout matches regexp: |
476 | 475 | """ | 472 | """ |
477 | @@ -484,47 +481,61 @@ Feature: FIPS enablement in lxd VMs | |||
478 | 484 | fips +yes enabled | 481 | fips +yes enabled |
479 | 485 | """ | 482 | """ |
480 | 486 | When I reboot the `<release>` machine | 483 | When I reboot the `<release>` machine |
482 | 487 | And I run `ua enable fips-updates --assume-yes` with sudo | 484 | And I run `uname -r` as non-root |
483 | 488 | Then stdout matches regexp: | 485 | Then stdout matches regexp: |
484 | 489 | """ | 486 | """ |
489 | 490 | Updating package lists | 487 | fips |
486 | 491 | Installing FIPS Updates packages | ||
487 | 492 | FIPS Updates enabled | ||
488 | 493 | A reboot is required to complete install | ||
490 | 494 | """ | 488 | """ |
492 | 495 | When I run `ua status --all` with sudo | 489 | When I verify that running `ua enable fips-updates --assume-yes` `with sudo` exits `0` |
493 | 496 | Then stdout matches regexp: | 490 | Then stdout matches regexp: |
494 | 497 | """ | 491 | """ |
514 | 498 | fips +yes n/a | 492 | One moment, checking your subscription first |
515 | 499 | """ | 493 | Disabling incompatible service: FIPS |
516 | 500 | And stdout matches regexp: | 494 | Updating package lists |
517 | 501 | """ | 495 | Installing FIPS Updates packages |
518 | 502 | fips-updates +yes enabled | 496 | FIPS Updates enabled |
519 | 503 | """ | 497 | A reboot is required to complete install. |
520 | 504 | When I reboot the `<release>` machine | 498 | """ |
521 | 505 | Then I verify that running `apt update` `with sudo` exits `0` | 499 | When I run `ua status --all` with sudo |
522 | 506 | And I verify that `ubuntu-fips` is installed from apt source `<fips-apt-source>` | 500 | Then stdout matches regexp: |
523 | 507 | And I verify that `openssh-server` is installed from apt source `<fips-apt-source>` | 501 | """ |
524 | 508 | And I verify that `openssh-client` is installed from apt source `<fips-apt-source>` | 502 | fips-updates +yes enabled |
525 | 509 | And I verify that `strongswan` is installed from apt source `<fips-apt-source>` | 503 | """ |
526 | 510 | And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>` | 504 | And stdout matches regexp: |
527 | 511 | And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>` | 505 | """ |
528 | 512 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | 506 | fips +yes n/a |
529 | 513 | When I run `uname -r` as non-root | 507 | """ |
530 | 514 | Then stdout matches regexp: | 508 | When I reboot the `<release>` machine |
531 | 515 | """ | 509 | And I run `ua enable livepatch` with sudo |
532 | 516 | fips | 510 | And I run `ua status --all` with sudo |
533 | 511 | Then stdout matches regexp: | ||
534 | 512 | """ | ||
535 | 513 | fips-updates +yes enabled | ||
536 | 514 | """ | ||
537 | 515 | And stdout matches regexp: | ||
538 | 516 | """ | ||
539 | 517 | fips +yes n/a | ||
540 | 518 | """ | ||
541 | 519 | And stdout matches regexp: | ||
542 | 520 | """ | ||
543 | 521 | livepatch +yes enabled | ||
544 | 522 | """ | ||
545 | 523 | When I run `uname -r` as non-root | ||
546 | 524 | Then stdout matches regexp: | ||
547 | 525 | """ | ||
548 | 526 | fips | ||
549 | 527 | """ | ||
550 | 528 | When I run `cat /proc/sys/crypto/fips_enabled` with sudo | ||
551 | 529 | Then I will see the following on stdout: | ||
552 | 530 | """ | ||
553 | 531 | 1 | ||
554 | 517 | """ | 532 | """ |
555 | 518 | When I run `cat /proc/sys/crypto/fips_enabled` with sudo | ||
556 | 519 | Then I will see the following on stdout: | ||
557 | 520 | """ | ||
558 | 521 | 1 | ||
559 | 522 | """ | ||
560 | 523 | 533 | ||
561 | 524 | Examples: ubuntu release | 534 | Examples: ubuntu release |
565 | 525 | | release | fips-apt-source | | 535 | | release | |
566 | 526 | | xenial | https://esm.ubuntu.com/fips-updates/ubuntu xenial-updates/main | | 536 | | xenial | |
567 | 527 | | bionic | https://esm.ubuntu.com/fips-updates/ubuntu bionic-updates/main | | 537 | | bionic | |
568 | 538 | | focal | | ||
569 | 528 | 539 | ||
570 | 529 | @slow | 540 | @slow |
571 | 530 | @series.xenial | 541 | @series.xenial |
572 | diff --git a/features/realtime_kernel.feature b/features/realtime_kernel.feature | |||
573 | 531 | new file mode 100644 | 542 | new file mode 100644 |
574 | index 0000000..a04664c | |||
575 | --- /dev/null | |||
576 | +++ b/features/realtime_kernel.feature | |||
577 | @@ -0,0 +1,128 @@ | |||
578 | 1 | @uses.config.contract_token | ||
579 | 2 | Feature: Enable command behaviour when attached to an UA subscription | ||
580 | 3 | |||
581 | 4 | @series.jammy | ||
582 | 5 | @uses.config.machine_type.lxd.container | ||
583 | 6 | Scenario Outline: Enable Real-Time Kernel service in a container | ||
584 | 7 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
585 | 8 | When I attach `contract_token` with sudo | ||
586 | 9 | Then I verify that running `ua enable realtime-kernel` `as non-root` exits `1` | ||
587 | 10 | And I will see the following on stderr: | ||
588 | 11 | """ | ||
589 | 12 | This command must be run as root (try using sudo). | ||
590 | 13 | """ | ||
591 | 14 | Then I verify that running `ua enable realtime-kernel --beta` `with sudo` exits `1` | ||
592 | 15 | Then I will see the following on stdout: | ||
593 | 16 | """ | ||
594 | 17 | One moment, checking your subscription first | ||
595 | 18 | Cannot install Real-Time Kernel on a container. | ||
596 | 19 | """ | ||
597 | 20 | Examples: ubuntu release | ||
598 | 21 | | release | | ||
599 | 22 | | jammy | | ||
600 | 23 | |||
601 | 24 | @series.lts | ||
602 | 25 | @uses.config.machine_type.lxd.vm | ||
603 | 26 | Scenario Outline: Enable Real-Time Kernel service on unsupported release | ||
604 | 27 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
605 | 28 | When I attach `contract_token` with sudo | ||
606 | 29 | Then I verify that running `ua enable realtime-kernel` `as non-root` exits `1` | ||
607 | 30 | And I will see the following on stderr: | ||
608 | 31 | """ | ||
609 | 32 | This command must be run as root (try using sudo). | ||
610 | 33 | """ | ||
611 | 34 | Then I verify that running `ua enable realtime-kernel --beta` `with sudo` exits `1` | ||
612 | 35 | Then I will see the following on stdout: | ||
613 | 36 | """ | ||
614 | 37 | One moment, checking your subscription first | ||
615 | 38 | Real-Time Kernel is not available for Ubuntu <version> (<full_name>). | ||
616 | 39 | """ | ||
617 | 40 | Examples: ubuntu release | ||
618 | 41 | | release | version | full_name | | ||
619 | 42 | | xenial | 16.04 LTS | Xenial Xerus | | ||
620 | 43 | | bionic | 18.04 LTS | Bionic Beaver | | ||
621 | 44 | | focal | 20.04 LTS | Focal Fossa | | ||
622 | 45 | | jammy | 22.04 | Jammy Jellyfish | | ||
623 | 46 | |||
624 | 47 | @series.jammy | ||
625 | 48 | @uses.config.machine_type.gcp.generic | ||
626 | 49 | Scenario Outline: Enable Real-Time Kernel service | ||
627 | 50 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
628 | 51 | When I create the file `/home/ubuntu/machine-token-overlay.json` with the following: | ||
629 | 52 | """ | ||
630 | 53 | { | ||
631 | 54 | "machineTokenInfo": { | ||
632 | 55 | "contractInfo": { | ||
633 | 56 | "resourceEntitlements": [ | ||
634 | 57 | { | ||
635 | 58 | "type": "realtime-kernel", | ||
636 | 59 | "affordances": { | ||
637 | 60 | "series": ["jammy"] | ||
638 | 61 | } | ||
639 | 62 | } | ||
640 | 63 | ] | ||
641 | 64 | } | ||
642 | 65 | } | ||
643 | 66 | } | ||
644 | 67 | """ | ||
645 | 68 | And I append the following on uaclient config: | ||
646 | 69 | """ | ||
647 | 70 | features: | ||
648 | 71 | machine_token_overlay: "/home/ubuntu/machine-token-overlay.json" | ||
649 | 72 | """ | ||
650 | 73 | When I attach `contract_token` with sudo | ||
651 | 74 | And I run `ua disable livepatch --assume-yes` with sudo | ||
652 | 75 | Then I verify that running `ua enable realtime-kernel` `as non-root` exits `1` | ||
653 | 76 | And I will see the following on stderr: | ||
654 | 77 | """ | ||
655 | 78 | This command must be run as root (try using sudo). | ||
656 | 79 | """ | ||
657 | 80 | Then I verify that running `ua enable realtime-kernel` `with sudo` exits `1` | ||
658 | 81 | And stderr matches regexp: | ||
659 | 82 | """ | ||
660 | 83 | Cannot enable unknown service 'realtime-kernel'. | ||
661 | 84 | """ | ||
662 | 85 | When I run `ua enable realtime-kernel --beta` `with sudo` and stdin `y` | ||
663 | 86 | Then stdout matches regexp: | ||
664 | 87 | """ | ||
665 | 88 | One moment, checking your subscription first | ||
666 | 89 | The real-time kernel is a beta version of the 22.04 Ubuntu kernel with the | ||
667 | 90 | PREEMPT_RT patchset integrated for x86_64 and ARM64. | ||
668 | 91 | |||
669 | 92 | .*You will not be able to revert to your original kernel after enabling real-time..* | ||
670 | 93 | |||
671 | 94 | Do you want to continue\? \[ default = Yes \]: \(Y/n\) Updating package lists | ||
672 | 95 | Installing Real-Time Kernel packages | ||
673 | 96 | Real-Time Kernel enabled | ||
674 | 97 | A reboot is required to complete install. | ||
675 | 98 | """ | ||
676 | 99 | When I run `apt-cache policy linux-realtime` as non-root | ||
677 | 100 | Then stdout does not match regexp: | ||
678 | 101 | """ | ||
679 | 102 | .*Installed: \(none\) | ||
680 | 103 | """ | ||
681 | 104 | And stdout matches regexp: | ||
682 | 105 | """ | ||
683 | 106 | \s* 500 https://esm.ubuntu.com/realtime/ubuntu <release>/main amd64 Packages | ||
684 | 107 | """ | ||
685 | 108 | When I verify that running `ua enable realtime-kernel --beta` `with sudo` exits `1` | ||
686 | 109 | Then stdout matches regexp | ||
687 | 110 | """ | ||
688 | 111 | One moment, checking your subscription first | ||
689 | 112 | Real-Time Kernel is already enabled. | ||
690 | 113 | See: sudo ua status | ||
691 | 114 | """ | ||
692 | 115 | When I reboot the `<release>` machine | ||
693 | 116 | When I run `uname -r` as non-root | ||
694 | 117 | Then stdout matches regexp: | ||
695 | 118 | """ | ||
696 | 119 | realtime | ||
697 | 120 | """ | ||
698 | 121 | When I run `ua disable realtime-kernel` `with sudo` and stdin `y` | ||
699 | 122 | Then stdout matches regexp: | ||
700 | 123 | """ | ||
701 | 124 | This will disable the Real-Time Kernel entitlement but the Real-Time Kernel will remain installed. | ||
702 | 125 | """ | ||
703 | 126 | Examples: ubuntu release | ||
704 | 127 | | release | | ||
705 | 128 | | jammy | | ||
706 | diff --git a/features/staging_commands.feature b/features/staging_commands.feature | |||
707 | index 360b329..23aed73 100644 | |||
708 | --- a/features/staging_commands.feature | |||
709 | +++ b/features/staging_commands.feature | |||
710 | @@ -9,7 +9,7 @@ Feature: Enable command behaviour when attached to an UA staging subscription | |||
711 | 9 | And I run `ua status --all` as non-root | 9 | And I run `ua status --all` as non-root |
712 | 10 | Then stdout matches regexp | 10 | Then stdout matches regexp |
713 | 11 | """ | 11 | """ |
715 | 12 | esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\) | 12 | esm-apps +yes enabled UA Apps: Extended Security Maintenance \(ESM\) |
716 | 13 | """ | 13 | """ |
717 | 14 | And I verify that running `apt update` `with sudo` exits `0` | 14 | And I verify that running `apt update` `with sudo` exits `0` |
718 | 15 | When I run `apt-cache policy` as non-root | 15 | When I run `apt-cache policy` as non-root |
719 | diff --git a/features/ubuntu_pro.feature b/features/ubuntu_pro.feature | |||
720 | index 04ef4fc..0f336ef 100644 | |||
721 | --- a/features/ubuntu_pro.feature | |||
722 | +++ b/features/ubuntu_pro.feature | |||
723 | @@ -25,7 +25,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
724 | 25 | When I run `ua auto-attach` with sudo | 25 | When I run `ua auto-attach` with sudo |
725 | 26 | Then stdout matches regexp: | 26 | Then stdout matches regexp: |
726 | 27 | """ | 27 | """ |
728 | 28 | SERVICE ENTITLED STATUS DESCRIPTION | 28 | SERVICE +ENTITLED STATUS DESCRIPTION |
729 | 29 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 29 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
730 | 30 | """ | 30 | """ |
731 | 31 | Then stdout matches regexp: | 31 | Then stdout matches regexp: |
732 | @@ -96,7 +96,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
733 | 96 | When I run `ua auto-attach` with sudo | 96 | When I run `ua auto-attach` with sudo |
734 | 97 | Then stdout matches regexp: | 97 | Then stdout matches regexp: |
735 | 98 | """ | 98 | """ |
737 | 99 | SERVICE ENTITLED STATUS DESCRIPTION | 99 | SERVICE +ENTITLED STATUS DESCRIPTION |
738 | 100 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 100 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
739 | 101 | """ | 101 | """ |
740 | 102 | Then stdout matches regexp: | 102 | Then stdout matches regexp: |
741 | @@ -167,7 +167,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
742 | 167 | When I run `ua auto-attach` with sudo | 167 | When I run `ua auto-attach` with sudo |
743 | 168 | Then stdout matches regexp: | 168 | Then stdout matches regexp: |
744 | 169 | """ | 169 | """ |
746 | 170 | SERVICE ENTITLED STATUS DESCRIPTION | 170 | SERVICE +ENTITLED STATUS DESCRIPTION |
747 | 171 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 171 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
748 | 172 | """ | 172 | """ |
749 | 173 | Then stdout matches regexp: | 173 | Then stdout matches regexp: |
750 | @@ -228,7 +228,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
751 | 228 | And I run `ua status --wait` as non-root | 228 | And I run `ua status --wait` as non-root |
752 | 229 | Then stdout matches regexp: | 229 | Then stdout matches regexp: |
753 | 230 | """ | 230 | """ |
755 | 231 | SERVICE ENTITLED STATUS DESCRIPTION | 231 | SERVICE +ENTITLED STATUS DESCRIPTION |
756 | 232 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 232 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
757 | 233 | """ | 233 | """ |
758 | 234 | Then stdout matches regexp: | 234 | Then stdout matches regexp: |
759 | @@ -246,7 +246,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
760 | 246 | When I run `ua status --all` as non-root | 246 | When I run `ua status --all` as non-root |
761 | 247 | Then stdout matches regexp: | 247 | Then stdout matches regexp: |
762 | 248 | """ | 248 | """ |
764 | 249 | SERVICE ENTITLED STATUS DESCRIPTION | 249 | SERVICE +ENTITLED STATUS DESCRIPTION |
765 | 250 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 250 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
766 | 251 | """ | 251 | """ |
767 | 252 | Then stdout matches regexp: | 252 | Then stdout matches regexp: |
768 | @@ -362,7 +362,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
769 | 362 | And I run `ua status` as non-root | 362 | And I run `ua status` as non-root |
770 | 363 | Then stdout matches regexp: | 363 | Then stdout matches regexp: |
771 | 364 | """ | 364 | """ |
773 | 365 | SERVICE ENTITLED STATUS DESCRIPTION | 365 | SERVICE +ENTITLED STATUS DESCRIPTION |
774 | 366 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 366 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
775 | 367 | """ | 367 | """ |
776 | 368 | Then stdout matches regexp: | 368 | Then stdout matches regexp: |
777 | @@ -380,7 +380,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
778 | 380 | When I run `ua status --all` as non-root | 380 | When I run `ua status --all` as non-root |
779 | 381 | Then stdout matches regexp: | 381 | Then stdout matches regexp: |
780 | 382 | """ | 382 | """ |
782 | 383 | SERVICE ENTITLED STATUS DESCRIPTION | 383 | SERVICE +ENTITLED STATUS DESCRIPTION |
783 | 384 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 384 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
784 | 385 | """ | 385 | """ |
785 | 386 | Then stdout matches regexp: | 386 | Then stdout matches regexp: |
786 | @@ -496,7 +496,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
787 | 496 | And I run `ua status` as non-root | 496 | And I run `ua status` as non-root |
788 | 497 | Then stdout matches regexp: | 497 | Then stdout matches regexp: |
789 | 498 | """ | 498 | """ |
791 | 499 | SERVICE ENTITLED STATUS DESCRIPTION | 499 | SERVICE +ENTITLED STATUS DESCRIPTION |
792 | 500 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 500 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
793 | 501 | """ | 501 | """ |
794 | 502 | Then stdout matches regexp: | 502 | Then stdout matches regexp: |
795 | @@ -514,7 +514,7 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO image | |||
796 | 514 | When I run `ua status --all` as non-root | 514 | When I run `ua status --all` as non-root |
797 | 515 | Then stdout matches regexp: | 515 | Then stdout matches regexp: |
798 | 516 | """ | 516 | """ |
800 | 517 | SERVICE ENTITLED STATUS DESCRIPTION | 517 | SERVICE +ENTITLED STATUS DESCRIPTION |
801 | 518 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages | 518 | cc-eal +yes +<cc-eal-s> +Common Criteria EAL2 Provisioning Packages |
802 | 519 | """ | 519 | """ |
803 | 520 | Then stdout matches regexp: | 520 | Then stdout matches regexp: |
804 | diff --git a/features/ubuntu_pro_fips.feature b/features/ubuntu_pro_fips.feature | |||
805 | index 7a18b03..1e83ee3 100644 | |||
806 | --- a/features/ubuntu_pro_fips.feature | |||
807 | +++ b/features/ubuntu_pro_fips.feature | |||
808 | @@ -26,12 +26,6 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
809 | 26 | """ | 26 | """ |
810 | 27 | And I verify that running `apt update` `with sudo` exits `0` | 27 | And I verify that running `apt update` `with sudo` exits `0` |
811 | 28 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` | 28 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` |
812 | 29 | And I verify that `openssh-server` is installed from apt source `<fips-apt-source>` | ||
813 | 30 | And I verify that `openssh-client` is installed from apt source `<fips-apt-source>` | ||
814 | 31 | And I verify that `strongswan` is installed from apt source `<fips-apt-source>` | ||
815 | 32 | And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>` | ||
816 | 33 | And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>` | ||
817 | 34 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | ||
818 | 35 | When I run `uname -r` as non-root | 29 | When I run `uname -r` as non-root |
819 | 36 | Then stdout matches regexp: | 30 | Then stdout matches regexp: |
820 | 37 | """ | 31 | """ |
821 | @@ -79,6 +73,10 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
822 | 79 | """ | 73 | """ |
823 | 80 | https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages | 74 | https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages |
824 | 81 | """ | 75 | """ |
825 | 76 | And apt-cache policy for the following url has permission `1001` | ||
826 | 77 | """ | ||
827 | 78 | <fips-apt-source> amd64 Packages | ||
828 | 79 | """ | ||
829 | 82 | And I verify that running `apt update` `with sudo` exits `0` | 80 | And I verify that running `apt update` `with sudo` exits `0` |
830 | 83 | When I run `apt install -y <infra-pkg>/<release>-infra-security` with sudo, retrying exit [100] | 81 | When I run `apt install -y <infra-pkg>/<release>-infra-security` with sudo, retrying exit [100] |
831 | 84 | And I run `apt-cache policy <infra-pkg>` as non-root | 82 | And I run `apt-cache policy <infra-pkg>` as non-root |
832 | @@ -99,15 +97,48 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
833 | 99 | \s*\*\*\* .* 500 | 97 | \s*\*\*\* .* 500 |
834 | 100 | \s*500 https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages | 98 | \s*500 https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages |
835 | 101 | """ | 99 | """ |
836 | 100 | When I run `ua enable fips-updates --assume-yes` with sudo | ||
837 | 101 | Then I will see the following on stdout: | ||
838 | 102 | """ | ||
839 | 103 | One moment, checking your subscription first | ||
840 | 104 | Disabling incompatible service: FIPS | ||
841 | 105 | Updating package lists | ||
842 | 106 | Installing FIPS Updates packages | ||
843 | 107 | FIPS Updates enabled | ||
844 | 108 | A reboot is required to complete install. | ||
845 | 109 | """ | ||
846 | 110 | When I run `ua status` with sudo | ||
847 | 111 | Then stdout matches regexp: | ||
848 | 112 | """ | ||
849 | 113 | fips +yes +n/a +NIST-certified core packages | ||
850 | 114 | fips-updates +yes +enabled +NIST-certified core packages with priority security updates | ||
851 | 115 | """ | ||
852 | 116 | When I reboot the `<release>` machine | ||
853 | 117 | And I run `uname -r` as non-root | ||
854 | 118 | Then stdout matches regexp: | ||
855 | 119 | """ | ||
856 | 120 | <fips-kernel-version> | ||
857 | 121 | """ | ||
858 | 122 | When I run `apt-cache policy ubuntu-azure-fips` as non-root | ||
859 | 123 | Then stdout does not match regexp: | ||
860 | 124 | """ | ||
861 | 125 | .*Installed: \(none\) | ||
862 | 126 | """ | ||
863 | 127 | When I run `cat /proc/sys/crypto/fips_enabled` with sudo | ||
864 | 128 | Then I will see the following on stdout: | ||
865 | 129 | """ | ||
866 | 130 | 1 | ||
867 | 131 | """ | ||
868 | 102 | 132 | ||
869 | 103 | Examples: ubuntu release | 133 | Examples: ubuntu release |
870 | 104 | | release | infra-pkg | apps-pkg | fips-apt-source | fips-kernel-version | | 134 | | release | infra-pkg | apps-pkg | fips-apt-source | fips-kernel-version | |
871 | 105 | | xenial | libkrad0 | jq | https://esm.ubuntu.com/fips/ubuntu xenial/main | fips | | 135 | | xenial | libkrad0 | jq | https://esm.ubuntu.com/fips/ubuntu xenial/main | fips | |
872 | 106 | | bionic | libkrad0 | bundler | https://esm.ubuntu.com/fips/ubuntu bionic/main | azure-fips | | 136 | | bionic | libkrad0 | bundler | https://esm.ubuntu.com/fips/ubuntu bionic/main | azure-fips | |
873 | 137 | | focal | hello | 389-ds | https://esm.ubuntu.com/fips/ubuntu focal/main | azure-fips | | ||
874 | 107 | 138 | ||
878 | 108 | @series.lts | 139 | @series.focal |
879 | 109 | @uses.config.machine_type.aws.pro.fips | 140 | @uses.config.machine_type.azure.pro.fips |
880 | 110 | Scenario Outline: Check fips is enabled correctly on Ubuntu pro fips AWS machine | 141 | Scenario Outline: Check fips packages are correctly installed on Azure Focal machine |
881 | 111 | Given a `<release>` machine with ubuntu-advantage-tools installed | 142 | Given a `<release>` machine with ubuntu-advantage-tools installed |
882 | 112 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | 143 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: |
883 | 113 | """ | 144 | """ |
884 | @@ -115,6 +146,44 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
885 | 115 | data_dir: /var/lib/ubuntu-advantage | 146 | data_dir: /var/lib/ubuntu-advantage |
886 | 116 | log_level: debug | 147 | log_level: debug |
887 | 117 | log_file: /var/log/ubuntu-advantage.log | 148 | log_file: /var/log/ubuntu-advantage.log |
888 | 149 | features: | ||
889 | 150 | allow_xenial_fips_on_cloud: true | ||
890 | 151 | """ | ||
891 | 152 | And I run `ua auto-attach` with sudo | ||
892 | 153 | And I run `ua status --wait` as non-root | ||
893 | 154 | And I run `ua status` as non-root | ||
894 | 155 | Then stdout matches regexp: | ||
895 | 156 | """ | ||
896 | 157 | esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\) | ||
897 | 158 | esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\) | ||
898 | 159 | fips +yes +enabled +NIST-certified core packages | ||
899 | 160 | fips-updates +yes +disabled +NIST-certified core packages with priority security updates | ||
900 | 161 | livepatch +yes +n/a +Canonical Livepatch service | ||
901 | 162 | """ | ||
902 | 163 | And I verify that running `apt update` `with sudo` exits `0` | ||
903 | 164 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` | ||
904 | 165 | And I verify that `openssh-server` is installed from apt source `<fips-apt-source>` | ||
905 | 166 | And I verify that `openssh-client` is installed from apt source `<fips-apt-source>` | ||
906 | 167 | And I verify that `strongswan` is installed from apt source `<fips-apt-source>` | ||
907 | 168 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | ||
908 | 169 | |||
909 | 170 | Examples: ubuntu release | ||
910 | 171 | | release | fips-apt-source | | ||
911 | 172 | | focal | https://esm.ubuntu.com/fips/ubuntu focal/main | | ||
912 | 173 | |||
913 | 174 | @series.xenial | ||
914 | 175 | @series.bionic | ||
915 | 176 | @uses.config.machine_type.azure.pro.fips | ||
916 | 177 | Scenario Outline: Check fips packages are correctly installed on Azure Bionic & Xenial machines | ||
917 | 178 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
918 | 179 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | ||
919 | 180 | """ | ||
920 | 181 | contract_url: 'https://contracts.canonical.com' | ||
921 | 182 | data_dir: /var/lib/ubuntu-advantage | ||
922 | 183 | log_level: debug | ||
923 | 184 | log_file: /var/log/ubuntu-advantage.log | ||
924 | 185 | features: | ||
925 | 186 | allow_xenial_fips_on_cloud: true | ||
926 | 118 | """ | 187 | """ |
927 | 119 | And I run `ua auto-attach` with sudo | 188 | And I run `ua auto-attach` with sudo |
928 | 120 | And I run `ua status --wait` as non-root | 189 | And I run `ua status --wait` as non-root |
929 | @@ -135,6 +204,36 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
930 | 135 | And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>` | 204 | And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>` |
931 | 136 | And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>` | 205 | And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>` |
932 | 137 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | 206 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` |
933 | 207 | |||
934 | 208 | Examples: ubuntu release | ||
935 | 209 | | release | fips-apt-source | | ||
936 | 210 | | xenial | https://esm.ubuntu.com/fips/ubuntu xenial/main | | ||
937 | 211 | | bionic | https://esm.ubuntu.com/fips/ubuntu bionic/main | | ||
938 | 212 | |||
939 | 213 | @series.lts | ||
940 | 214 | @uses.config.machine_type.aws.pro.fips | ||
941 | 215 | Scenario Outline: Check fips is enabled correctly on Ubuntu pro fips AWS machine | ||
942 | 216 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
943 | 217 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | ||
944 | 218 | """ | ||
945 | 219 | contract_url: 'https://contracts.canonical.com' | ||
946 | 220 | data_dir: /var/lib/ubuntu-advantage | ||
947 | 221 | log_level: debug | ||
948 | 222 | log_file: /var/log/ubuntu-advantage.log | ||
949 | 223 | """ | ||
950 | 224 | And I run `ua auto-attach` with sudo | ||
951 | 225 | And I run `ua status --wait` as non-root | ||
952 | 226 | And I run `ua status` as non-root | ||
953 | 227 | Then stdout matches regexp: | ||
954 | 228 | """ | ||
955 | 229 | esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\) | ||
956 | 230 | esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\) | ||
957 | 231 | fips +yes +enabled +NIST-certified core packages | ||
958 | 232 | fips-updates +yes +disabled +NIST-certified core packages with priority security updates | ||
959 | 233 | livepatch +yes +n/a +Canonical Livepatch service | ||
960 | 234 | """ | ||
961 | 235 | And I verify that running `apt update` `with sudo` exits `0` | ||
962 | 236 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` | ||
963 | 138 | When I run `uname -r` as non-root | 237 | When I run `uname -r` as non-root |
964 | 139 | Then stdout matches regexp: | 238 | Then stdout matches regexp: |
965 | 140 | """ | 239 | """ |
966 | @@ -182,6 +281,10 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
967 | 182 | """ | 281 | """ |
968 | 183 | https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages | 282 | https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages |
969 | 184 | """ | 283 | """ |
970 | 284 | And apt-cache policy for the following url has permission `1001` | ||
971 | 285 | """ | ||
972 | 286 | <fips-apt-source> amd64 Packages | ||
973 | 287 | """ | ||
974 | 185 | And I verify that running `apt update` `with sudo` exits `0` | 288 | And I verify that running `apt update` `with sudo` exits `0` |
975 | 186 | When I run `apt install -y <infra-pkg>/<release>-infra-security` with sudo, retrying exit [100] | 289 | When I run `apt install -y <infra-pkg>/<release>-infra-security` with sudo, retrying exit [100] |
976 | 187 | And I run `apt-cache policy <infra-pkg>` as non-root | 290 | And I run `apt-cache policy <infra-pkg>` as non-root |
977 | @@ -202,9 +305,167 @@ Feature: Command behaviour when auto-attached in an ubuntu PRO fips image | |||
978 | 202 | \s*\*\*\* .* 500 | 305 | \s*\*\*\* .* 500 |
979 | 203 | \s*500 https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages | 306 | \s*500 https://esm.ubuntu.com/apps/ubuntu <release>-apps-security/main amd64 Packages |
980 | 204 | """ | 307 | """ |
981 | 308 | When I run `ua enable fips-updates --assume-yes` with sudo | ||
982 | 309 | Then I will see the following on stdout: | ||
983 | 310 | """ | ||
984 | 311 | One moment, checking your subscription first | ||
985 | 312 | Disabling incompatible service: FIPS | ||
986 | 313 | Updating package lists | ||
987 | 314 | Installing FIPS Updates packages | ||
988 | 315 | FIPS Updates enabled | ||
989 | 316 | A reboot is required to complete install. | ||
990 | 317 | """ | ||
991 | 318 | When I run `ua status` with sudo | ||
992 | 319 | Then stdout matches regexp: | ||
993 | 320 | """ | ||
994 | 321 | fips +yes +n/a +NIST-certified core packages | ||
995 | 322 | fips-updates +yes +enabled +NIST-certified core packages with priority security updates | ||
996 | 323 | """ | ||
997 | 324 | When I reboot the `<release>` machine | ||
998 | 325 | And I run `uname -r` as non-root | ||
999 | 326 | Then stdout matches regexp: | ||
1000 | 327 | """ | ||
1001 | 328 | <fips-kernel-version> | ||
1002 | 329 | """ | ||
1003 | 330 | When I run `apt-cache policy ubuntu-aws-fips` as non-root | ||
1004 | 331 | Then stdout does not match regexp: | ||
1005 | 332 | """ | ||
1006 | 333 | .*Installed: \(none\) | ||
1007 | 334 | """ | ||
1008 | 335 | When I run `cat /proc/sys/crypto/fips_enabled` with sudo | ||
1009 | 336 | Then I will see the following on stdout: | ||
1010 | 337 | """ | ||
1011 | 338 | 1 | ||
1012 | 339 | """ | ||
1013 | 205 | 340 | ||
1014 | 206 | Examples: ubuntu release | 341 | Examples: ubuntu release |
1015 | 207 | | release | infra-pkg | apps-pkg | fips-apt-source | fips-kernel-version | | 342 | | release | infra-pkg | apps-pkg | fips-apt-source | fips-kernel-version | |
1016 | 208 | | xenial | libkrad0 | jq | https://esm.ubuntu.com/fips/ubuntu xenial/main | fips | | 343 | | xenial | libkrad0 | jq | https://esm.ubuntu.com/fips/ubuntu xenial/main | fips | |
1017 | 209 | | bionic | libkrad0 | bundler | https://esm.ubuntu.com/fips/ubuntu bionic/main | aws-fips | | 344 | | bionic | libkrad0 | bundler | https://esm.ubuntu.com/fips/ubuntu bionic/main | aws-fips | |
1018 | 345 | | focal | hello | 389-ds | https://esm.ubuntu.com/fips/ubuntu focal/main | aws-fips | | ||
1019 | 210 | 346 | ||
1020 | 347 | @series.focal | ||
1021 | 348 | @uses.config.machine_type.aws.pro.fips | ||
1022 | 349 | Scenario Outline: Check fips packages are correctly installed on AWS Focal machine | ||
1023 | 350 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
1024 | 351 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | ||
1025 | 352 | """ | ||
1026 | 353 | contract_url: 'https://contracts.canonical.com' | ||
1027 | 354 | data_dir: /var/lib/ubuntu-advantage | ||
1028 | 355 | log_level: debug | ||
1029 | 356 | log_file: /var/log/ubuntu-advantage.log | ||
1030 | 357 | features: | ||
1031 | 358 | allow_xenial_fips_on_cloud: true | ||
1032 | 359 | """ | ||
1033 | 360 | And I run `ua auto-attach` with sudo | ||
1034 | 361 | And I run `ua status --wait` as non-root | ||
1035 | 362 | And I run `ua status` as non-root | ||
1036 | 363 | Then stdout matches regexp: | ||
1037 | 364 | """ | ||
1038 | 365 | esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\) | ||
1039 | 366 | esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\) | ||
1040 | 367 | fips +yes +enabled +NIST-certified core packages | ||
1041 | 368 | fips-updates +yes +disabled +NIST-certified core packages with priority security updates | ||
1042 | 369 | livepatch +yes +n/a +Canonical Livepatch service | ||
1043 | 370 | """ | ||
1044 | 371 | And I verify that running `apt update` `with sudo` exits `0` | ||
1045 | 372 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` | ||
1046 | 373 | And I verify that `openssh-server` is installed from apt source `<fips-apt-source>` | ||
1047 | 374 | And I verify that `openssh-client` is installed from apt source `<fips-apt-source>` | ||
1048 | 375 | And I verify that `strongswan` is installed from apt source `<fips-apt-source>` | ||
1049 | 376 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | ||
1050 | 377 | |||
1051 | 378 | Examples: ubuntu release | ||
1052 | 379 | | release | fips-apt-source | | ||
1053 | 380 | | focal | https://esm.ubuntu.com/fips/ubuntu focal/main | | ||
1054 | 381 | |||
1055 | 382 | @series.xenial | ||
1056 | 383 | @series.bionic | ||
1057 | 384 | @uses.config.machine_type.aws.pro.fips | ||
1058 | 385 | Scenario Outline: Check fips packages are correctly installed on AWS Bionic & Xenial machines | ||
1059 | 386 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
1060 | 387 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | ||
1061 | 388 | """ | ||
1062 | 389 | contract_url: 'https://contracts.canonical.com' | ||
1063 | 390 | data_dir: /var/lib/ubuntu-advantage | ||
1064 | 391 | log_level: debug | ||
1065 | 392 | log_file: /var/log/ubuntu-advantage.log | ||
1066 | 393 | features: | ||
1067 | 394 | allow_xenial_fips_on_cloud: true | ||
1068 | 395 | """ | ||
1069 | 396 | And I run `ua auto-attach` with sudo | ||
1070 | 397 | And I run `ua status --wait` as non-root | ||
1071 | 398 | And I run `ua status` as non-root | ||
1072 | 399 | Then stdout matches regexp: | ||
1073 | 400 | """ | ||
1074 | 401 | esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\) | ||
1075 | 402 | esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\) | ||
1076 | 403 | fips +yes +enabled +NIST-certified core packages | ||
1077 | 404 | fips-updates +yes +disabled +NIST-certified core packages with priority security updates | ||
1078 | 405 | livepatch +yes +n/a +Canonical Livepatch service | ||
1079 | 406 | """ | ||
1080 | 407 | And I verify that running `apt update` `with sudo` exits `0` | ||
1081 | 408 | And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1` | ||
1082 | 409 | And I verify that `openssh-server` is installed from apt source `<fips-apt-source>` | ||
1083 | 410 | And I verify that `openssh-client` is installed from apt source `<fips-apt-source>` | ||
1084 | 411 | And I verify that `strongswan` is installed from apt source `<fips-apt-source>` | ||
1085 | 412 | And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>` | ||
1086 | 413 | And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>` | ||
1087 | 414 | And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>` | ||
1088 | 415 | |||
1089 | 416 | Examples: ubuntu release | ||
1090 | 417 | | release | fips-apt-source | | ||
1091 | 418 | | xenial | https://esm.ubuntu.com/fips/ubuntu xenial/main | | ||
1092 | 419 | | bionic | https://esm.ubuntu.com/fips/ubuntu bionic/main | | ||
1093 | 420 | |||
1094 | 421 | @series.focal | ||
1095 | 422 | @uses.config.machine_type.azure.pro.fips | ||
1096 | 423 | @uses.config.machine_type.aws.pro.fips | ||
1097 | 424 | Scenario Outline: Check fips-updates can be enable in a focal PRO FIPS machine | ||
1098 | 425 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
1099 | 426 | When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following: | ||
1100 | 427 | """ | ||
1101 | 428 | contract_url: 'https://contracts.canonical.com' | ||
1102 | 429 | data_dir: /var/lib/ubuntu-advantage | ||
1103 | 430 | log_level: debug | ||
1104 | 431 | log_file: /var/log/ubuntu-advantage.log | ||
1105 | 432 | """ | ||
1106 | 433 | And I run `ua auto-attach` with sudo | ||
1107 | 434 | And I run `ua status --wait` as non-root | ||
1108 | 435 | And I run `ua status` as non-root | ||
1109 | 436 | Then stdout matches regexp: | ||
1110 | 437 | """ | ||
1111 | 438 | fips +yes +enabled +NIST-certified core packages | ||
1112 | 439 | fips-updates +yes +disabled +NIST-certified core packages with priority security updates | ||
1113 | 440 | """ | ||
1114 | 441 | When I run `ua enable fips-updates --assume-yes` with sudo | ||
1115 | 442 | Then stdout matches regexp: | ||
1116 | 443 | """ | ||
1117 | 444 | One moment, checking your subscription first | ||
1118 | 445 | Disabling incompatible service: FIPS | ||
1119 | 446 | Updating package lists | ||
1120 | 447 | Installing FIPS Updates packages | ||
1121 | 448 | FIPS Updates enabled | ||
1122 | 449 | A reboot is required to complete install. | ||
1123 | 450 | """ | ||
1124 | 451 | When I run `ua status` with sudo | ||
1125 | 452 | Then stdout matches regexp: | ||
1126 | 453 | """ | ||
1127 | 454 | fips +yes +n/a +NIST-certified core packages | ||
1128 | 455 | fips-updates +yes +enabled +NIST-certified core packages with priority security updates | ||
1129 | 456 | """ | ||
1130 | 457 | When I reboot the `<release>` machine | ||
1131 | 458 | And I run `uname -r` as non-root | ||
1132 | 459 | Then stdout matches regexp: | ||
1133 | 460 | """ | ||
1134 | 461 | fips | ||
1135 | 462 | """ | ||
1136 | 463 | When I run `cat /proc/sys/crypto/fips_enabled` with sudo | ||
1137 | 464 | Then I will see the following on stdout: | ||
1138 | 465 | """ | ||
1139 | 466 | 1 | ||
1140 | 467 | """ | ||
1141 | 468 | |||
1142 | 469 | Examples: ubuntu release | ||
1143 | 470 | | release | | ||
1144 | 471 | | focal | | ||
1145 | diff --git a/features/ubuntu_upgrade.feature b/features/ubuntu_upgrade.feature | |||
1146 | index 4cf3407..0ffa683 100644 | |||
1147 | --- a/features/ubuntu_upgrade.feature | |||
1148 | +++ b/features/ubuntu_upgrade.feature | |||
1149 | @@ -17,7 +17,6 @@ Feature: Upgrade between releases when uaclient is attached | |||
1150 | 17 | [Sources] | 17 | [Sources] |
1151 | 18 | AllowThirdParty=yes | 18 | AllowThirdParty=yes |
1152 | 19 | """ | 19 | """ |
1153 | 20 | And I run `sed -i 's/Prompt=lts/Prompt=normal/' /etc/update-manager/release-upgrades` with sudo | ||
1154 | 21 | And I run `do-release-upgrade <devel_release> --frontend DistUpgradeViewNonInteractive` `with sudo` and stdin `y\n` | 20 | And I run `do-release-upgrade <devel_release> --frontend DistUpgradeViewNonInteractive` `with sudo` and stdin `y\n` |
1155 | 22 | And I reboot the `<release>` machine | 21 | And I reboot the `<release>` machine |
1156 | 23 | And I run `lsb_release -cs` as non-root | 22 | And I run `lsb_release -cs` as non-root |
1157 | @@ -42,7 +41,7 @@ Feature: Upgrade between releases when uaclient is attached | |||
1158 | 42 | 41 | ||
1159 | 43 | Examples: ubuntu release | 42 | Examples: ubuntu release |
1160 | 44 | | release | next_release | devel_release | | 43 | | release | next_release | devel_release | |
1162 | 45 | | focal | impish | | | 44 | | focal | jammy | --devel-release | |
1163 | 46 | | impish | jammy | --devel-release | | 45 | | impish | jammy | --devel-release | |
1164 | 47 | 46 | ||
1165 | 48 | @slow | 47 | @slow |
1166 | diff --git a/features/unattached_status.feature b/features/unattached_status.feature | |||
1167 | index 08538a2..eccaf60 100644 | |||
1168 | --- a/features/unattached_status.feature | |||
1169 | +++ b/features/unattached_status.feature | |||
1170 | @@ -47,13 +47,13 @@ Feature: Unattached status | |||
1171 | 47 | When I run `ua status` as non-root | 47 | When I run `ua status` as non-root |
1172 | 48 | Then stdout matches regexp: | 48 | Then stdout matches regexp: |
1173 | 49 | """ | 49 | """ |
1176 | 50 | SERVICE AVAILABLE DESCRIPTION | 50 | SERVICE +AVAILABLE DESCRIPTION |
1177 | 51 | cc-eal <cc-eal> +Common Criteria EAL2 Provisioning Packages | 51 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
1178 | 52 | ?<cis>( +<cis-available> +Security compliance and audit tools)? | 52 | ?<cis>( +<cis-available> +Security compliance and audit tools)? |
1183 | 53 | ?esm-infra <esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) | 53 | ?esm-infra +<esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) |
1184 | 54 | fips <fips> +NIST-certified core packages | 54 | fips +<fips> +NIST-certified core packages |
1185 | 55 | fips-updates <fips> +NIST-certified core packages with priority security updates | 55 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
1186 | 56 | livepatch <livepatch> +Canonical Livepatch service | 56 | livepatch +<livepatch> +Canonical Livepatch service |
1187 | 57 | ?<usg>( +<cis-available> +Security compliance and audit tools)? | 57 | ?<usg>( +<cis-available> +Security compliance and audit tools)? |
1188 | 58 | 58 | ||
1189 | 59 | This machine is not attached to a UA subscription. | 59 | This machine is not attached to a UA subscription. |
1190 | @@ -62,16 +62,17 @@ Feature: Unattached status | |||
1191 | 62 | When I run `ua status --all` as non-root | 62 | When I run `ua status --all` as non-root |
1192 | 63 | Then stdout matches regexp: | 63 | Then stdout matches regexp: |
1193 | 64 | """ | 64 | """ |
1196 | 65 | SERVICE AVAILABLE DESCRIPTION | 65 | SERVICE +AVAILABLE DESCRIPTION |
1197 | 66 | cc-eal <cc-eal> +Common Criteria EAL2 Provisioning Packages | 66 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
1198 | 67 | ?<cis>( +<cis-available> +Security compliance and audit tools)? | 67 | ?<cis>( +<cis-available> +Security compliance and audit tools)? |
1206 | 68 | ?esm-apps <esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) | 68 | ?esm-apps +<esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) |
1207 | 69 | esm-infra <esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) | 69 | esm-infra +<esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) |
1208 | 70 | fips <fips> +NIST-certified core packages | 70 | fips +<fips> +NIST-certified core packages |
1209 | 71 | fips-updates <fips> +NIST-certified core packages with priority security updates | 71 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
1210 | 72 | livepatch <livepatch> +Canonical Livepatch service | 72 | livepatch +<livepatch> +Canonical Livepatch service |
1211 | 73 | ros <ros> +Security Updates for the Robot Operating System | 73 | realtime-kernel +<realtime-kernel> +Beta-version Ubuntu Kernel with PREEMPT_RT patches |
1212 | 74 | ros-updates <ros> +All Updates for the Robot Operating System | 74 | ros +<ros> +Security Updates for the Robot Operating System |
1213 | 75 | ros-updates +<ros> +All Updates for the Robot Operating System | ||
1214 | 75 | ?<usg>( +<cis-available> +Security compliance and audit tools)? | 76 | ?<usg>( +<cis-available> +Security compliance and audit tools)? |
1215 | 76 | 77 | ||
1216 | 77 | This machine is not attached to a UA subscription. | 78 | This machine is not attached to a UA subscription. |
1217 | @@ -80,13 +81,13 @@ Feature: Unattached status | |||
1218 | 80 | When I run `ua status` with sudo | 81 | When I run `ua status` with sudo |
1219 | 81 | Then stdout matches regexp: | 82 | Then stdout matches regexp: |
1220 | 82 | """ | 83 | """ |
1223 | 83 | SERVICE AVAILABLE DESCRIPTION | 84 | SERVICE +AVAILABLE DESCRIPTION |
1224 | 84 | cc-eal <cc-eal> +Common Criteria EAL2 Provisioning Packages | 85 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
1225 | 85 | ?<cis>( +<cis-available> +Security compliance and audit tools)? | 86 | ?<cis>( +<cis-available> +Security compliance and audit tools)? |
1230 | 86 | ?esm-infra <esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) | 87 | ?esm-infra +<esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) |
1231 | 87 | fips <fips> +NIST-certified core packages | 88 | fips +<fips> +NIST-certified core packages |
1232 | 88 | fips-updates <fips> +NIST-certified core packages with priority security updates | 89 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
1233 | 89 | livepatch <livepatch> +Canonical Livepatch service | 90 | livepatch +<livepatch> +Canonical Livepatch service |
1234 | 90 | ?<usg>( +<cis-available> +Security compliance and audit tools)? | 91 | ?<usg>( +<cis-available> +Security compliance and audit tools)? |
1235 | 91 | 92 | ||
1236 | 92 | This machine is not attached to a UA subscription. | 93 | This machine is not attached to a UA subscription. |
1237 | @@ -95,16 +96,17 @@ Feature: Unattached status | |||
1238 | 95 | When I run `ua status --all` with sudo | 96 | When I run `ua status --all` with sudo |
1239 | 96 | Then stdout matches regexp: | 97 | Then stdout matches regexp: |
1240 | 97 | """ | 98 | """ |
1243 | 98 | SERVICE AVAILABLE DESCRIPTION | 99 | SERVICE +AVAILABLE DESCRIPTION |
1244 | 99 | cc-eal <cc-eal> +Common Criteria EAL2 Provisioning Packages | 100 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
1245 | 100 | ?<cis>( +<cis-available> +Security compliance and audit tools)? | 101 | ?<cis>( +<cis-available> +Security compliance and audit tools)? |
1253 | 101 | ?esm-apps <esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) | 102 | ?esm-apps +<esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) |
1254 | 102 | esm-infra <esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) | 103 | esm-infra +<esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) |
1255 | 103 | fips <fips> +NIST-certified core packages | 104 | fips +<fips> +NIST-certified core packages |
1256 | 104 | fips-updates <fips> +NIST-certified core packages with priority security updates | 105 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
1257 | 105 | livepatch <livepatch> +Canonical Livepatch service | 106 | livepatch +<livepatch> +Canonical Livepatch service |
1258 | 106 | ros <ros> +Security Updates for the Robot Operating System | 107 | realtime-kernel +<realtime-kernel> +Beta-version Ubuntu Kernel with PREEMPT_RT patches |
1259 | 107 | ros-updates <ros> +All Updates for the Robot Operating System | 108 | ros +<ros> +Security Updates for the Robot Operating System |
1260 | 109 | ros-updates +<ros> +All Updates for the Robot Operating System | ||
1261 | 108 | ?<usg>( +<cis-available> +Security compliance and audit tools)? | 110 | ?<usg>( +<cis-available> +Security compliance and audit tools)? |
1262 | 109 | 111 | ||
1263 | 110 | This machine is not attached to a UA subscription. | 112 | This machine is not attached to a UA subscription. |
1264 | @@ -118,16 +120,17 @@ Feature: Unattached status | |||
1265 | 118 | And I run `ua status` as non-root | 120 | And I run `ua status` as non-root |
1266 | 119 | Then stdout matches regexp: | 121 | Then stdout matches regexp: |
1267 | 120 | """ | 122 | """ |
1270 | 121 | SERVICE AVAILABLE DESCRIPTION | 123 | SERVICE +AVAILABLE DESCRIPTION |
1271 | 122 | cc-eal <cc-eal> +Common Criteria EAL2 Provisioning Packages | 124 | cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages |
1272 | 123 | ?<cis>( +<cis-available> +Security compliance and audit tools)? | 125 | ?<cis>( +<cis-available> +Security compliance and audit tools)? |
1280 | 124 | ?esm-apps <esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) | 126 | ?esm-apps +<esm-apps> +UA Apps: Extended Security Maintenance \(ESM\) |
1281 | 125 | esm-infra <esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) | 127 | esm-infra +<esm-infra> +UA Infra: Extended Security Maintenance \(ESM\) |
1282 | 126 | fips <fips> +NIST-certified core packages | 128 | fips +<fips> +NIST-certified core packages |
1283 | 127 | fips-updates <fips> +NIST-certified core packages with priority security updates | 129 | fips-updates +<fips> +NIST-certified core packages with priority security updates |
1284 | 128 | livepatch <livepatch> +Canonical Livepatch service | 130 | livepatch +<livepatch> +Canonical Livepatch service |
1285 | 129 | ros <ros> +Security Updates for the Robot Operating System | 131 | realtime-kernel +<realtime-kernel> +Beta-version Ubuntu Kernel with PREEMPT_RT patches |
1286 | 130 | ros-updates <ros> +All Updates for the Robot Operating System | 132 | ros +<ros> +Security Updates for the Robot Operating System |
1287 | 133 | ros-updates +<ros> +All Updates for the Robot Operating System | ||
1288 | 131 | ?<usg>( +<cis-available> +Security compliance and audit tools)? | 134 | ?<usg>( +<cis-available> +Security compliance and audit tools)? |
1289 | 132 | 135 | ||
1290 | 133 | This machine is not attached to a UA subscription. | 136 | This machine is not attached to a UA subscription. |
1291 | @@ -135,44 +138,44 @@ Feature: Unattached status | |||
1292 | 135 | """ | 138 | """ |
1293 | 136 | 139 | ||
1294 | 137 | Examples: ubuntu release | 140 | Examples: ubuntu release |
1301 | 138 | | release | esm-apps | cc-eal | cis | cis-available | fips | esm-infra | ros | livepatch | usg | | 141 | | release | esm-apps | cc-eal | cis | cis-available | fips | esm-infra | ros | livepatch | usg | realtime-kernel | |
1302 | 139 | | xenial | yes | yes | cis | yes | yes | yes | yes | yes | | | 142 | | xenial | yes | yes | cis | yes | yes | yes | yes | yes | | no | |
1303 | 140 | | bionic | yes | yes | cis | yes | yes | yes | yes | yes | | | 143 | | bionic | yes | yes | cis | yes | yes | yes | yes | yes | | no | |
1304 | 141 | | focal | yes | no | | yes | yes | yes | no | yes | usg | | 144 | | focal | yes | no | | yes | yes | yes | no | yes | usg | no | |
1305 | 142 | | impish | no | no | cis | no | no | no | no | no | | | 145 | | impish | no | no | cis | no | no | no | no | no | | no | |
1306 | 143 | | jammy | no | no | cis | no | no | no | no | no | | | 146 | | jammy | no | no | cis | no | no | no | no | no | | yes | |
1307 | 144 | 147 | ||
1308 | 145 | @series.all | 148 | @series.all |
1309 | 146 | @uses.config.machine_type.lxd.container | 149 | @uses.config.machine_type.lxd.container |
1310 | 147 | @uses.config.contract_token | 150 | @uses.config.contract_token |
1311 | 148 | @uses.config.contract_token_staging_expired | ||
1312 | 149 | Scenario Outline: Simulate status in a ubuntu machine | 151 | Scenario Outline: Simulate status in a ubuntu machine |
1313 | 150 | Given a `<release>` machine with ubuntu-advantage-tools installed | 152 | Given a `<release>` machine with ubuntu-advantage-tools installed |
1314 | 151 | When I do a preflight check for `contract_token` without the all flag | 153 | When I do a preflight check for `contract_token` without the all flag |
1315 | 152 | Then stdout matches regexp: | 154 | Then stdout matches regexp: |
1316 | 153 | """ | 155 | """ |
1319 | 154 | SERVICE AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION | 156 | SERVICE +AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION |
1320 | 155 | cc-eal <cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages | 157 | cc-eal +<cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages |
1321 | 156 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? | 158 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1326 | 157 | ?esm-infra <esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) | 159 | ?esm-infra +<esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) |
1327 | 158 | fips <fips> +yes +no +NIST-certified core packages | 160 | fips +<fips> +yes +no +NIST-certified core packages |
1328 | 159 | fips-updates <fips> +yes +no +NIST-certified core packages with priority security updates | 161 | fips-updates +<fips> +yes +no +NIST-certified core packages with priority security updates |
1329 | 160 | livepatch <livepatch> +yes +yes +Canonical Livepatch service | 162 | livepatch +<livepatch> +yes +yes +Canonical Livepatch service |
1330 | 161 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? | 163 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1331 | 162 | """ | 164 | """ |
1332 | 163 | When I do a preflight check for `contract_token` with the all flag | 165 | When I do a preflight check for `contract_token` with the all flag |
1333 | 164 | Then stdout matches regexp: | 166 | Then stdout matches regexp: |
1334 | 165 | """ | 167 | """ |
1337 | 166 | SERVICE AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION | 168 | SERVICE +AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION |
1338 | 167 | cc-eal <cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages | 169 | cc-eal +<cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages |
1339 | 168 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? | 170 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1347 | 169 | ?esm-apps <esm-apps> +yes +yes +UA Apps: Extended Security Maintenance \(ESM\) | 171 | ?esm-apps +<esm-apps> +yes +yes +UA Apps: Extended Security Maintenance \(ESM\) |
1348 | 170 | esm-infra <esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) | 172 | esm-infra +<esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) |
1349 | 171 | fips <fips> +yes +no +NIST-certified core packages | 173 | fips +<fips> +yes +no +NIST-certified core packages |
1350 | 172 | fips-updates <fips> +yes +no +NIST-certified core packages with priority security updates | 174 | fips-updates +<fips> +yes +no +NIST-certified core packages with priority security updates |
1351 | 173 | livepatch <livepatch> +yes +yes +Canonical Livepatch service | 175 | livepatch +<livepatch> +yes +yes +Canonical Livepatch service |
1352 | 174 | ros <ros> +yes +no +Security Updates for the Robot Operating System | 176 | realtime-kernel +<realtime-kernel> +yes +no +Beta-version Ubuntu Kernel with PREEMPT_RT patches |
1353 | 175 | ros-updates <ros> +yes +no +All Updates for the Robot Operating System | 177 | ros +<ros> +yes +no +Security Updates for the Robot Operating System |
1354 | 178 | ros-updates +<ros> +yes +no +All Updates for the Robot Operating System | ||
1355 | 176 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? | 179 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1356 | 177 | """ | 180 | """ |
1357 | 178 | When I do a preflight check for `contract_token` formatted as json | 181 | When I do a preflight check for `contract_token` formatted as json |
1358 | @@ -199,6 +202,20 @@ Feature: Unattached status | |||
1359 | 199 | services: [] | 202 | services: [] |
1360 | 200 | warnings: [] | 203 | warnings: [] |
1361 | 201 | """ | 204 | """ |
1362 | 205 | Examples: ubuntu release | ||
1363 | 206 | | release | esm-apps | cc-eal | cis | cis-available | fips | esm-infra | ros | livepatch | usg | realtime-kernel | | ||
1364 | 207 | | xenial | yes | yes | cis | yes | yes | yes | yes | yes | | no | | ||
1365 | 208 | | bionic | yes | yes | cis | yes | yes | yes | yes | yes | | no | | ||
1366 | 209 | | focal | yes | no | | yes | yes | yes | no | yes | usg | no | | ||
1367 | 210 | | impish | no | no | cis | no | no | no | no | no | | no | | ||
1368 | 211 | | jammy | no | no | cis | no | no | no | no | no | | yes | | ||
1369 | 212 | |||
1370 | 213 | |||
1371 | 214 | @series.all | ||
1372 | 215 | @uses.config.machine_type.lxd.container | ||
1373 | 216 | @uses.config.contract_token_staging_expired | ||
1374 | 217 | Scenario Outline: Simulate status with expired token in a ubuntu machine | ||
1375 | 218 | Given a `<release>` machine with ubuntu-advantage-tools installed | ||
1376 | 202 | When I run `sed -i 's/contracts.can/contracts.staging.can/' /etc/ubuntu-advantage/uaclient.conf` with sudo | 219 | When I run `sed -i 's/contracts.can/contracts.staging.can/' /etc/ubuntu-advantage/uaclient.conf` with sudo |
1377 | 203 | And I verify that a preflight check for `contract_token_staging_expired` formatted as json exits 1 | 220 | And I verify that a preflight check for `contract_token_staging_expired` formatted as json exits 1 |
1378 | 204 | Then stdout is a json matching the `ua_status` schema | 221 | Then stdout is a json matching the `ua_status` schema |
1379 | @@ -223,13 +240,13 @@ Feature: Unattached status | |||
1380 | 223 | This token is not valid. | 240 | This token is not valid. |
1381 | 224 | Contract \".*\" expired on .* | 241 | Contract \".*\" expired on .* |
1382 | 225 | 242 | ||
1385 | 226 | SERVICE AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION | 243 | SERVICE +AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION |
1386 | 227 | cc-eal <cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages | 244 | cc-eal +<cc-eal> +yes +no +Common Criteria EAL2 Provisioning Packages |
1387 | 228 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? | 245 | ?<cis>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1392 | 229 | ?esm-infra <esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) | 246 | ?esm-infra +<esm-infra> +yes +yes +UA Infra: Extended Security Maintenance \(ESM\) |
1393 | 230 | fips <fips> +yes +no +NIST-certified core packages | 247 | fips +<fips> +yes +no +NIST-certified core packages |
1394 | 231 | fips-updates <fips> +yes +no +NIST-certified core packages with priority security updates | 248 | fips-updates +<fips> +yes +no +NIST-certified core packages with priority security updates |
1395 | 232 | livepatch <livepatch> +yes +yes +Canonical Livepatch service | 249 | livepatch +<livepatch> +yes +yes +Canonical Livepatch service |
1396 | 233 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? | 250 | ?<usg>( +<cis-available> +yes +no +Security compliance and audit tools)? |
1397 | 234 | """ | 251 | """ |
1398 | 235 | 252 | ||
1399 | @@ -239,4 +256,4 @@ Feature: Unattached status | |||
1400 | 239 | | bionic | yes | yes | cis | yes | yes | yes | yes | yes | | | 256 | | bionic | yes | yes | cis | yes | yes | yes | yes | yes | | |
1401 | 240 | | focal | yes | no | | yes | yes | yes | no | yes | usg | | 257 | | focal | yes | no | | yes | yes | yes | no | yes | usg | |
1402 | 241 | | impish | no | no | cis | no | no | no | no | no | | | 258 | | impish | no | no | cis | no | no | no | no | no | | |
1404 | 242 | | jammy | no | no | cis | no | no | no | no | no | | | 259 | | jammy | no | no | cis | no | no | yes | no | no | | |
1405 | diff --git a/help_data.yaml b/help_data.yaml | |||
1406 | index d5d6486..c301573 100644 | |||
1407 | --- a/help_data.yaml | |||
1408 | +++ b/help_data.yaml | |||
1409 | @@ -61,6 +61,16 @@ livepatch: | |||
1410 | 61 | more about Ubuntu Kernel Livepatch service at | 61 | more about Ubuntu Kernel Livepatch service at |
1411 | 62 | https://ubuntu.com/security/livepatch | 62 | https://ubuntu.com/security/livepatch |
1412 | 63 | 63 | ||
1413 | 64 | realtime-kernel: | ||
1414 | 65 | help: | | ||
1415 | 66 | The real-time kernel is a beta version of the 22.04 Ubuntu kernel with the | ||
1416 | 67 | PREEMPT_RT patchset integrated for x86_64 and ARM64. It services extreme | ||
1417 | 68 | latency-dependent use cases and provides deterministic response times to | ||
1418 | 69 | service events. By meeting stringent preemption specifications, the | ||
1419 | 70 | real-time kernel is suitable for telco applications and embedded devices | ||
1420 | 71 | in industrial automation and robotics. To enroll in the beta program, visit | ||
1421 | 72 | https://ubuntu.com/realtime-kernel | ||
1422 | 73 | |||
1423 | 64 | ros: | 74 | ros: |
1424 | 65 | help: | | 75 | help: | |
1425 | 66 | ros provides access to a private PPA which includes security-related | 76 | ros provides access to a private PPA which includes security-related |
1426 | diff --git a/keyrings/ubuntu-advantage-realtime-kernel.gpg b/keyrings/ubuntu-advantage-realtime-kernel.gpg | |||
1427 | 67 | new file mode 100644 | 77 | new file mode 100644 |
1428 | index 0000000..edf9246 | |||
1429 | 68 | Binary files /dev/null and b/keyrings/ubuntu-advantage-realtime-kernel.gpg differ | 78 | Binary files /dev/null and b/keyrings/ubuntu-advantage-realtime-kernel.gpg differ |
1430 | diff --git a/lib/upgrade_lts_contract.py b/lib/upgrade_lts_contract.py | |||
1431 | index 2da9d58..ca7af18 100755 | |||
1432 | --- a/lib/upgrade_lts_contract.py | |||
1433 | +++ b/lib/upgrade_lts_contract.py | |||
1434 | @@ -34,21 +34,27 @@ version_to_codename = { | |||
1435 | 34 | "16.04": "xenial", | 34 | "16.04": "xenial", |
1436 | 35 | "18.04": "bionic", | 35 | "18.04": "bionic", |
1437 | 36 | "20.04": "focal", | 36 | "20.04": "focal", |
1439 | 37 | "20.10": "groovy", | 37 | "21.10": "impish", |
1440 | 38 | "22.04": "jammy", | ||
1441 | 38 | } | 39 | } |
1442 | 39 | 40 | ||
1443 | 40 | current_codename_to_past_codename = { | 41 | current_codename_to_past_codename = { |
1444 | 41 | "xenial": "trusty", | 42 | "xenial": "trusty", |
1445 | 42 | "bionic": "xenial", | 43 | "bionic": "xenial", |
1446 | 43 | "focal": "bionic", | 44 | "focal": "bionic", |
1448 | 44 | "groovy": "focal", | 45 | "impish": "focal", |
1449 | 46 | # We are considering the past release for Jammy to be Focal | ||
1450 | 47 | # because we don't have any services available on Impish. | ||
1451 | 48 | # Therefore, it is safer for us to try to process contract deltas | ||
1452 | 49 | # using Focal | ||
1453 | 50 | "jammy": "focal", | ||
1454 | 45 | } | 51 | } |
1455 | 46 | 52 | ||
1456 | 47 | 53 | ||
1457 | 48 | def process_contract_delta_after_apt_lock() -> None: | 54 | def process_contract_delta_after_apt_lock() -> None: |
1458 | 49 | logging.debug("Check whether to upgrade-lts-contract") | 55 | logging.debug("Check whether to upgrade-lts-contract") |
1459 | 50 | if not UAConfig().is_attached: | 56 | if not UAConfig().is_attached: |
1461 | 51 | logging.debug("Skiping upgrade-lts-contract. Machine is unattached") | 57 | logging.debug("Skipping upgrade-lts-contract. Machine is unattached") |
1462 | 52 | return | 58 | return |
1463 | 53 | out, _err = subp(["lsof", "/var/lib/apt/lists/lock"], rcs=[0, 1]) | 59 | out, _err = subp(["lsof", "/var/lib/apt/lists/lock"], rcs=[0, 1]) |
1464 | 54 | msg = "Starting upgrade-lts-contract." | 60 | msg = "Starting upgrade-lts-contract." |
1465 | @@ -58,7 +64,15 @@ def process_contract_delta_after_apt_lock() -> None: | |||
1466 | 58 | logging.debug(msg) | 64 | logging.debug(msg) |
1467 | 59 | 65 | ||
1468 | 60 | current_version = parse_os_release()["VERSION_ID"] | 66 | current_version = parse_os_release()["VERSION_ID"] |
1470 | 61 | current_release = version_to_codename[current_version] | 67 | current_release = version_to_codename.get(current_version) |
1471 | 68 | |||
1472 | 69 | if current_release is None: | ||
1473 | 70 | msg = "Unable to get release codename for version: {}".format( | ||
1474 | 71 | current_version | ||
1475 | 72 | ) | ||
1476 | 73 | print(msg) | ||
1477 | 74 | logging.warning(msg) | ||
1478 | 75 | sys.exit(1) | ||
1479 | 62 | 76 | ||
1480 | 63 | if current_release == "trusty": | 77 | if current_release == "trusty": |
1481 | 64 | msg = "Unable to execute upgrade-lts-contract.py on trusty" | 78 | msg = "Unable to execute upgrade-lts-contract.py on trusty" |
1482 | @@ -66,7 +80,13 @@ def process_contract_delta_after_apt_lock() -> None: | |||
1483 | 66 | logging.warning(msg) | 80 | logging.warning(msg) |
1484 | 67 | sys.exit(1) | 81 | sys.exit(1) |
1485 | 68 | 82 | ||
1487 | 69 | past_release = current_codename_to_past_codename[current_release] | 83 | past_release = current_codename_to_past_codename.get(current_release) |
1488 | 84 | if past_release is None: | ||
1489 | 85 | msg = "Could not find past release for: {}".format(current_release) | ||
1490 | 86 | print(msg) | ||
1491 | 87 | logging.warning(msg) | ||
1492 | 88 | sys.exit(1) | ||
1493 | 89 | |||
1494 | 70 | past_entitlements = UAConfig(series=past_release).entitlements | 90 | past_entitlements = UAConfig(series=past_release).entitlements |
1495 | 71 | new_entitlements = UAConfig(series=current_release).entitlements | 91 | new_entitlements = UAConfig(series=current_release).entitlements |
1496 | 72 | 92 | ||
1497 | diff --git a/tools/refresh-keyrings.sh b/tools/refresh-keyrings.sh | |||
1498 | index f4c1db1..850d8fb 100755 | |||
1499 | --- a/tools/refresh-keyrings.sh | |||
1500 | +++ b/tools/refresh-keyrings.sh | |||
1501 | @@ -28,6 +28,7 @@ ESM_APPS_KEY_ID="E8A443CE358113D187BEE0E6AB01A101DB53907B" | |||
1502 | 28 | FIPS_KEY_ID="E23341B2A1467EDBF07057D6C1997C40EDE22758" | 28 | FIPS_KEY_ID="E23341B2A1467EDBF07057D6C1997C40EDE22758" |
1503 | 29 | CIS_KEY_ID="81CF06E53F2C513A" | 29 | CIS_KEY_ID="81CF06E53F2C513A" |
1504 | 30 | ROS_KEY_ID="853874C8B0F10896" | 30 | ROS_KEY_ID="853874C8B0F10896" |
1505 | 31 | REALTIME_KEY_ID="F6D1E58F4DCD9F91" | ||
1506 | 31 | 32 | ||
1507 | 32 | generate_keyrings() { | 33 | generate_keyrings() { |
1508 | 33 | KEYRING_DIR="$1" | 34 | KEYRING_DIR="$1" |
1509 | @@ -50,6 +51,8 @@ generate_keyrings() { | |||
1510 | 50 | service_name="cis";; | 51 | service_name="cis";; |
1511 | 51 | $ROS_KEY_ID) | 52 | $ROS_KEY_ID) |
1512 | 52 | service_name="ros";; | 53 | service_name="ros";; |
1513 | 54 | $REALTIME_KEY_ID) | ||
1514 | 55 | service_name="realtime-kernel";; | ||
1515 | 53 | *) | 56 | *) |
1516 | 54 | echo "Unhandled key id provided: " $key | 57 | echo "Unhandled key id provided: " $key |
1517 | 55 | exit 1; | 58 | exit 1; |
1518 | @@ -70,6 +73,6 @@ generate_keyrings() { | |||
1519 | 70 | } | 73 | } |
1520 | 71 | 74 | ||
1521 | 72 | 75 | ||
1523 | 73 | generate_keyrings $TARGET_DIR $EAL_KEY_ID $ESM_INFRA_KEY_ID $ESM_APPS_KEY_ID $FIPS_KEY_ID $CIS_KEY_ID $ROS_KEY_ID | 76 | generate_keyrings $TARGET_DIR $EAL_KEY_ID $ESM_INFRA_KEY_ID $ESM_APPS_KEY_ID $FIPS_KEY_ID $CIS_KEY_ID $ROS_KEY_ID $REALTIME_KEY_ID |
1524 | 74 | 77 | ||
1525 | 75 | rm -rf $tmp_dir | 78 | rm -rf $tmp_dir |
1526 | diff --git a/tox.ini b/tox.ini | |||
1527 | index 45962e0..dffbfa8 100644 | |||
1528 | --- a/tox.ini | |||
1529 | +++ b/tox.ini | |||
1530 | @@ -60,6 +60,7 @@ commands = | |||
1531 | 60 | behave-vm-16.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.xenial,series.all,series.lts" --tags="~upgrade" | 60 | behave-vm-16.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.xenial,series.all,series.lts" --tags="~upgrade" |
1532 | 61 | behave-vm-18.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.bionic,series.all,series.lts" --tags="~upgrade" | 61 | behave-vm-18.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.bionic,series.all,series.lts" --tags="~upgrade" |
1533 | 62 | behave-vm-20.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.focal,series.all,series.lts" --tags="~upgrade" | 62 | behave-vm-20.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.focal,series.all,series.lts" --tags="~upgrade" |
1534 | 63 | behave-vm-22.04: behave -v {posargs} --tags="uses.config.machine_type.lxd.vm" --tags="series.jammy,series.all,series.lts" --tags="~upgrade" | ||
1535 | 63 | behave-upgrade-16.04: behave -v {posargs} --tags="upgrade" --tags="series.xenial,series.all" | 64 | behave-upgrade-16.04: behave -v {posargs} --tags="upgrade" --tags="series.xenial,series.all" |
1536 | 64 | behave-upgrade-18.04: behave -v {posargs} --tags="upgrade" --tags="series.bionic,series.all" | 65 | behave-upgrade-18.04: behave -v {posargs} --tags="upgrade" --tags="series.bionic,series.all" |
1537 | 65 | behave-upgrade-20.04: behave -v {posargs} --tags="upgrade" --tags="series.focal,series.all" | 66 | behave-upgrade-20.04: behave -v {posargs} --tags="upgrade" --tags="series.focal,series.all" |
1538 | @@ -72,6 +73,7 @@ commands = | |||
1539 | 72 | behave-awspro-20.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro" --tags="series.focal,series.lts,series.all" | 73 | behave-awspro-20.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro" --tags="series.focal,series.lts,series.all" |
1540 | 73 | behave-awspro-fips-16.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro.fips" --tags="series.xenial,series.lts,series.all" | 74 | behave-awspro-fips-16.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro.fips" --tags="series.xenial,series.lts,series.all" |
1541 | 74 | behave-awspro-fips-18.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro.fips" --tags="series.bionic,series.lts,series.all" | 75 | behave-awspro-fips-18.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro.fips" --tags="series.bionic,series.lts,series.all" |
1542 | 76 | behave-awspro-fips-20.04: behave -v {posargs} --tags="uses.config.machine_type.aws.pro.fips" --tags="series.focal,series.lts,series.all" | ||
1543 | 75 | behave-azuregeneric-16.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.xenial,series.lts,series.all" --tags="~upgrade" | 77 | behave-azuregeneric-16.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.xenial,series.lts,series.all" --tags="~upgrade" |
1544 | 76 | behave-azuregeneric-18.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.bionic,series.lts,series.all" --tags="~upgrade" | 78 | behave-azuregeneric-18.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.bionic,series.lts,series.all" --tags="~upgrade" |
1545 | 77 | behave-azuregeneric-20.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.focal,series.lts,series.all" --tags="~upgrade" | 79 | behave-azuregeneric-20.04: behave -v {posargs} --tags="uses.config.machine_type.azure.generic" --tags="series.focal,series.lts,series.all" --tags="~upgrade" |
1546 | @@ -80,6 +82,7 @@ commands = | |||
1547 | 80 | behave-azurepro-20.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro" --tags="series.focal,series.lts,series.all" | 82 | behave-azurepro-20.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro" --tags="series.focal,series.lts,series.all" |
1548 | 81 | behave-azurepro-fips-16.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro.fips" --tags="series.xenial,series.lts,series.all" | 83 | behave-azurepro-fips-16.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro.fips" --tags="series.xenial,series.lts,series.all" |
1549 | 82 | behave-azurepro-fips-18.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro.fips" --tags="series.bionic,series.lts,series.all" | 84 | behave-azurepro-fips-18.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro.fips" --tags="series.bionic,series.lts,series.all" |
1550 | 85 | behave-azurepro-fips-20.04: behave -v {posargs} --tags="uses.config.machine_type.azure.pro.fips" --tags="series.focal,series.lts,series.all" | ||
1551 | 83 | behave-gcpgeneric-16.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.xenial,series.lts,series.all" --tags="~upgrade" | 86 | behave-gcpgeneric-16.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.xenial,series.lts,series.all" --tags="~upgrade" |
1552 | 84 | behave-gcpgeneric-18.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.bionic,series.lts,series.all" --tags="~upgrade" | 87 | behave-gcpgeneric-18.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.bionic,series.lts,series.all" --tags="~upgrade" |
1553 | 85 | behave-gcpgeneric-20.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.focal,series.lts,series.all" --tags="~upgrade" | 88 | behave-gcpgeneric-20.04: behave -v {posargs} --tags="uses.config.machine_type.gcp.generic" --tags="series.focal,series.lts,series.all" --tags="~upgrade" |
1554 | diff --git a/uaclient/clouds/identity.py b/uaclient/clouds/identity.py | |||
1555 | index 7542d35..a39fef0 100644 | |||
1556 | --- a/uaclient/clouds/identity.py | |||
1557 | +++ b/uaclient/clouds/identity.py | |||
1558 | @@ -1,5 +1,6 @@ | |||
1559 | 1 | import logging | 1 | import logging |
1560 | 2 | from enum import Enum | 2 | from enum import Enum |
1561 | 3 | from functools import lru_cache | ||
1562 | 3 | from typing import Dict, Optional, Tuple, Type # noqa: F401 | 4 | from typing import Dict, Optional, Tuple, Type # noqa: F401 |
1563 | 4 | 5 | ||
1564 | 5 | from uaclient import clouds, exceptions, util | 6 | from uaclient import clouds, exceptions, util |
1565 | @@ -36,6 +37,7 @@ def get_instance_id() -> Optional[str]: | |||
1566 | 36 | return None | 37 | return None |
1567 | 37 | 38 | ||
1568 | 38 | 39 | ||
1569 | 40 | @lru_cache(maxsize=None) | ||
1570 | 39 | @apply_config_settings_override("cloud_type") | 41 | @apply_config_settings_override("cloud_type") |
1571 | 40 | def get_cloud_type() -> Tuple[Optional[str], Optional[NoCloudTypeReason]]: | 42 | def get_cloud_type() -> Tuple[Optional[str], Optional[NoCloudTypeReason]]: |
1572 | 41 | if util.which("cloud-id"): | 43 | if util.which("cloud-id"): |
1573 | diff --git a/uaclient/clouds/tests/test_identity.py b/uaclient/clouds/tests/test_identity.py | |||
1574 | index a21efee..ae2e4a6 100644 | |||
1575 | --- a/uaclient/clouds/tests/test_identity.py | |||
1576 | +++ b/uaclient/clouds/tests/test_identity.py | |||
1577 | @@ -40,7 +40,7 @@ class TestGetCloudType: | |||
1578 | 40 | @mock.patch(M_PATH + "util.subp", return_value=("somecloud\n", "")) | 40 | @mock.patch(M_PATH + "util.subp", return_value=("somecloud\n", "")) |
1579 | 41 | def test_use_cloud_id_when_available(self, m_subp, m_which): | 41 | def test_use_cloud_id_when_available(self, m_subp, m_which): |
1580 | 42 | """Use cloud-id utility to discover cloud type.""" | 42 | """Use cloud-id utility to discover cloud type.""" |
1582 | 43 | assert ("somecloud", None) == get_cloud_type() | 43 | assert ("somecloud", None) == get_cloud_type.__wrapped__() |
1583 | 44 | assert [mock.call("cloud-id")] == m_which.call_args_list | 44 | assert [mock.call("cloud-id")] == m_which.call_args_list |
1584 | 45 | 45 | ||
1585 | 46 | @mock.patch(M_PATH + "util.which", return_value="/usr/bin/cloud-id") | 46 | @mock.patch(M_PATH + "util.which", return_value="/usr/bin/cloud-id") |
1586 | @@ -49,7 +49,10 @@ class TestGetCloudType: | |||
1587 | 49 | side_effect=exceptions.ProcessExecutionError("cloud-id"), | 49 | side_effect=exceptions.ProcessExecutionError("cloud-id"), |
1588 | 50 | ) | 50 | ) |
1589 | 51 | def test_error_when_cloud_id_fails(self, m_subp, m_which): | 51 | def test_error_when_cloud_id_fails(self, m_subp, m_which): |
1591 | 52 | assert (None, NoCloudTypeReason.CLOUD_ID_ERROR) == get_cloud_type() | 52 | assert ( |
1592 | 53 | None, | ||
1593 | 54 | NoCloudTypeReason.CLOUD_ID_ERROR, | ||
1594 | 55 | ) == get_cloud_type.__wrapped__() | ||
1595 | 53 | 56 | ||
1596 | 54 | @pytest.mark.parametrize( | 57 | @pytest.mark.parametrize( |
1597 | 55 | "settings_overrides", | 58 | "settings_overrides", |
1598 | @@ -80,7 +83,7 @@ class TestGetCloudType: | |||
1599 | 80 | expected_value = "test" | 83 | expected_value = "test" |
1600 | 81 | 84 | ||
1601 | 82 | m_load_file.return_value = settings_overrides | 85 | m_load_file.return_value = settings_overrides |
1603 | 83 | assert get_cloud_type() == (expected_value, None) | 86 | assert get_cloud_type.__wrapped__() == (expected_value, None) |
1604 | 84 | 87 | ||
1605 | 85 | 88 | ||
1606 | 86 | @mock.patch(M_PATH + "get_cloud_type") | 89 | @mock.patch(M_PATH + "get_cloud_type") |
1607 | diff --git a/uaclient/config.py b/uaclient/config.py | |||
1608 | index 079708e..74bb06b 100644 | |||
1609 | --- a/uaclient/config.py | |||
1610 | +++ b/uaclient/config.py | |||
1611 | @@ -357,7 +357,7 @@ class UAConfig: | |||
1612 | 357 | entitlement_cfg["resourceToken"] = tokens_by_name[ | 357 | entitlement_cfg["resourceToken"] = tokens_by_name[ |
1613 | 358 | entitlement_name | 358 | entitlement_name |
1614 | 359 | ] | 359 | ] |
1616 | 360 | util.apply_series_overrides(entitlement_cfg, self.series) | 360 | util.apply_contract_overrides(entitlement_cfg, self.series) |
1617 | 361 | self._entitlements[entitlement_name] = entitlement_cfg | 361 | self._entitlements[entitlement_name] = entitlement_cfg |
1618 | 362 | return self._entitlements | 362 | return self._entitlements |
1619 | 363 | 363 | ||
1620 | diff --git a/uaclient/contract.py b/uaclient/contract.py | |||
1621 | index 47d0b5a..b47b484 100644 | |||
1622 | --- a/uaclient/contract.py | |||
1623 | +++ b/uaclient/contract.py | |||
1624 | @@ -347,7 +347,7 @@ def process_entitlement_delta( | |||
1625 | 347 | from uaclient.entitlements import entitlement_factory | 347 | from uaclient.entitlements import entitlement_factory |
1626 | 348 | 348 | ||
1627 | 349 | if series_overrides: | 349 | if series_overrides: |
1629 | 350 | util.apply_series_overrides(new_access) | 350 | util.apply_contract_overrides(new_access) |
1630 | 351 | 351 | ||
1631 | 352 | deltas = util.get_dict_deltas(orig_access, new_access) | 352 | deltas = util.get_dict_deltas(orig_access, new_access) |
1632 | 353 | ret = False | 353 | ret = False |
1633 | diff --git a/uaclient/entitlements/__init__.py b/uaclient/entitlements/__init__.py | |||
1634 | index 1c6a156..8f7356d 100644 | |||
1635 | --- a/uaclient/entitlements/__init__.py | |||
1636 | +++ b/uaclient/entitlements/__init__.py | |||
1637 | @@ -7,6 +7,7 @@ from uaclient.entitlements.cc import CommonCriteriaEntitlement | |||
1638 | 7 | from uaclient.entitlements.cis import CISEntitlement | 7 | from uaclient.entitlements.cis import CISEntitlement |
1639 | 8 | from uaclient.entitlements.esm import ESMAppsEntitlement, ESMInfraEntitlement | 8 | from uaclient.entitlements.esm import ESMAppsEntitlement, ESMInfraEntitlement |
1640 | 9 | from uaclient.entitlements.livepatch import LivepatchEntitlement | 9 | from uaclient.entitlements.livepatch import LivepatchEntitlement |
1641 | 10 | from uaclient.entitlements.realtime import RealtimeKernelEntitlement | ||
1642 | 10 | from uaclient.entitlements.ros import ROSEntitlement, ROSUpdatesEntitlement | 11 | from uaclient.entitlements.ros import ROSEntitlement, ROSUpdatesEntitlement |
1643 | 11 | from uaclient.exceptions import EntitlementNotFoundError | 12 | from uaclient.exceptions import EntitlementNotFoundError |
1644 | 12 | from uaclient.util import is_config_value_true | 13 | from uaclient.util import is_config_value_true |
1645 | @@ -19,6 +20,7 @@ ENTITLEMENT_CLASSES = [ | |||
1646 | 19 | fips.FIPSEntitlement, | 20 | fips.FIPSEntitlement, |
1647 | 20 | fips.FIPSUpdatesEntitlement, | 21 | fips.FIPSUpdatesEntitlement, |
1648 | 21 | LivepatchEntitlement, | 22 | LivepatchEntitlement, |
1649 | 23 | RealtimeKernelEntitlement, | ||
1650 | 22 | ROSEntitlement, | 24 | ROSEntitlement, |
1651 | 23 | ROSUpdatesEntitlement, | 25 | ROSUpdatesEntitlement, |
1652 | 24 | ] # type: List[Type[UAEntitlement]] | 26 | ] # type: List[Type[UAEntitlement]] |
1653 | diff --git a/uaclient/entitlements/base.py b/uaclient/entitlements/base.py | |||
1654 | index bf1b926..4606b5c 100644 | |||
1655 | --- a/uaclient/entitlements/base.py | |||
1656 | +++ b/uaclient/entitlements/base.py | |||
1657 | @@ -209,7 +209,8 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1658 | 209 | populated CanEnableFailure reason. This may expand to | 209 | populated CanEnableFailure reason. This may expand to |
1659 | 210 | include other types of reasons in the future. | 210 | include other types of reasons in the future. |
1660 | 211 | """ | 211 | """ |
1662 | 212 | msg_ops = self.messaging.get("pre_enable", []) | 212 | |
1663 | 213 | msg_ops = self.messaging.get("pre_can_enable", []) | ||
1664 | 213 | if not util.handle_message_operations(msg_ops): | 214 | if not util.handle_message_operations(msg_ops): |
1665 | 214 | return False, None | 215 | return False, None |
1666 | 215 | 216 | ||
1667 | @@ -237,6 +238,10 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1668 | 237 | # every other reason means we can't continue | 238 | # every other reason means we can't continue |
1669 | 238 | return False, fail | 239 | return False, fail |
1670 | 239 | 240 | ||
1671 | 241 | msg_ops = self.messaging.get("pre_enable", []) | ||
1672 | 242 | if not util.handle_message_operations(msg_ops): | ||
1673 | 243 | return False, None | ||
1674 | 244 | |||
1675 | 240 | ret = self._perform_enable(silent=silent) | 245 | ret = self._perform_enable(silent=silent) |
1676 | 241 | if not ret: | 246 | if not ret: |
1677 | 242 | return False, None | 247 | return False, None |
1678 | @@ -449,7 +454,7 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1679 | 449 | path_to_value="features.block_disable_on_enable", | 454 | path_to_value="features.block_disable_on_enable", |
1680 | 450 | ) | 455 | ) |
1681 | 451 | for service in self.blocking_incompatible_services(): | 456 | for service in self.blocking_incompatible_services(): |
1683 | 452 | ent = service.entitlement(self.cfg) | 457 | ent = service.entitlement(self.cfg, assume_yes=True) |
1684 | 453 | 458 | ||
1685 | 454 | user_msg = messages.INCOMPATIBLE_SERVICE.format( | 459 | user_msg = messages.INCOMPATIBLE_SERVICE.format( |
1686 | 455 | service_being_enabled=self.title, | 460 | service_being_enabled=self.title, |
1687 | @@ -474,7 +479,7 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1688 | 474 | ) | 479 | ) |
1689 | 475 | event.info(disable_msg) | 480 | event.info(disable_msg) |
1690 | 476 | 481 | ||
1692 | 477 | ret = ent.disable() | 482 | ret = ent.disable(silent=True) |
1693 | 478 | if not ret: | 483 | if not ret: |
1694 | 479 | return ret, None | 484 | return ret, None |
1695 | 480 | 485 | ||
1696 | @@ -664,7 +669,7 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1697 | 664 | event.info(info_msg=msg.msg, file_type=sys.stderr) | 669 | event.info(info_msg=msg.msg, file_type=sys.stderr) |
1698 | 665 | return False, msg | 670 | return False, msg |
1699 | 666 | 671 | ||
1701 | 667 | ent = ent_cls(self.cfg) | 672 | ent = ent_cls(cfg=self.cfg, assume_yes=True) |
1702 | 668 | 673 | ||
1703 | 669 | is_service_enabled = ( | 674 | is_service_enabled = ( |
1704 | 670 | ent.application_status()[0] == status.ApplicationStatus.ENABLED | 675 | ent.application_status()[0] == status.ApplicationStatus.ENABLED |
1705 | @@ -710,13 +715,16 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1706 | 710 | """Check if system needs to be rebooted.""" | 715 | """Check if system needs to be rebooted.""" |
1707 | 711 | return util.should_reboot() | 716 | return util.should_reboot() |
1708 | 712 | 717 | ||
1710 | 713 | def _check_for_reboot_msg(self, operation: str) -> None: | 718 | def _check_for_reboot_msg( |
1711 | 719 | self, operation: str, silent: bool = False | ||
1712 | 720 | ) -> None: | ||
1713 | 714 | """Check if user should be alerted that a reboot must be performed. | 721 | """Check if user should be alerted that a reboot must be performed. |
1714 | 715 | 722 | ||
1715 | 716 | @param operation: The operation being executed. | 723 | @param operation: The operation being executed. |
1716 | 724 | @param silent: Boolean set True to silence print/log of messages | ||
1717 | 717 | """ | 725 | """ |
1720 | 718 | if self._check_for_reboot(): | 726 | if self._check_for_reboot() and not silent: |
1721 | 719 | print( | 727 | event.info( |
1722 | 720 | messages.ENABLE_REBOOT_REQUIRED_TMPL.format( | 728 | messages.ENABLE_REBOOT_REQUIRED_TMPL.format( |
1723 | 721 | operation=operation | 729 | operation=operation |
1724 | 722 | ) | 730 | ) |
1725 | @@ -763,7 +771,9 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1726 | 763 | if not util.handle_message_operations(msg_ops): | 771 | if not util.handle_message_operations(msg_ops): |
1727 | 764 | return False, None | 772 | return False, None |
1728 | 765 | 773 | ||
1730 | 766 | self._check_for_reboot_msg(operation="disable operation") | 774 | self._check_for_reboot_msg( |
1731 | 775 | operation="disable operation", silent=silent | ||
1732 | 776 | ) | ||
1733 | 767 | return True, None | 777 | return True, None |
1734 | 768 | 778 | ||
1735 | 769 | def contract_status(self) -> ContractStatus: | 779 | def contract_status(self) -> ContractStatus: |
1736 | @@ -836,7 +846,7 @@ class UAEntitlement(metaclass=abc.ABCMeta): | |||
1737 | 836 | transition_to_unentitled = bool(delta_entitlement == util.DROPPED_KEY) | 846 | transition_to_unentitled = bool(delta_entitlement == util.DROPPED_KEY) |
1738 | 837 | if not transition_to_unentitled: | 847 | if not transition_to_unentitled: |
1739 | 838 | if delta_entitlement: | 848 | if delta_entitlement: |
1741 | 839 | util.apply_series_overrides(deltas) | 849 | util.apply_contract_overrides(deltas) |
1742 | 840 | delta_entitlement = deltas["entitlement"] | 850 | delta_entitlement = deltas["entitlement"] |
1743 | 841 | if orig_access and "entitled" in delta_entitlement: | 851 | if orig_access and "entitled" in delta_entitlement: |
1744 | 842 | transition_to_unentitled = delta_entitlement["entitled"] in ( | 852 | transition_to_unentitled = delta_entitlement["entitled"] in ( |
1745 | diff --git a/uaclient/entitlements/cis.py b/uaclient/entitlements/cis.py | |||
1746 | index 07a6a2e..b5c81f4 100644 | |||
1747 | --- a/uaclient/entitlements/cis.py | |||
1748 | +++ b/uaclient/entitlements/cis.py | |||
1749 | @@ -29,7 +29,7 @@ class CISEntitlement(repo.RepoEntitlement): | |||
1750 | 29 | ] | 29 | ] |
1751 | 30 | } # type: MessagingOperationsDict | 30 | } # type: MessagingOperationsDict |
1752 | 31 | if "usg" in self.valid_names: | 31 | if "usg" in self.valid_names: |
1754 | 32 | messages["pre_enable"] = [ | 32 | messages["pre_can_enable"] = [ |
1755 | 33 | "From Ubuntu 20.04 and onwards 'ua enable cis' has been", | 33 | "From Ubuntu 20.04 and onwards 'ua enable cis' has been", |
1756 | 34 | "replaced by 'ua enable usg'. See more information at:", | 34 | "replaced by 'ua enable usg'. See more information at:", |
1757 | 35 | USG_DOCS_URL, | 35 | USG_DOCS_URL, |
1758 | diff --git a/uaclient/entitlements/fips.py b/uaclient/entitlements/fips.py | |||
1759 | index 7c78543..b83b47e 100644 | |||
1760 | --- a/uaclient/entitlements/fips.py | |||
1761 | +++ b/uaclient/entitlements/fips.py | |||
1762 | @@ -87,6 +87,27 @@ class FIPSCommonEntitlement(repo.RepoEntitlement): | |||
1763 | 87 | 87 | ||
1764 | 88 | help_doc_url = "https://ubuntu.com/security/certifications#fips" | 88 | help_doc_url = "https://ubuntu.com/security/certifications#fips" |
1765 | 89 | 89 | ||
1766 | 90 | fips_pro_package_holds = [ | ||
1767 | 91 | "fips-initramfs", | ||
1768 | 92 | "libssl1.1", | ||
1769 | 93 | "libssl1.1-hmac", | ||
1770 | 94 | "libssl1.0.0", | ||
1771 | 95 | "libssl1.0.0-hmac", | ||
1772 | 96 | "libssl1.0.0", | ||
1773 | 97 | "libssl1.0.0-hmac", | ||
1774 | 98 | "linux-fips", | ||
1775 | 99 | "openssh-client", | ||
1776 | 100 | "openssh-client-hmac", | ||
1777 | 101 | "openssh-server", | ||
1778 | 102 | "openssh-server-hmac", | ||
1779 | 103 | "openssl", | ||
1780 | 104 | "strongswan", | ||
1781 | 105 | "strongswan-hmac", | ||
1782 | 106 | "libgcrypt20", | ||
1783 | 107 | "libgcrypt20-hmac", | ||
1784 | 108 | "fips-initramfs-generic", | ||
1785 | 109 | ] | ||
1786 | 110 | |||
1787 | 90 | @property | 111 | @property |
1788 | 91 | def conditional_packages(self): | 112 | def conditional_packages(self): |
1789 | 92 | """ | 113 | """ |
1790 | @@ -155,19 +176,23 @@ class FIPSCommonEntitlement(repo.RepoEntitlement): | |||
1791 | 155 | ) | 176 | ) |
1792 | 156 | ) | 177 | ) |
1793 | 157 | 178 | ||
1795 | 158 | def _check_for_reboot_msg(self, operation: str) -> None: | 179 | def _check_for_reboot_msg( |
1796 | 180 | self, operation: str, silent: bool = False | ||
1797 | 181 | ) -> None: | ||
1798 | 159 | """Check if user should be alerted that a reboot must be performed. | 182 | """Check if user should be alerted that a reboot must be performed. |
1799 | 160 | 183 | ||
1800 | 161 | @param operation: The operation being executed. | 184 | @param operation: The operation being executed. |
1801 | 185 | @param silent: Boolean set True to silence print/log of messages | ||
1802 | 162 | """ | 186 | """ |
1803 | 163 | reboot_required = util.should_reboot() | 187 | reboot_required = util.should_reboot() |
1804 | 164 | event.needs_reboot(reboot_required) | 188 | event.needs_reboot(reboot_required) |
1805 | 165 | if reboot_required: | 189 | if reboot_required: |
1809 | 166 | event.info( | 190 | if not silent: |
1810 | 167 | messages.ENABLE_REBOOT_REQUIRED_TMPL.format( | 191 | event.info( |
1811 | 168 | operation=operation | 192 | messages.ENABLE_REBOOT_REQUIRED_TMPL.format( |
1812 | 193 | operation=operation | ||
1813 | 194 | ) | ||
1814 | 169 | ) | 195 | ) |
1815 | 170 | ) | ||
1816 | 171 | if operation == "install": | 196 | if operation == "install": |
1817 | 172 | self.cfg.add_notice( | 197 | self.cfg.add_notice( |
1818 | 173 | "", messages.FIPS_SYSTEM_REBOOT_REQUIRED.msg | 198 | "", messages.FIPS_SYSTEM_REBOOT_REQUIRED.msg |
1819 | @@ -361,6 +386,27 @@ class FIPSCommonEntitlement(repo.RepoEntitlement): | |||
1820 | 361 | 386 | ||
1821 | 362 | return False | 387 | return False |
1822 | 363 | 388 | ||
1823 | 389 | def setup_apt_config(self, silent: bool = False) -> None: | ||
1824 | 390 | """Setup apt config based on the resourceToken and directives. | ||
1825 | 391 | |||
1826 | 392 | FIPS-specifically handle apt-mark unhold | ||
1827 | 393 | |||
1828 | 394 | :raise UserFacingError: on failure to setup any aspect of this apt | ||
1829 | 395 | configuration | ||
1830 | 396 | """ | ||
1831 | 397 | cmd = ["apt-mark", "showholds"] | ||
1832 | 398 | holds = apt.run_apt_command(cmd, " ".join(cmd) + " failed.") | ||
1833 | 399 | unholds = [] | ||
1834 | 400 | for hold in holds.splitlines(): | ||
1835 | 401 | if hold in self.fips_pro_package_holds: | ||
1836 | 402 | unholds.append(hold) | ||
1837 | 403 | if unholds: | ||
1838 | 404 | unhold_cmd = ["apt-mark", "unhold"] + unholds | ||
1839 | 405 | holds = apt.run_apt_command( | ||
1840 | 406 | unhold_cmd, " ".join(unhold_cmd) + " failed." | ||
1841 | 407 | ) | ||
1842 | 408 | super().setup_apt_config(silent=silent) | ||
1843 | 409 | |||
1844 | 364 | 410 | ||
1845 | 365 | class FIPSEntitlement(FIPSCommonEntitlement): | 411 | class FIPSEntitlement(FIPSCommonEntitlement): |
1846 | 366 | 412 | ||
1847 | @@ -369,27 +415,10 @@ class FIPSEntitlement(FIPSCommonEntitlement): | |||
1848 | 369 | description = "NIST-certified core packages" | 415 | description = "NIST-certified core packages" |
1849 | 370 | origin = "UbuntuFIPS" | 416 | origin = "UbuntuFIPS" |
1850 | 371 | 417 | ||
1851 | 372 | fips_pro_package_holds = [ | ||
1852 | 373 | "fips-initramfs", | ||
1853 | 374 | "libssl1.1", | ||
1854 | 375 | "libssl1.1-hmac", | ||
1855 | 376 | "libssl1.0.0", | ||
1856 | 377 | "libssl1.0.0-hmac", | ||
1857 | 378 | "libssl1.0.0", | ||
1858 | 379 | "libssl1.0.0-hmac", | ||
1859 | 380 | "linux-fips", | ||
1860 | 381 | "openssh-client", | ||
1861 | 382 | "openssh-client-hmac", | ||
1862 | 383 | "openssh-server", | ||
1863 | 384 | "openssh-server-hmac", | ||
1864 | 385 | "openssl", | ||
1865 | 386 | "strongswan", | ||
1866 | 387 | "strongswan-hmac", | ||
1867 | 388 | ] | ||
1868 | 389 | |||
1869 | 390 | @property | 418 | @property |
1870 | 391 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: | 419 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: |
1871 | 392 | from uaclient.entitlements.livepatch import LivepatchEntitlement | 420 | from uaclient.entitlements.livepatch import LivepatchEntitlement |
1872 | 421 | from uaclient.entitlements.realtime import RealtimeKernelEntitlement | ||
1873 | 393 | 422 | ||
1874 | 394 | return ( | 423 | return ( |
1875 | 395 | IncompatibleService( | 424 | IncompatibleService( |
1876 | @@ -398,6 +427,9 @@ class FIPSEntitlement(FIPSCommonEntitlement): | |||
1877 | 398 | IncompatibleService( | 427 | IncompatibleService( |
1878 | 399 | FIPSUpdatesEntitlement, messages.FIPS_UPDATES_INVALIDATES_FIPS | 428 | FIPSUpdatesEntitlement, messages.FIPS_UPDATES_INVALIDATES_FIPS |
1879 | 400 | ), | 429 | ), |
1880 | 430 | IncompatibleService( | ||
1881 | 431 | RealtimeKernelEntitlement, messages.REALTIME_FIPS_INCOMPATIBLE | ||
1882 | 432 | ), | ||
1883 | 401 | ) | 433 | ) |
1884 | 402 | 434 | ||
1885 | 403 | @property | 435 | @property |
1886 | @@ -464,27 +496,6 @@ class FIPSEntitlement(FIPSCommonEntitlement): | |||
1887 | 464 | ], | 496 | ], |
1888 | 465 | } | 497 | } |
1889 | 466 | 498 | ||
1890 | 467 | def setup_apt_config(self, silent: bool = False) -> None: | ||
1891 | 468 | """Setup apt config based on the resourceToken and directives. | ||
1892 | 469 | |||
1893 | 470 | FIPS-specifically handle apt-mark unhold | ||
1894 | 471 | |||
1895 | 472 | :raise UserFacingError: on failure to setup any aspect of this apt | ||
1896 | 473 | configuration | ||
1897 | 474 | """ | ||
1898 | 475 | cmd = ["apt-mark", "showholds"] | ||
1899 | 476 | holds = apt.run_apt_command(cmd, " ".join(cmd) + " failed.") | ||
1900 | 477 | unholds = [] | ||
1901 | 478 | for hold in holds.splitlines(): | ||
1902 | 479 | if hold in self.fips_pro_package_holds: | ||
1903 | 480 | unholds.append(hold) | ||
1904 | 481 | if unholds: | ||
1905 | 482 | unhold_cmd = ["apt-mark", "unhold"] + unholds | ||
1906 | 483 | holds = apt.run_apt_command( | ||
1907 | 484 | unhold_cmd, " ".join(unhold_cmd) + " failed." | ||
1908 | 485 | ) | ||
1909 | 486 | super().setup_apt_config(silent=silent) | ||
1910 | 487 | |||
1911 | 488 | def _perform_enable(self, silent: bool = False) -> bool: | 499 | def _perform_enable(self, silent: bool = False) -> bool: |
1912 | 489 | cloud_type, error = get_cloud_type() | 500 | cloud_type, error = get_cloud_type() |
1913 | 490 | if cloud_type is None and error == NoCloudTypeReason.CLOUD_ID_ERROR: | 501 | if cloud_type is None and error == NoCloudTypeReason.CLOUD_ID_ERROR: |
1914 | @@ -507,6 +518,20 @@ class FIPSUpdatesEntitlement(FIPSCommonEntitlement): | |||
1915 | 507 | description = "NIST-certified core packages with priority security updates" | 518 | description = "NIST-certified core packages with priority security updates" |
1916 | 508 | 519 | ||
1917 | 509 | @property | 520 | @property |
1918 | 521 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: | ||
1919 | 522 | from uaclient.entitlements.realtime import RealtimeKernelEntitlement | ||
1920 | 523 | |||
1921 | 524 | return ( | ||
1922 | 525 | IncompatibleService( | ||
1923 | 526 | FIPSEntitlement, messages.FIPS_INVALIDATES_FIPS_UPDATES | ||
1924 | 527 | ), | ||
1925 | 528 | IncompatibleService( | ||
1926 | 529 | RealtimeKernelEntitlement, | ||
1927 | 530 | messages.REALTIME_FIPS_UPDATES_INCOMPATIBLE, | ||
1928 | 531 | ), | ||
1929 | 532 | ) | ||
1930 | 533 | |||
1931 | 534 | @property | ||
1932 | 510 | def messaging(self,) -> MessagingOperationsDict: | 535 | def messaging(self,) -> MessagingOperationsDict: |
1933 | 511 | post_enable = None # type: Optional[MessagingOperations] | 536 | post_enable = None # type: Optional[MessagingOperations] |
1934 | 512 | if util.is_container(): | 537 | if util.is_container(): |
1935 | diff --git a/uaclient/entitlements/livepatch.py b/uaclient/entitlements/livepatch.py | |||
1936 | index f652eb0..4fc9127 100644 | |||
1937 | --- a/uaclient/entitlements/livepatch.py | |||
1938 | +++ b/uaclient/entitlements/livepatch.py | |||
1939 | @@ -109,11 +109,16 @@ class LivepatchEntitlement(UAEntitlement): | |||
1940 | 109 | @property | 109 | @property |
1941 | 110 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: | 110 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: |
1942 | 111 | from uaclient.entitlements.fips import FIPSEntitlement | 111 | from uaclient.entitlements.fips import FIPSEntitlement |
1943 | 112 | from uaclient.entitlements.realtime import RealtimeKernelEntitlement | ||
1944 | 112 | 113 | ||
1945 | 113 | return ( | 114 | return ( |
1946 | 114 | IncompatibleService( | 115 | IncompatibleService( |
1947 | 115 | FIPSEntitlement, messages.LIVEPATCH_INVALIDATES_FIPS | 116 | FIPSEntitlement, messages.LIVEPATCH_INVALIDATES_FIPS |
1948 | 116 | ), | 117 | ), |
1949 | 118 | IncompatibleService( | ||
1950 | 119 | RealtimeKernelEntitlement, | ||
1951 | 120 | messages.REALTIME_LIVEPATCH_INCOMPATIBLE, | ||
1952 | 121 | ), | ||
1953 | 117 | ) | 122 | ) |
1954 | 118 | 123 | ||
1955 | 119 | @property | 124 | @property |
1956 | diff --git a/uaclient/entitlements/realtime.py b/uaclient/entitlements/realtime.py | |||
1957 | 120 | new file mode 100644 | 125 | new file mode 100644 |
1958 | index 0000000..35e5561 | |||
1959 | --- /dev/null | |||
1960 | +++ b/uaclient/entitlements/realtime.py | |||
1961 | @@ -0,0 +1,84 @@ | |||
1962 | 1 | from typing import Tuple | ||
1963 | 2 | |||
1964 | 3 | from uaclient import event_logger, messages, util | ||
1965 | 4 | from uaclient.entitlements import repo | ||
1966 | 5 | from uaclient.entitlements.base import IncompatibleService | ||
1967 | 6 | from uaclient.types import MessagingOperationsDict, StaticAffordance | ||
1968 | 7 | |||
1969 | 8 | event = event_logger.get_event_logger() | ||
1970 | 9 | |||
1971 | 10 | REALTIME_KERNEL_DOCS_URL = "https://ubuntu.com/realtime-kernel" | ||
1972 | 11 | |||
1973 | 12 | |||
1974 | 13 | class RealtimeKernelEntitlement(repo.RepoEntitlement): | ||
1975 | 14 | name = "realtime-kernel" | ||
1976 | 15 | title = "Real-Time Kernel" | ||
1977 | 16 | description = "Beta-version Ubuntu Kernel with PREEMPT_RT patches" | ||
1978 | 17 | help_doc_url = REALTIME_KERNEL_DOCS_URL | ||
1979 | 18 | repo_key_file = "ubuntu-advantage-realtime-kernel.gpg" | ||
1980 | 19 | is_beta = True | ||
1981 | 20 | apt_noninteractive = True | ||
1982 | 21 | |||
1983 | 22 | def _check_for_reboot(self) -> bool: | ||
1984 | 23 | """Check if system needs to be rebooted.""" | ||
1985 | 24 | reboot_required = util.should_reboot( | ||
1986 | 25 | installed_pkgs=set(self.packages), | ||
1987 | 26 | installed_pkgs_regex=set(["linux-.*-realtime"]), | ||
1988 | 27 | ) | ||
1989 | 28 | event.needs_reboot(reboot_required) | ||
1990 | 29 | return reboot_required | ||
1991 | 30 | |||
1992 | 31 | @property | ||
1993 | 32 | def incompatible_services(self) -> Tuple[IncompatibleService, ...]: | ||
1994 | 33 | from uaclient.entitlements.fips import ( | ||
1995 | 34 | FIPSEntitlement, | ||
1996 | 35 | FIPSUpdatesEntitlement, | ||
1997 | 36 | ) | ||
1998 | 37 | from uaclient.entitlements.livepatch import LivepatchEntitlement | ||
1999 | 38 | |||
2000 | 39 | return ( | ||
2001 | 40 | IncompatibleService( | ||
2002 | 41 | FIPSEntitlement, messages.REALTIME_FIPS_INCOMPATIBLE | ||
2003 | 42 | ), | ||
2004 | 43 | IncompatibleService( | ||
2005 | 44 | FIPSUpdatesEntitlement, | ||
2006 | 45 | messages.REALTIME_FIPS_UPDATES_INCOMPATIBLE, | ||
2007 | 46 | ), | ||
2008 | 47 | IncompatibleService( | ||
2009 | 48 | LivepatchEntitlement, messages.REALTIME_LIVEPATCH_INCOMPATIBLE | ||
2010 | 49 | ), | ||
2011 | 50 | ) | ||
2012 | 51 | |||
2013 | 52 | @property | ||
2014 | 53 | def static_affordances(self) -> Tuple[StaticAffordance, ...]: | ||
2015 | 54 | return ( | ||
2016 | 55 | ( | ||
2017 | 56 | messages.REALTIME_ERROR_INSTALL_ON_CONTAINER, | ||
2018 | 57 | lambda: util.is_container(), | ||
2019 | 58 | False, | ||
2020 | 59 | ), | ||
2021 | 60 | ) | ||
2022 | 61 | |||
2023 | 62 | @property | ||
2024 | 63 | def messaging(self,) -> MessagingOperationsDict: | ||
2025 | 64 | return { | ||
2026 | 65 | "pre_enable": [ | ||
2027 | 66 | ( | ||
2028 | 67 | util.prompt_for_confirmation, | ||
2029 | 68 | { | ||
2030 | 69 | "msg": messages.REALTIME_BETA_PROMPT, | ||
2031 | 70 | "assume_yes": self.assume_yes, | ||
2032 | 71 | "default": True, | ||
2033 | 72 | }, | ||
2034 | 73 | ) | ||
2035 | 74 | ], | ||
2036 | 75 | "pre_disable": [ | ||
2037 | 76 | ( | ||
2038 | 77 | util.prompt_for_confirmation, | ||
2039 | 78 | { | ||
2040 | 79 | "msg": messages.REALTIME_PRE_DISABLE_PROMPT, | ||
2041 | 80 | "assume_yes": self.assume_yes, | ||
2042 | 81 | }, | ||
2043 | 82 | ) | ||
2044 | 83 | ], | ||
2045 | 84 | } | ||
2046 | diff --git a/uaclient/entitlements/tests/test_cc.py b/uaclient/entitlements/tests/test_cc.py | |||
2047 | index 2e42b5f..362f5ea 100644 | |||
2048 | --- a/uaclient/entitlements/tests/test_cc.py | |||
2049 | +++ b/uaclient/entitlements/tests/test_cc.py | |||
2050 | @@ -110,8 +110,10 @@ class TestCommonCriteriaEntitlementEnable: | |||
2051 | 110 | @mock.patch("uaclient.util.should_reboot") | 110 | @mock.patch("uaclient.util.should_reboot") |
2052 | 111 | @mock.patch("uaclient.util.subp") | 111 | @mock.patch("uaclient.util.subp") |
2053 | 112 | @mock.patch("uaclient.util.get_platform_info") | 112 | @mock.patch("uaclient.util.get_platform_info") |
2054 | 113 | @mock.patch("uaclient.util.apply_contract_overrides") | ||
2055 | 113 | def test_enable_configures_apt_sources_and_auth_files( | 114 | def test_enable_configures_apt_sources_and_auth_files( |
2056 | 114 | self, | 115 | self, |
2057 | 116 | _m_contract_overrides, | ||
2058 | 115 | m_platform_info, | 117 | m_platform_info, |
2059 | 116 | m_subp, | 118 | m_subp, |
2060 | 117 | m_should_reboot, | 119 | m_should_reboot, |
2061 | diff --git a/uaclient/entitlements/tests/test_fips.py b/uaclient/entitlements/tests/test_fips.py | |||
2062 | index 8cf2898..51dc72f 100644 | |||
2063 | --- a/uaclient/entitlements/tests/test_fips.py | |||
2064 | +++ b/uaclient/entitlements/tests/test_fips.py | |||
2065 | @@ -21,6 +21,7 @@ from uaclient.entitlements.fips import ( | |||
2066 | 21 | FIPSEntitlement, | 21 | FIPSEntitlement, |
2067 | 22 | FIPSUpdatesEntitlement, | 22 | FIPSUpdatesEntitlement, |
2068 | 23 | ) | 23 | ) |
2069 | 24 | from uaclient.status import CanEnableFailureReason | ||
2070 | 24 | 25 | ||
2071 | 25 | M_PATH = "uaclient.entitlements.fips." | 26 | M_PATH = "uaclient.entitlements.fips." |
2072 | 26 | M_LIVEPATCH_PATH = "uaclient.entitlements.livepatch.LivepatchEntitlement." | 27 | M_LIVEPATCH_PATH = "uaclient.entitlements.livepatch.LivepatchEntitlement." |
2073 | @@ -302,9 +303,11 @@ class TestFIPSEntitlementEnable: | |||
2074 | 302 | stack.enter_context( | 303 | stack.enter_context( |
2075 | 303 | mock.patch.object(type(entitlement), "packages", m_packages) | 304 | mock.patch.object(type(entitlement), "packages", m_packages) |
2076 | 304 | ) | 305 | ) |
2077 | 306 | stack.enter_context( | ||
2078 | 307 | mock.patch("uaclient.util.is_container", return_value=False) | ||
2079 | 308 | ) | ||
2080 | 305 | 309 | ||
2081 | 306 | m_can_enable.return_value = (True, None) | 310 | m_can_enable.return_value = (True, None) |
2082 | 307 | |||
2083 | 308 | assert (True, None) == entitlement.enable() | 311 | assert (True, None) == entitlement.enable() |
2084 | 309 | 312 | ||
2085 | 310 | repo_url = "http://{}".format(entitlement.name.upper()) | 313 | repo_url = "http://{}".format(entitlement.name.upper()) |
2086 | @@ -364,27 +367,20 @@ class TestFIPSEntitlementEnable: | |||
2087 | 364 | ) | 367 | ) |
2088 | 365 | ) | 368 | ) |
2089 | 366 | 369 | ||
2111 | 367 | if isinstance(entitlement, FIPSEntitlement): | 370 | subp_calls = [ |
2112 | 368 | subp_calls = [ | 371 | mock.call( |
2113 | 369 | mock.call( | 372 | ["apt-mark", "showholds"], |
2114 | 370 | ["apt-mark", "showholds"], | 373 | capture=True, |
2115 | 371 | capture=True, | 374 | retry_sleeps=apt.APT_RETRIES, |
2116 | 372 | retry_sleeps=apt.APT_RETRIES, | 375 | env={}, |
2117 | 373 | env={}, | 376 | ), |
2118 | 374 | ) | 377 | mock.call( |
2119 | 375 | ] | 378 | ["apt-get", "update"], |
2120 | 376 | else: | 379 | capture=True, |
2121 | 377 | subp_calls = [] | 380 | retry_sleeps=apt.APT_RETRIES, |
2122 | 378 | subp_calls.extend( | 381 | env={}, |
2123 | 379 | [ | 382 | ), |
2124 | 380 | mock.call( | 383 | ] |
2104 | 381 | ["apt-get", "update"], | ||
2105 | 382 | capture=True, | ||
2106 | 383 | retry_sleeps=apt.APT_RETRIES, | ||
2107 | 384 | env={}, | ||
2108 | 385 | ) | ||
2109 | 386 | ] | ||
2110 | 387 | ) | ||
2125 | 388 | subp_calls += install_cmd | 384 | subp_calls += install_cmd |
2126 | 389 | 385 | ||
2127 | 390 | assert [mock.call()] == m_can_enable.call_args_list | 386 | assert [mock.call()] == m_can_enable.call_args_list |
2128 | @@ -1092,6 +1088,10 @@ class TestFipsSetupAPTConfig: | |||
2129 | 1092 | "openssh-server\nlibssl1.1-hmac\nasdf\n", | 1088 | "openssh-server\nlibssl1.1-hmac\nasdf\n", |
2130 | 1093 | ["openssh-server", "libssl1.1-hmac"], | 1089 | ["openssh-server", "libssl1.1-hmac"], |
2131 | 1094 | ), | 1090 | ), |
2132 | 1091 | ( | ||
2133 | 1092 | "libgcrypt20\nlibgcrypt20-hmac\nwow\n", | ||
2134 | 1093 | ["libgcrypt20", "libgcrypt20-hmac"], | ||
2135 | 1094 | ), | ||
2136 | 1095 | ), | 1095 | ), |
2137 | 1096 | ) | 1096 | ) |
2138 | 1097 | @mock.patch(M_REPOPATH + "RepoEntitlement.setup_apt_config") | 1097 | @mock.patch(M_REPOPATH + "RepoEntitlement.setup_apt_config") |
2139 | @@ -1107,19 +1107,12 @@ class TestFipsSetupAPTConfig: | |||
2140 | 1107 | """Unmark only fips-specific package holds if present.""" | 1107 | """Unmark only fips-specific package holds if present.""" |
2141 | 1108 | run_apt_command.return_value = held_packages | 1108 | run_apt_command.return_value = held_packages |
2142 | 1109 | entitlement.setup_apt_config(silent=False) | 1109 | entitlement.setup_apt_config(silent=False) |
2156 | 1110 | if isinstance(entitlement, FIPSUpdatesEntitlement): | 1110 | expected_calls = [ |
2157 | 1111 | expected_calls = [] | 1111 | mock.call(["apt-mark", "showholds"], "apt-mark showholds failed.") |
2158 | 1112 | else: | 1112 | ] |
2159 | 1113 | expected_calls = [ | 1113 | if unhold_packages: |
2160 | 1114 | mock.call( | 1114 | cmd = ["apt-mark", "unhold"] + unhold_packages |
2161 | 1115 | ["apt-mark", "showholds"], "apt-mark showholds failed." | 1115 | expected_calls.append(mock.call(cmd, " ".join(cmd) + " failed.")) |
2149 | 1116 | ) | ||
2150 | 1117 | ] | ||
2151 | 1118 | if unhold_packages: | ||
2152 | 1119 | cmd = ["apt-mark", "unhold"] + unhold_packages | ||
2153 | 1120 | expected_calls.append( | ||
2154 | 1121 | mock.call(cmd, " ".join(cmd) + " failed.") | ||
2155 | 1122 | ) | ||
2162 | 1123 | assert expected_calls == run_apt_command.call_args_list | 1116 | assert expected_calls == run_apt_command.call_args_list |
2163 | 1124 | assert [mock.call(silent=False)] == setup_apt_config.call_args_list | 1117 | assert [mock.call(silent=False)] == setup_apt_config.call_args_list |
2164 | 1125 | 1118 | ||
2165 | @@ -1287,3 +1280,35 @@ class TestFIPSUpdatesEntitlementEnable: | |||
2166 | 1287 | else: | 1280 | else: |
2167 | 1288 | assert not m_read_cache.call_count | 1281 | assert not m_read_cache.call_count |
2168 | 1289 | assert not m_write_cache.call_count | 1282 | assert not m_write_cache.call_count |
2169 | 1283 | |||
2170 | 1284 | |||
2171 | 1285 | class TestFIPSUpdatesEntitlementCanEnable: | ||
2172 | 1286 | @mock.patch("uaclient.util.is_config_value_true", return_value=False) | ||
2173 | 1287 | def test_can_enable_false_if_fips_enabled( | ||
2174 | 1288 | self, m_is_config_value_true, capsys, entitlement_factory | ||
2175 | 1289 | ): | ||
2176 | 1290 | """When entitlement is disabled, can_enable returns True.""" | ||
2177 | 1291 | entitlement = entitlement_factory(FIPSUpdatesEntitlement) | ||
2178 | 1292 | with mock.patch.object( | ||
2179 | 1293 | entitlement, | ||
2180 | 1294 | "applicability_status", | ||
2181 | 1295 | return_value=(status.ApplicabilityStatus.APPLICABLE, ""), | ||
2182 | 1296 | ): | ||
2183 | 1297 | with mock.patch.object( | ||
2184 | 1298 | entitlement, | ||
2185 | 1299 | "application_status", | ||
2186 | 1300 | return_value=(status.ApplicationStatus.DISABLED, ""), | ||
2187 | 1301 | ): | ||
2188 | 1302 | with mock.patch( | ||
2189 | 1303 | M_PATH + "FIPSEntitlement.application_status" | ||
2190 | 1304 | ) as m_fips_status: | ||
2191 | 1305 | m_fips_status.return_value = ( | ||
2192 | 1306 | status.ApplicationStatus.ENABLED, | ||
2193 | 1307 | None, | ||
2194 | 1308 | ) | ||
2195 | 1309 | actual_ret, reason = entitlement.can_enable() | ||
2196 | 1310 | assert actual_ret is False | ||
2197 | 1311 | assert ( | ||
2198 | 1312 | reason.reason | ||
2199 | 1313 | == CanEnableFailureReason.INCOMPATIBLE_SERVICE | ||
2200 | 1314 | ) | ||
2201 | diff --git a/uaclient/entitlements/tests/test_livepatch.py b/uaclient/entitlements/tests/test_livepatch.py | |||
2202 | index 191e91d..50fb50d 100644 | |||
2203 | --- a/uaclient/entitlements/tests/test_livepatch.py | |||
2204 | +++ b/uaclient/entitlements/tests/test_livepatch.py | |||
2205 | @@ -617,6 +617,7 @@ class TestLivepatchEntitlementEnable: | |||
2206 | 617 | @pytest.mark.parametrize("apt_update_success", (True, False)) | 617 | @pytest.mark.parametrize("apt_update_success", (True, False)) |
2207 | 618 | @mock.patch("uaclient.util.get_platform_info") | 618 | @mock.patch("uaclient.util.get_platform_info") |
2208 | 619 | @mock.patch("uaclient.util.subp") | 619 | @mock.patch("uaclient.util.subp") |
2209 | 620 | @mock.patch("uaclient.util.apply_contract_overrides") | ||
2210 | 620 | @mock.patch("uaclient.apt.run_apt_install_command") | 621 | @mock.patch("uaclient.apt.run_apt_install_command") |
2211 | 621 | @mock.patch("uaclient.apt.run_apt_update_command") | 622 | @mock.patch("uaclient.apt.run_apt_update_command") |
2212 | 622 | @mock.patch("uaclient.util.which", return_value=False) | 623 | @mock.patch("uaclient.util.which", return_value=False) |
2213 | @@ -631,6 +632,7 @@ class TestLivepatchEntitlementEnable: | |||
2214 | 631 | m_which, | 632 | m_which, |
2215 | 632 | m_run_apt_update, | 633 | m_run_apt_update, |
2216 | 633 | m_run_apt_install, | 634 | m_run_apt_install, |
2217 | 635 | _m_contract_overrides, | ||
2218 | 634 | m_subp, | 636 | m_subp, |
2219 | 635 | _m_get_platform_info, | 637 | _m_get_platform_info, |
2220 | 636 | m_livepatch_proxy, | 638 | m_livepatch_proxy, |
2221 | @@ -678,6 +680,7 @@ class TestLivepatchEntitlementEnable: | |||
2222 | 678 | 680 | ||
2223 | 679 | @mock.patch("uaclient.util.get_platform_info") | 681 | @mock.patch("uaclient.util.get_platform_info") |
2224 | 680 | @mock.patch("uaclient.util.subp", return_value=("snapd", "")) | 682 | @mock.patch("uaclient.util.subp", return_value=("snapd", "")) |
2225 | 683 | @mock.patch("uaclient.util.apply_contract_overrides") | ||
2226 | 681 | @mock.patch( | 684 | @mock.patch( |
2227 | 682 | "uaclient.util.which", side_effect=lambda cmd: cmd == "/usr/bin/snap" | 685 | "uaclient.util.which", side_effect=lambda cmd: cmd == "/usr/bin/snap" |
2228 | 683 | ) | 686 | ) |
2229 | @@ -690,6 +693,7 @@ class TestLivepatchEntitlementEnable: | |||
2230 | 690 | m_can_enable, | 693 | m_can_enable, |
2231 | 691 | m_app_status, | 694 | m_app_status, |
2232 | 692 | m_which, | 695 | m_which, |
2233 | 696 | _m_contract_overrides, | ||
2234 | 693 | m_subp, | 697 | m_subp, |
2235 | 694 | _m_get_platform_info, | 698 | _m_get_platform_info, |
2236 | 695 | m_livepatch_proxy, | 699 | m_livepatch_proxy, |
2237 | @@ -759,6 +763,7 @@ class TestLivepatchEntitlementEnable: | |||
2238 | 759 | @mock.patch("uaclient.apt.get_installed_packages", return_value=["snapd"]) | 763 | @mock.patch("uaclient.apt.get_installed_packages", return_value=["snapd"]) |
2239 | 760 | @mock.patch("uaclient.util.get_platform_info") | 764 | @mock.patch("uaclient.util.get_platform_info") |
2240 | 761 | @mock.patch("uaclient.util.subp") | 765 | @mock.patch("uaclient.util.subp") |
2241 | 766 | @mock.patch("uaclient.util.apply_contract_overrides") | ||
2242 | 762 | @mock.patch("uaclient.util.which", side_effect=[True, True]) | 767 | @mock.patch("uaclient.util.which", side_effect=[True, True]) |
2243 | 763 | @mock.patch(M_PATH + "LivepatchEntitlement.application_status") | 768 | @mock.patch(M_PATH + "LivepatchEntitlement.application_status") |
2244 | 764 | @mock.patch( | 769 | @mock.patch( |
2245 | @@ -769,6 +774,7 @@ class TestLivepatchEntitlementEnable: | |||
2246 | 769 | m_can_enable, | 774 | m_can_enable, |
2247 | 770 | m_app_status, | 775 | m_app_status, |
2248 | 771 | m_which, | 776 | m_which, |
2249 | 777 | _m_contract_overrides, | ||
2250 | 772 | m_subp, | 778 | m_subp, |
2251 | 773 | _m_get_platform_info, | 779 | _m_get_platform_info, |
2252 | 774 | _m_get_installed_packages, | 780 | _m_get_installed_packages, |
2253 | @@ -808,6 +814,7 @@ class TestLivepatchEntitlementEnable: | |||
2254 | 808 | @mock.patch("uaclient.apt.get_installed_packages", return_value=["snapd"]) | 814 | @mock.patch("uaclient.apt.get_installed_packages", return_value=["snapd"]) |
2255 | 809 | @mock.patch("uaclient.util.get_platform_info") | 815 | @mock.patch("uaclient.util.get_platform_info") |
2256 | 810 | @mock.patch("uaclient.util.subp") | 816 | @mock.patch("uaclient.util.subp") |
2257 | 817 | @mock.patch("uaclient.util.apply_contract_overrides") | ||
2258 | 811 | @mock.patch("uaclient.util.which", side_effect=[True, True]) | 818 | @mock.patch("uaclient.util.which", side_effect=[True, True]) |
2259 | 812 | @mock.patch(M_PATH + "LivepatchEntitlement.application_status") | 819 | @mock.patch(M_PATH + "LivepatchEntitlement.application_status") |
2260 | 813 | @mock.patch( | 820 | @mock.patch( |
2261 | @@ -818,6 +825,7 @@ class TestLivepatchEntitlementEnable: | |||
2262 | 818 | m_can_enable, | 825 | m_can_enable, |
2263 | 819 | m_app_status, | 826 | m_app_status, |
2264 | 820 | m_which, | 827 | m_which, |
2265 | 828 | _m_contract_overrides, | ||
2266 | 821 | m_subp, | 829 | m_subp, |
2267 | 822 | _m_get_platform_info, | 830 | _m_get_platform_info, |
2268 | 823 | _m_get_installed_packages, | 831 | _m_get_installed_packages, |
2269 | diff --git a/uaclient/entitlements/tests/test_repo.py b/uaclient/entitlements/tests/test_repo.py | |||
2270 | index 084bab0..c59cb47 100644 | |||
2271 | --- a/uaclient/entitlements/tests/test_repo.py | |||
2272 | +++ b/uaclient/entitlements/tests/test_repo.py | |||
2273 | @@ -385,23 +385,25 @@ class TestProcessContractDeltas: | |||
2274 | 385 | 385 | ||
2275 | 386 | class TestRepoEnable: | 386 | class TestRepoEnable: |
2276 | 387 | @pytest.mark.parametrize( | 387 | @pytest.mark.parametrize( |
2278 | 388 | "pre_enable_msg, output, can_enable_call_count", | 388 | "pre_enable_msg, output, perform_enable_call_count", |
2279 | 389 | ( | 389 | ( |
2280 | 390 | (["msg1", (lambda: False, {}), "msg2"], "msg1\n", 0), | 390 | (["msg1", (lambda: False, {}), "msg2"], "msg1\n", 0), |
2281 | 391 | (["msg1", (lambda: True, {}), "msg2"], "msg1\nmsg2\n", 1), | 391 | (["msg1", (lambda: True, {}), "msg2"], "msg1\nmsg2\n", 1), |
2282 | 392 | ), | 392 | ), |
2283 | 393 | ) | 393 | ) |
2284 | 394 | @mock.patch.object( | 394 | @mock.patch.object( |
2288 | 395 | RepoTestEntitlement, | 395 | RepoTestEntitlement, "_perform_enable", return_value=False |
2289 | 396 | "can_enable", | 396 | ) |
2290 | 397 | return_value=(False, status.CanEnableFailure(None)), | 397 | @mock.patch.object( |
2291 | 398 | RepoTestEntitlement, "can_enable", return_value=(True, None) | ||
2292 | 398 | ) | 399 | ) |
2293 | 399 | def test_enable_can_exit_on_pre_enable_messaging_hooks( | 400 | def test_enable_can_exit_on_pre_enable_messaging_hooks( |
2294 | 400 | self, | 401 | self, |
2296 | 401 | m_can_enable, | 402 | _m_can_enable, |
2297 | 403 | m_perform_enable, | ||
2298 | 402 | pre_enable_msg, | 404 | pre_enable_msg, |
2299 | 403 | output, | 405 | output, |
2301 | 404 | can_enable_call_count, | 406 | perform_enable_call_count, |
2302 | 405 | entitlement, | 407 | entitlement, |
2303 | 406 | capsys, | 408 | capsys, |
2304 | 407 | ): | 409 | ): |
2305 | @@ -414,7 +416,7 @@ class TestRepoEnable: | |||
2306 | 414 | entitlement.enable() | 416 | entitlement.enable() |
2307 | 415 | stdout, _ = capsys.readouterr() | 417 | stdout, _ = capsys.readouterr() |
2308 | 416 | assert output == stdout | 418 | assert output == stdout |
2310 | 417 | assert can_enable_call_count == m_can_enable.call_count | 419 | assert perform_enable_call_count == m_perform_enable.call_count |
2311 | 418 | 420 | ||
2312 | 419 | @pytest.mark.parametrize( | 421 | @pytest.mark.parametrize( |
2313 | 420 | "pre_disable_msg,post_disable_msg,output,retval", | 422 | "pre_disable_msg,post_disable_msg,output,retval", |
2314 | @@ -734,8 +736,10 @@ class TestRemoveAptConfig: | |||
2315 | 734 | @mock.patch(M_PATH + "apt.remove_apt_list_files") | 736 | @mock.patch(M_PATH + "apt.remove_apt_list_files") |
2316 | 735 | @mock.patch(M_PATH + "apt.run_apt_command") | 737 | @mock.patch(M_PATH + "apt.run_apt_command") |
2317 | 736 | @mock.patch(M_PATH + "util.get_platform_info") | 738 | @mock.patch(M_PATH + "util.get_platform_info") |
2318 | 739 | @mock.patch(M_PATH + "util.apply_contract_overrides") | ||
2319 | 737 | def test_repo_pin_priority_int_removes_apt_preferences( | 740 | def test_repo_pin_priority_int_removes_apt_preferences( |
2320 | 738 | self, | 741 | self, |
2321 | 742 | _m_contract_overrides, | ||
2322 | 739 | m_get_platform, | 743 | m_get_platform, |
2323 | 740 | _m_run_apt_command, | 744 | _m_run_apt_command, |
2324 | 741 | _m_remove_apt_list_files, | 745 | _m_remove_apt_list_files, |
2325 | @@ -862,8 +866,10 @@ class TestSetupAptConfig: | |||
2326 | 862 | @mock.patch("uaclient.apt.setup_apt_proxy") | 866 | @mock.patch("uaclient.apt.setup_apt_proxy") |
2327 | 863 | @mock.patch(M_PATH + "apt.add_auth_apt_repo") | 867 | @mock.patch(M_PATH + "apt.add_auth_apt_repo") |
2328 | 864 | @mock.patch(M_PATH + "apt.run_apt_install_command") | 868 | @mock.patch(M_PATH + "apt.run_apt_install_command") |
2329 | 869 | @mock.patch(M_PATH + "util.apply_contract_overrides") | ||
2330 | 865 | def test_install_prerequisite_packages( | 870 | def test_install_prerequisite_packages( |
2331 | 866 | self, | 871 | self, |
2332 | 872 | _m_contract_overrides, | ||
2333 | 867 | m_run_apt_install_command, | 873 | m_run_apt_install_command, |
2334 | 868 | m_add_auth_repo, | 874 | m_add_auth_repo, |
2335 | 869 | _m_setup_apt_proxy, | 875 | _m_setup_apt_proxy, |
2336 | @@ -908,8 +914,10 @@ class TestSetupAptConfig: | |||
2337 | 908 | @mock.patch(M_PATH + "apt.add_auth_apt_repo") | 914 | @mock.patch(M_PATH + "apt.add_auth_apt_repo") |
2338 | 909 | @mock.patch(M_PATH + "apt.run_apt_command") | 915 | @mock.patch(M_PATH + "apt.run_apt_command") |
2339 | 910 | @mock.patch(M_PATH + "util.get_platform_info") | 916 | @mock.patch(M_PATH + "util.get_platform_info") |
2340 | 917 | @mock.patch(M_PATH + "util.apply_contract_overrides") | ||
2341 | 911 | def test_setup_with_repo_pin_priority_never_removes_apt_preferences_file( | 918 | def test_setup_with_repo_pin_priority_never_removes_apt_preferences_file( |
2342 | 912 | self, | 919 | self, |
2343 | 920 | _m_contract_overrides, | ||
2344 | 913 | m_get_platform_info, | 921 | m_get_platform_info, |
2345 | 914 | m_run_apt_command, | 922 | m_run_apt_command, |
2346 | 915 | m_add_auth_repo, | 923 | m_add_auth_repo, |
2347 | @@ -940,8 +948,10 @@ class TestSetupAptConfig: | |||
2348 | 940 | @mock.patch(M_PATH + "apt.run_apt_update_command") | 948 | @mock.patch(M_PATH + "apt.run_apt_update_command") |
2349 | 941 | @mock.patch(M_PATH + "apt.add_ppa_pinning") | 949 | @mock.patch(M_PATH + "apt.add_ppa_pinning") |
2350 | 942 | @mock.patch(M_PATH + "util.get_platform_info") | 950 | @mock.patch(M_PATH + "util.get_platform_info") |
2351 | 951 | @mock.patch(M_PATH + "util.apply_contract_overrides") | ||
2352 | 943 | def test_setup_with_repo_pin_priority_int_adds_a_pins_repo_apt_preference( | 952 | def test_setup_with_repo_pin_priority_int_adds_a_pins_repo_apt_preference( |
2353 | 944 | self, | 953 | self, |
2354 | 954 | _m_apply_overrides, | ||
2355 | 945 | m_get_platform_info, | 955 | m_get_platform_info, |
2356 | 946 | m_add_ppa_pinning, | 956 | m_add_ppa_pinning, |
2357 | 947 | m_run_apt_update_command, | 957 | m_run_apt_update_command, |
2358 | diff --git a/uaclient/messages.py b/uaclient/messages.py | |||
2359 | index b7640b8..e9f5d9c 100644 | |||
2360 | --- a/uaclient/messages.py | |||
2361 | +++ b/uaclient/messages.py | |||
2362 | @@ -22,6 +22,7 @@ class TxtColor: | |||
2363 | 22 | OKGREEN = "\033[92m" | 22 | OKGREEN = "\033[92m" |
2364 | 23 | DISABLEGREY = "\033[37m" | 23 | DISABLEGREY = "\033[37m" |
2365 | 24 | FAIL = "\033[91m" | 24 | FAIL = "\033[91m" |
2366 | 25 | BOLD = "\033[1m" | ||
2367 | 25 | ENDC = "\033[0m" | 26 | ENDC = "\033[0m" |
2368 | 26 | 27 | ||
2369 | 27 | 28 | ||
2370 | @@ -661,6 +662,12 @@ FIPS_UPDATES_INVALIDATES_FIPS = NamedMessage( | |||
2371 | 661 | " FIPS Updates installs security patches that aren't officially" | 662 | " FIPS Updates installs security patches that aren't officially" |
2372 | 662 | " certified.", | 663 | " certified.", |
2373 | 663 | ) | 664 | ) |
2374 | 665 | FIPS_INVALIDATES_FIPS_UPDATES = NamedMessage( | ||
2375 | 666 | "fips-invalidates-fips-updates", | ||
2376 | 667 | "FIPS Updates cannot be enabled if FIPS is enabled." | ||
2377 | 668 | " FIPS Updates installs security patches that aren't officially" | ||
2378 | 669 | " certified.", | ||
2379 | 670 | ) | ||
2380 | 664 | LIVEPATCH_INVALIDATES_FIPS = NamedMessage( | 671 | LIVEPATCH_INVALIDATES_FIPS = NamedMessage( |
2381 | 665 | "livepatch-invalidates-fips", | 672 | "livepatch-invalidates-fips", |
2382 | 666 | "Livepatch cannot be enabled while running the official FIPS" | 673 | "Livepatch cannot be enabled while running the official FIPS" |
2383 | @@ -668,6 +675,45 @@ LIVEPATCH_INVALIDATES_FIPS = NamedMessage( | |||
2384 | 668 | " with additional bug fixes and security updates, you can use" | 675 | " with additional bug fixes and security updates, you can use" |
2385 | 669 | " the FIPS Updates service with Livepatch.", | 676 | " the FIPS Updates service with Livepatch.", |
2386 | 670 | ) | 677 | ) |
2387 | 678 | REALTIME_FIPS_INCOMPATIBLE = NamedMessage( | ||
2388 | 679 | "realtime-fips-incompatible", | ||
2389 | 680 | "Realtime and FIPS require different kernels, so you cannot enable" | ||
2390 | 681 | " both at the same time.", | ||
2391 | 682 | ) | ||
2392 | 683 | REALTIME_FIPS_UPDATES_INCOMPATIBLE = NamedMessage( | ||
2393 | 684 | "realtime-fips-updates-incompatible", | ||
2394 | 685 | "Realtime and FIPS Updates require different kernels, so you cannot enable" | ||
2395 | 686 | " both at the same time.", | ||
2396 | 687 | ) | ||
2397 | 688 | REALTIME_LIVEPATCH_INCOMPATIBLE = NamedMessage( | ||
2398 | 689 | "realtime-livepatch-incompatible", | ||
2399 | 690 | "Livepatch is not currently supported for the real-time kernel.", | ||
2400 | 691 | ) | ||
2401 | 692 | REALTIME_BETA_FLAG_REQUIRED = NamedMessage( | ||
2402 | 693 | "beta-flag-required", | ||
2403 | 694 | "Use `ua enable realtime-kernel --beta` to acknowledge the real-time" | ||
2404 | 695 | " kernel is currently in beta and comes with no support.", | ||
2405 | 696 | ) | ||
2406 | 697 | REALTIME_BETA_PROMPT = """\ | ||
2407 | 698 | The real-time kernel is a beta version of the 22.04 Ubuntu kernel with the | ||
2408 | 699 | PREEMPT_RT patchset integrated for x86_64 and ARM64. | ||
2409 | 700 | |||
2410 | 701 | {bold}You will not be able to revert to your original kernel after enabling\ | ||
2411 | 702 | real-time.{end_bold} | ||
2412 | 703 | |||
2413 | 704 | Do you want to continue? [ default = Yes ]: (Y/n) """.format( | ||
2414 | 705 | bold=TxtColor.BOLD, end_bold=TxtColor.ENDC | ||
2415 | 706 | ) | ||
2416 | 707 | REALTIME_PRE_DISABLE_PROMPT = """\ | ||
2417 | 708 | This will disable the Real-Time Kernel entitlement but the Real-Time Kernel\ | ||
2418 | 709 | will remain installed. | ||
2419 | 710 | Are you sure? (y/N) """ | ||
2420 | 711 | |||
2421 | 712 | REALTIME_ERROR_INSTALL_ON_CONTAINER = NamedMessage( | ||
2422 | 713 | "realtime-error-install-on-container", | ||
2423 | 714 | "Cannot install Real-Time Kernel on a container.", | ||
2424 | 715 | ) | ||
2425 | 716 | |||
2426 | 671 | 717 | ||
2427 | 672 | LOG_CONNECTIVITY_ERROR_TMPL = CONNECTIVITY_ERROR.msg + " {error}" | 718 | LOG_CONNECTIVITY_ERROR_TMPL = CONNECTIVITY_ERROR.msg + " {error}" |
2428 | 673 | LOG_CONNECTIVITY_ERROR_WITH_URL_TMPL = ( | 719 | LOG_CONNECTIVITY_ERROR_WITH_URL_TMPL = ( |
2429 | diff --git a/uaclient/status.py b/uaclient/status.py | |||
2430 | index 7dd5ba2..3db4b67 100644 | |||
2431 | --- a/uaclient/status.py | |||
2432 | +++ b/uaclient/status.py | |||
2433 | @@ -225,17 +225,17 @@ Open a browser to: {}/subscribe""".format( | |||
2434 | 225 | BASE_UA_URL | 225 | BASE_UA_URL |
2435 | 226 | ) | 226 | ) |
2436 | 227 | 227 | ||
2438 | 228 | STATUS_UNATTACHED_TMPL = "{name: <14}{available: <11}{description}" | 228 | STATUS_UNATTACHED_TMPL = "{name: <17}{available: <11}{description}" |
2439 | 229 | 229 | ||
2440 | 230 | STATUS_SIMULATED_TMPL = """\ | 230 | STATUS_SIMULATED_TMPL = """\ |
2442 | 231 | {name: <14}{available: <11}{entitled: <11}{auto_enabled: <14}{description}""" | 231 | {name: <17}{available: <11}{entitled: <11}{auto_enabled: <14}{description}""" |
2443 | 232 | 232 | ||
2445 | 233 | STATUS_HEADER = "SERVICE ENTITLED STATUS DESCRIPTION" | 233 | STATUS_HEADER = "SERVICE ENTITLED STATUS DESCRIPTION" |
2446 | 234 | # The widths listed below for entitled and status are actually 9 characters | 234 | # The widths listed below for entitled and status are actually 9 characters |
2447 | 235 | # less than reality because we colorize the values in entitled and status | 235 | # less than reality because we colorize the values in entitled and status |
2448 | 236 | # columns. Colorizing has an opening and closing set of unprintable characters | 236 | # columns. Colorizing has an opening and closing set of unprintable characters |
2449 | 237 | # that factor into formats len() calculations | 237 | # that factor into formats len() calculations |
2451 | 238 | STATUS_TMPL = "{name: <14}{entitled: <19}{status: <19}{description}" | 238 | STATUS_TMPL = "{name: <17}{entitled: <19}{status: <19}{description}" |
2452 | 239 | 239 | ||
2453 | 240 | 240 | ||
2454 | 241 | def colorize(string: str) -> str: | 241 | def colorize(string: str) -> str: |
2455 | diff --git a/uaclient/tests/test_cli_attach.py b/uaclient/tests/test_cli_attach.py | |||
2456 | index 75cd0e1..e568f5f 100644 | |||
2457 | --- a/uaclient/tests/test_cli_attach.py | |||
2458 | +++ b/uaclient/tests/test_cli_attach.py | |||
2459 | @@ -532,14 +532,14 @@ class TestActionAttach: | |||
2460 | 532 | assert expected == json.loads(fake_stdout.getvalue()) | 532 | assert expected == json.loads(fake_stdout.getvalue()) |
2461 | 533 | 533 | ||
2462 | 534 | @mock.patch("uaclient.contract.process_entitlement_delta") | 534 | @mock.patch("uaclient.contract.process_entitlement_delta") |
2464 | 535 | @mock.patch("uaclient.util.apply_series_overrides") | 535 | @mock.patch("uaclient.util.apply_contract_overrides") |
2465 | 536 | @mock.patch("uaclient.contract.UAContractClient.request_url") | 536 | @mock.patch("uaclient.contract.UAContractClient.request_url") |
2466 | 537 | @mock.patch("uaclient.jobs.update_messaging.update_apt_and_motd_messages") | 537 | @mock.patch("uaclient.jobs.update_messaging.update_apt_and_motd_messages") |
2467 | 538 | def test_attach_when_one_service_fails_to_enable( | 538 | def test_attach_when_one_service_fails_to_enable( |
2468 | 539 | self, | 539 | self, |
2469 | 540 | _m_update_messages, | 540 | _m_update_messages, |
2470 | 541 | m_request_url, | 541 | m_request_url, |
2472 | 542 | _m_apply_series_overrides, | 542 | _m_apply_contract_overrides, |
2473 | 543 | m_process_entitlement_delta, | 543 | m_process_entitlement_delta, |
2474 | 544 | _m_getuid, | 544 | _m_getuid, |
2475 | 545 | FakeConfig, | 545 | FakeConfig, |
2476 | diff --git a/uaclient/tests/test_cli_collect_logs.py b/uaclient/tests/test_cli_collect_logs.py | |||
2477 | index df6feba..accf283 100644 | |||
2478 | --- a/uaclient/tests/test_cli_collect_logs.py | |||
2479 | +++ b/uaclient/tests/test_cli_collect_logs.py | |||
2480 | @@ -124,8 +124,8 @@ class TestActionCollectLogs: | |||
2481 | 124 | ), | 124 | ), |
2482 | 125 | ] | 125 | ] |
2483 | 126 | 126 | ||
2486 | 127 | assert m_copy.call_count == 14 | 127 | assert m_copy.call_count == 15 |
2487 | 128 | assert redact.call_count == 14 | 128 | assert redact.call_count == 15 |
2488 | 129 | 129 | ||
2489 | 130 | 130 | ||
2490 | 131 | class TestParser: | 131 | class TestParser: |
2491 | diff --git a/uaclient/tests/test_cli_status.py b/uaclient/tests/test_cli_status.py | |||
2492 | index 125a896..1331955 100644 | |||
2493 | --- a/uaclient/tests/test_cli_status.py | |||
2494 | +++ b/uaclient/tests/test_cli_status.py | |||
2495 | @@ -24,6 +24,7 @@ RESPONSE_AVAILABLE_SERVICES = [ | |||
2496 | 24 | {"name": "esm-infra", "available": False}, | 24 | {"name": "esm-infra", "available": False}, |
2497 | 25 | {"name": "esm-apps", "available": True}, | 25 | {"name": "esm-apps", "available": True}, |
2498 | 26 | {"name": "fips-updates", "available": False}, | 26 | {"name": "fips-updates", "available": False}, |
2499 | 27 | {"name": "realtime-kernel", "available": False}, | ||
2500 | 27 | {"name": "ros", "available": False}, | 28 | {"name": "ros", "available": False}, |
2501 | 28 | {"name": "ros-updates", "available": False}, | 29 | {"name": "ros-updates", "available": False}, |
2502 | 29 | ] | 30 | ] |
2503 | @@ -68,41 +69,34 @@ RESPONSE_CONTRACT_INFO = { | |||
2504 | 68 | } | 69 | } |
2505 | 69 | 70 | ||
2506 | 70 | SIMULATED_STATUS = """\ | 71 | SIMULATED_STATUS = """\ |
2515 | 71 | SERVICE AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION | 72 | SERVICE AVAILABLE ENTITLED AUTO_ENABLED DESCRIPTION |
2516 | 72 | esm-infra no yes yes UA Infra: Extended Security\ | 73 | esm-infra no yes yes UA Infra: Extended Security Maintenance (ESM) |
2517 | 73 | Maintenance (ESM) | 74 | fips no no no NIST-certified core packages |
2518 | 74 | fips no no no NIST-certified core packages | 75 | fips-updates no no no NIST-certified core packages with priority security updates |
2519 | 75 | fips-updates no no no NIST-certified core packages\ | 76 | livepatch yes yes no Canonical Livepatch service |
2520 | 76 | with priority security updates | 77 | """ # noqa: E501 |
2513 | 77 | livepatch yes yes no Canonical Livepatch service | ||
2514 | 78 | """ | ||
2521 | 79 | 78 | ||
2522 | 80 | UNATTACHED_STATUS = """\ | 79 | UNATTACHED_STATUS = """\ |
2529 | 81 | SERVICE AVAILABLE DESCRIPTION | 80 | SERVICE AVAILABLE DESCRIPTION |
2530 | 82 | esm-infra no UA Infra: Extended Security Maintenance (ESM) | 81 | esm-infra no UA Infra: Extended Security Maintenance (ESM) |
2531 | 83 | fips no NIST-certified core packages | 82 | fips no NIST-certified core packages |
2532 | 84 | fips-updates no NIST-certified core packages with priority\ | 83 | fips-updates no NIST-certified core packages with priority security updates |
2533 | 85 | security updates | 84 | livepatch yes Canonical Livepatch service |
2528 | 86 | livepatch yes Canonical Livepatch service | ||
2534 | 87 | 85 | ||
2535 | 88 | This machine is not attached to a UA subscription. | 86 | This machine is not attached to a UA subscription. |
2536 | 89 | See https://ubuntu.com/advantage | 87 | See https://ubuntu.com/advantage |
2538 | 90 | """ | 88 | """ # noqa: E501 |
2539 | 91 | 89 | ||
2540 | 92 | ATTACHED_STATUS = """\ | 90 | ATTACHED_STATUS = """\ |
2554 | 93 | SERVICE ENTITLED STATUS DESCRIPTION | 91 | SERVICE ENTITLED STATUS DESCRIPTION |
2555 | 94 | esm-apps no {dash} UA Apps: Extended Security Maintenance\ | 92 | esm-apps no {dash} UA Apps: Extended Security Maintenance (ESM) |
2556 | 95 | (ESM) | 93 | esm-infra no {dash} UA Infra: Extended Security Maintenance (ESM) |
2557 | 96 | esm-infra no {dash} UA Infra: Extended Security Maintenance\ | 94 | fips no {dash} NIST-certified core packages |
2558 | 97 | (ESM) | 95 | fips-updates no {dash} NIST-certified core packages with priority security updates |
2559 | 98 | fips no {dash} NIST-certified core packages | 96 | livepatch no {dash} Canonical Livepatch service |
2560 | 99 | fips-updates no {dash} NIST-certified core packages with\ | 97 | realtime-kernel no {dash} Beta-version Ubuntu Kernel with PREEMPT_RT patches |
2561 | 100 | priority security updates | 98 | ros no {dash} Security Updates for the Robot Operating System |
2562 | 101 | livepatch no {dash} Canonical Livepatch service | 99 | ros-updates no {dash} All Updates for the Robot Operating System |
2550 | 102 | ros no {dash} Security Updates for the Robot\ | ||
2551 | 103 | Operating System | ||
2552 | 104 | ros-updates no {dash} All Updates for the Robot Operating\ | ||
2553 | 105 | System | ||
2563 | 106 | {notices} | 100 | {notices} |
2564 | 107 | Enable services with: ua enable <service> | 101 | Enable services with: ua enable <service> |
2565 | 108 | 102 | ||
2566 | @@ -110,17 +104,15 @@ Enable services with: ua enable <service> | |||
2567 | 110 | Subscription: test_contract | 104 | Subscription: test_contract |
2568 | 111 | Valid until: 2040-05-08 19:02:26+00:00 | 105 | Valid until: 2040-05-08 19:02:26+00:00 |
2569 | 112 | Technical support level: n/a | 106 | Technical support level: n/a |
2571 | 113 | """ | 107 | """ # noqa: E501 |
2572 | 114 | 108 | ||
2573 | 115 | # Omit beta services from status | 109 | # Omit beta services from status |
2574 | 116 | ATTACHED_STATUS_NOBETA = """\ | 110 | ATTACHED_STATUS_NOBETA = """\ |
2582 | 117 | SERVICE ENTITLED STATUS DESCRIPTION | 111 | SERVICE ENTITLED STATUS DESCRIPTION |
2583 | 118 | esm-infra no {dash} UA Infra: Extended Security Maintenance\ | 112 | esm-infra no {dash} UA Infra: Extended Security Maintenance (ESM) |
2584 | 119 | (ESM) | 113 | fips no {dash} NIST-certified core packages |
2585 | 120 | fips no {dash} NIST-certified core packages | 114 | fips-updates no {dash} NIST-certified core packages with priority security updates |
2586 | 121 | fips-updates no {dash} NIST-certified core packages with\ | 115 | livepatch no {dash} Canonical Livepatch service |
2580 | 122 | priority security updates | ||
2581 | 123 | livepatch no {dash} Canonical Livepatch service | ||
2587 | 124 | {notices} | 116 | {notices} |
2588 | 125 | Enable services with: ua enable <service> | 117 | Enable services with: ua enable <service> |
2589 | 126 | 118 | ||
2590 | @@ -128,9 +120,9 @@ Enable services with: ua enable <service> | |||
2591 | 128 | Subscription: test_contract | 120 | Subscription: test_contract |
2592 | 129 | Valid until: 2040-05-08 19:02:26+00:00 | 121 | Valid until: 2040-05-08 19:02:26+00:00 |
2593 | 130 | Technical support level: n/a | 122 | Technical support level: n/a |
2595 | 131 | """ | 123 | """ # noqa: E501 |
2596 | 132 | 124 | ||
2598 | 133 | BETA_SVC_NAMES = ["esm-apps", "ros", "ros-updates"] | 125 | BETA_SVC_NAMES = ["esm-apps", "realtime-kernel", "ros", "ros-updates"] |
2599 | 134 | 126 | ||
2600 | 135 | SERVICES_JSON_ALL = [ | 127 | SERVICES_JSON_ALL = [ |
2601 | 136 | { | 128 | { |
2602 | @@ -186,6 +178,16 @@ SERVICES_JSON_ALL = [ | |||
2603 | 186 | "blocked_by": [], | 178 | "blocked_by": [], |
2604 | 187 | }, | 179 | }, |
2605 | 188 | { | 180 | { |
2606 | 181 | "description": "TODO", | ||
2607 | 182 | "description_override": None, | ||
2608 | 183 | "entitled": "no", | ||
2609 | 184 | "name": "realtime-kernel", | ||
2610 | 185 | "status": "—", | ||
2611 | 186 | "status_details": "", | ||
2612 | 187 | "available": "yes", | ||
2613 | 188 | "blocked_by": [], | ||
2614 | 189 | }, | ||
2615 | 190 | { | ||
2616 | 189 | "description": "Security Updates for the Robot Operating System", | 191 | "description": "Security Updates for the Robot Operating System", |
2617 | 190 | "description_override": None, | 192 | "description_override": None, |
2618 | 191 | "entitled": "no", | 193 | "entitled": "no", |
2619 | @@ -739,6 +741,14 @@ class TestActionStatus: | |||
2620 | 739 | { | 741 | { |
2621 | 740 | "auto_enabled": "no", | 742 | "auto_enabled": "no", |
2622 | 741 | "available": "no", | 743 | "available": "no", |
2623 | 744 | "description": "Beta-version Ubuntu Kernel with PREEMPT_RT" | ||
2624 | 745 | " patches", | ||
2625 | 746 | "entitled": "no", | ||
2626 | 747 | "name": "realtime-kernel", | ||
2627 | 748 | }, | ||
2628 | 749 | { | ||
2629 | 750 | "auto_enabled": "no", | ||
2630 | 751 | "available": "no", | ||
2631 | 742 | "description": "Security Updates for the Robot Operating" | 752 | "description": "Security Updates for the Robot Operating" |
2632 | 743 | " System", | 753 | " System", |
2633 | 744 | "entitled": "no", | 754 | "entitled": "no", |
2634 | @@ -754,7 +764,7 @@ class TestActionStatus: | |||
2635 | 754 | ] | 764 | ] |
2636 | 755 | 765 | ||
2637 | 756 | if not use_all: | 766 | if not use_all: |
2639 | 757 | expected_services = expected_services[1:-2] | 767 | expected_services = expected_services[1:-3] |
2640 | 758 | 768 | ||
2641 | 759 | expected = { | 769 | expected = { |
2642 | 760 | "_doc": "Content provided in json response is currently considered" | 770 | "_doc": "Content provided in json response is currently considered" |
2643 | diff --git a/uaclient/tests/test_upgrade_lts_contract.py b/uaclient/tests/test_upgrade_lts_contract.py | |||
2644 | index 231fa17..7f76620 100644 | |||
2645 | --- a/uaclient/tests/test_upgrade_lts_contract.py | |||
2646 | +++ b/uaclient/tests/test_upgrade_lts_contract.py | |||
2647 | @@ -16,7 +16,7 @@ class TestUpgradeLTSContract: | |||
2648 | 16 | def test_unattached_noops(self, m_is_attached, capsys, caplog_text): | 16 | def test_unattached_noops(self, m_is_attached, capsys, caplog_text): |
2649 | 17 | expected_logs = [ | 17 | expected_logs = [ |
2650 | 18 | "Check whether to upgrade-lts-contract", | 18 | "Check whether to upgrade-lts-contract", |
2652 | 19 | "Skiping upgrade-lts-contract. Machine is unattached", | 19 | "Skipping upgrade-lts-contract. Machine is unattached", |
2653 | 20 | ] | 20 | ] |
2654 | 21 | 21 | ||
2655 | 22 | process_contract_delta_after_apt_lock() | 22 | process_contract_delta_after_apt_lock() |
2656 | @@ -67,6 +67,72 @@ class TestUpgradeLTSContract: | |||
2657 | 67 | ) | 67 | ) |
2658 | 68 | @mock.patch("lib.upgrade_lts_contract.parse_os_release") | 68 | @mock.patch("lib.upgrade_lts_contract.parse_os_release") |
2659 | 69 | @mock.patch("lib.upgrade_lts_contract.subp") | 69 | @mock.patch("lib.upgrade_lts_contract.subp") |
2660 | 70 | def test_upgrade_cancel_when_current_version_not_supported( | ||
2661 | 71 | self, m_subp, m_parse_os, m_is_attached, capsys, caplog_text | ||
2662 | 72 | ): | ||
2663 | 73 | m_parse_os.return_value = {"VERSION_ID": "NOT-SUPPORTED"} | ||
2664 | 74 | m_subp.return_value = ("", "") | ||
2665 | 75 | |||
2666 | 76 | expected_msgs = [ | ||
2667 | 77 | "Starting upgrade-lts-contract.", | ||
2668 | 78 | "Unable to get release codename for version: NOT-SUPPORTED", | ||
2669 | 79 | ] | ||
2670 | 80 | expected_logs = ["Check whether to upgrade-lts-contract"] | ||
2671 | 81 | with pytest.raises(SystemExit) as execinfo: | ||
2672 | 82 | process_contract_delta_after_apt_lock() | ||
2673 | 83 | |||
2674 | 84 | assert 1 == execinfo.value.code | ||
2675 | 85 | assert 1 == m_is_attached.call_count | ||
2676 | 86 | assert 1 == m_parse_os.call_count | ||
2677 | 87 | assert 1 == m_subp.call_count | ||
2678 | 88 | out, _err = capsys.readouterr() | ||
2679 | 89 | assert out == "\n".join(expected_msgs) + "\n" | ||
2680 | 90 | debug_logs = caplog_text() | ||
2681 | 91 | for log in expected_msgs + expected_logs: | ||
2682 | 92 | assert log in debug_logs | ||
2683 | 93 | |||
2684 | 94 | @mock.patch( | ||
2685 | 95 | "uaclient.config.UAConfig.is_attached", | ||
2686 | 96 | new_callable=mock.PropertyMock, | ||
2687 | 97 | return_value=True, | ||
2688 | 98 | ) | ||
2689 | 99 | @mock.patch("lib.upgrade_lts_contract.parse_os_release") | ||
2690 | 100 | @mock.patch("lib.upgrade_lts_contract.subp") | ||
2691 | 101 | def test_upgrade_cancel_when_past_version_not_supported( | ||
2692 | 102 | self, m_subp, m_parse_os, m_is_attached, capsys, caplog_text | ||
2693 | 103 | ): | ||
2694 | 104 | m_parse_os.return_value = {"VERSION_ID": "20.10"} | ||
2695 | 105 | m_subp.return_value = ("", "") | ||
2696 | 106 | |||
2697 | 107 | expected_msgs = [ | ||
2698 | 108 | "Starting upgrade-lts-contract.", | ||
2699 | 109 | "Could not find past release for: groovy", | ||
2700 | 110 | ] | ||
2701 | 111 | expected_logs = ["Check whether to upgrade-lts-contract"] | ||
2702 | 112 | with pytest.raises(SystemExit) as execinfo: | ||
2703 | 113 | with mock.patch( | ||
2704 | 114 | "lib.upgrade_lts_contract.version_to_codename", | ||
2705 | 115 | {"20.10": "groovy"}, | ||
2706 | 116 | ): | ||
2707 | 117 | process_contract_delta_after_apt_lock() | ||
2708 | 118 | |||
2709 | 119 | assert 1 == execinfo.value.code | ||
2710 | 120 | assert 1 == m_is_attached.call_count | ||
2711 | 121 | assert 1 == m_parse_os.call_count | ||
2712 | 122 | assert 1 == m_subp.call_count | ||
2713 | 123 | out, _err = capsys.readouterr() | ||
2714 | 124 | assert out == "\n".join(expected_msgs) + "\n" | ||
2715 | 125 | debug_logs = caplog_text() | ||
2716 | 126 | for log in expected_msgs + expected_logs: | ||
2717 | 127 | assert log in debug_logs | ||
2718 | 128 | |||
2719 | 129 | @mock.patch( | ||
2720 | 130 | "uaclient.config.UAConfig.is_attached", | ||
2721 | 131 | new_callable=mock.PropertyMock, | ||
2722 | 132 | return_value=True, | ||
2723 | 133 | ) | ||
2724 | 134 | @mock.patch("lib.upgrade_lts_contract.parse_os_release") | ||
2725 | 135 | @mock.patch("lib.upgrade_lts_contract.subp") | ||
2726 | 70 | @mock.patch("lib.upgrade_lts_contract.process_entitlements_delta") | 136 | @mock.patch("lib.upgrade_lts_contract.process_entitlements_delta") |
2727 | 71 | @mock.patch("lib.upgrade_lts_contract.time.sleep") | 137 | @mock.patch("lib.upgrade_lts_contract.time.sleep") |
2728 | 72 | def test_upgrade_contract_when_apt_lock_is_held( | 138 | def test_upgrade_contract_when_apt_lock_is_held( |
2729 | diff --git a/uaclient/tests/test_util.py b/uaclient/tests/test_util.py | |||
2730 | index 35bd8c0..99a7aa2 100644 | |||
2731 | --- a/uaclient/tests/test_util.py | |||
2732 | +++ b/uaclient/tests/test_util.py | |||
2733 | @@ -474,57 +474,244 @@ class TestGetPlatformInfo: | |||
2734 | 474 | assert expected == util.get_platform_info.__wrapped__() | 474 | assert expected == util.get_platform_info.__wrapped__() |
2735 | 475 | 475 | ||
2736 | 476 | 476 | ||
2738 | 477 | class TestApplySeriesOverrides: | 477 | class TestApplyContractOverrides: |
2739 | 478 | @pytest.mark.parametrize( | ||
2740 | 479 | "override_selector,expected_weight", | ||
2741 | 480 | ( | ||
2742 | 481 | ({"selector1": "valueX", "selector2": "valueZ"}, 0), | ||
2743 | 482 | ({"selector1": "valueA", "selector2": "valueZ"}, 0), | ||
2744 | 483 | ({"selector1": "valueX", "selector2": "valueB"}, 0), | ||
2745 | 484 | ({"selector1": "valueA"}, 1), | ||
2746 | 485 | ({"selector2": "valueB"}, 2), | ||
2747 | 486 | ({"selector1": "valueA", "selector2": "valueB"}, 3), | ||
2748 | 487 | ), | ||
2749 | 488 | ) | ||
2750 | 489 | def test_get_override_weight(self, override_selector, expected_weight): | ||
2751 | 490 | selector_values = {"selector1": "valueA", "selector2": "valueB"} | ||
2752 | 491 | selector_weights = {"selector1": 1, "selector2": 2} | ||
2753 | 492 | with mock.patch( | ||
2754 | 493 | "uaclient.util.OVERRIDE_SELECTOR_WEIGHTS", selector_weights | ||
2755 | 494 | ): | ||
2756 | 495 | assert expected_weight == util._get_override_weight( | ||
2757 | 496 | override_selector, selector_values | ||
2758 | 497 | ) | ||
2759 | 498 | |||
2760 | 478 | def test_error_on_non_entitlement_dict(self): | 499 | def test_error_on_non_entitlement_dict(self): |
2761 | 479 | """Raise a runtime error when seeing invalid dict type.""" | 500 | """Raise a runtime error when seeing invalid dict type.""" |
2762 | 480 | with pytest.raises(RuntimeError) as exc: | 501 | with pytest.raises(RuntimeError) as exc: |
2764 | 481 | util.apply_series_overrides({"some": "dict"}) | 502 | util.apply_contract_overrides({"some": "dict"}) |
2765 | 482 | error = ( | 503 | error = ( |
2766 | 483 | 'Expected entitlement access dict. Missing "entitlement" key:' | 504 | 'Expected entitlement access dict. Missing "entitlement" key:' |
2767 | 484 | " {'some': 'dict'}" | 505 | " {'some': 'dict'}" |
2768 | 485 | ) | 506 | ) |
2769 | 486 | assert error == str(exc.value) | 507 | assert error == str(exc.value) |
2770 | 487 | 508 | ||
2771 | 509 | @pytest.mark.parametrize("include_overrides", (True, False)) | ||
2772 | 488 | @mock.patch( | 510 | @mock.patch( |
2774 | 489 | "uaclient.util.get_platform_info", return_value={"series": "xenial"} | 511 | "uaclient.util.get_platform_info", return_value={"series": "ubuntuX"} |
2775 | 490 | ) | 512 | ) |
2778 | 491 | def test_mutates_orig_access_dict(self, _): | 513 | @mock.patch( |
2779 | 492 | """Mutate orig_access dict when called.""" | 514 | "uaclient.clouds.identity.get_cloud_type", return_value=(None, "") |
2780 | 515 | ) | ||
2781 | 516 | def test_return_same_dict_when_no_overrides_match( | ||
2782 | 517 | self, _m_cloud_type, _m_platform_info, include_overrides | ||
2783 | 518 | ): | ||
2784 | 493 | orig_access = { | 519 | orig_access = { |
2785 | 494 | "entitlement": { | 520 | "entitlement": { |
2789 | 495 | "a": {"a1": "av1", "a2": {"aa2": "aav2"}}, | 521 | "affordances": {"some_affordance": ["ubuntuX"]}, |
2790 | 496 | "b": "b1", | 522 | "directives": {"some_directive": ["ubuntuX"]}, |
2791 | 497 | "c": "c1", | 523 | "obligations": {"some_obligation": False}, |
2792 | 524 | } | ||
2793 | 525 | } | ||
2794 | 526 | # exactly the same | ||
2795 | 527 | expected = { | ||
2796 | 528 | "entitlement": { | ||
2797 | 529 | "affordances": {"some_affordance": ["ubuntuX"]}, | ||
2798 | 530 | "directives": {"some_directive": ["ubuntuX"]}, | ||
2799 | 531 | "obligations": {"some_obligation": False}, | ||
2800 | 532 | } | ||
2801 | 533 | } | ||
2802 | 534 | if include_overrides: | ||
2803 | 535 | orig_access["entitlement"].update( | ||
2804 | 536 | { | ||
2805 | 537 | "series": { | ||
2806 | 538 | "dontMatch": { | ||
2807 | 539 | "affordances": { | ||
2808 | 540 | "some_affordance": ["ubuntuX-series-overriden"] | ||
2809 | 541 | } | ||
2810 | 542 | } | ||
2811 | 543 | }, | ||
2812 | 544 | "overrides": [ | ||
2813 | 545 | { | ||
2814 | 546 | "selector": {"series": "dontMatch"}, | ||
2815 | 547 | "affordances": { | ||
2816 | 548 | "some_affordance": ["ubuntuX-series-overriden"] | ||
2817 | 549 | }, | ||
2818 | 550 | }, | ||
2819 | 551 | { | ||
2820 | 552 | "selector": {"cloud": "dontMatch"}, | ||
2821 | 553 | "affordances": { | ||
2822 | 554 | "some_affordance": ["ubuntuX-cloud-overriden"] | ||
2823 | 555 | }, | ||
2824 | 556 | }, | ||
2825 | 557 | ], | ||
2826 | 558 | } | ||
2827 | 559 | ) | ||
2828 | 560 | |||
2829 | 561 | util.apply_contract_overrides(orig_access) | ||
2830 | 562 | assert expected == orig_access | ||
2831 | 563 | |||
2832 | 564 | @mock.patch( | ||
2833 | 565 | "uaclient.util.get_platform_info", return_value={"series": "ubuntuX"} | ||
2834 | 566 | ) | ||
2835 | 567 | def test_missing_keys_are_included(self, _m_platform_info): | ||
2836 | 568 | orig_access = { | ||
2837 | 569 | "entitlement": { | ||
2838 | 570 | "series": {"ubuntuX": {"directives": {"suites": ["ubuntuX"]}}} | ||
2839 | 571 | } | ||
2840 | 572 | } | ||
2841 | 573 | expected = {"entitlement": {"directives": {"suites": ["ubuntuX"]}}} | ||
2842 | 574 | |||
2843 | 575 | util.apply_contract_overrides(orig_access) | ||
2844 | 576 | |||
2845 | 577 | assert expected == orig_access | ||
2846 | 578 | |||
2847 | 579 | @pytest.mark.parametrize( | ||
2848 | 580 | "series_selector,cloud_selector,series_cloud_selector,expected_value", | ||
2849 | 581 | ( | ||
2850 | 582 | # apply_overrides_when_only_series_match | ||
2851 | 583 | ("no-match", "no-match", "no-match", "old_series_overriden"), | ||
2852 | 584 | # series selector is applied over old series override | ||
2853 | 585 | ("ubuntuX", "no-match", "no-match", "series_overriden"), | ||
2854 | 586 | # cloud selector is applied over series override | ||
2855 | 587 | ("no-match", "cloudX", "no-match", "cloud_overriden"), | ||
2856 | 588 | # cloud selector is applied over series selector | ||
2857 | 589 | ("ubuntuX", "cloudX", "no-match", "cloud_overriden"), | ||
2858 | 590 | # cloud and series together are applied over others | ||
2859 | 591 | ("ubuntuX", "cloudX", "cloudX", "both_overriden"), | ||
2860 | 592 | ), | ||
2861 | 593 | ) | ||
2862 | 594 | @mock.patch( | ||
2863 | 595 | "uaclient.util.get_platform_info", return_value={"series": "ubuntuX"} | ||
2864 | 596 | ) | ||
2865 | 597 | @mock.patch( | ||
2866 | 598 | "uaclient.clouds.identity.get_cloud_type", | ||
2867 | 599 | return_value=("cloudX", None), | ||
2868 | 600 | ) | ||
2869 | 601 | def test_applies_contract_overrides_respecting_weight( | ||
2870 | 602 | self, | ||
2871 | 603 | _m_cloud_type, | ||
2872 | 604 | _m_platform_info, | ||
2873 | 605 | series_selector, | ||
2874 | 606 | cloud_selector, | ||
2875 | 607 | series_cloud_selector, | ||
2876 | 608 | expected_value, | ||
2877 | 609 | ): | ||
2878 | 610 | """Apply the expected overrides to orig_access dict when called.""" | ||
2879 | 611 | orig_access = { | ||
2880 | 612 | "entitlement": { | ||
2881 | 613 | "affordances": {"some_affordance": ["original_affordance"]}, | ||
2882 | 498 | "series": { | 614 | "series": { |
2885 | 499 | "trusty": {"a": "t1"}, | 615 | "ubuntuX": { |
2886 | 500 | "xenial": {"a": {"a2": {"aa2": "xxv2"}}, "b": "bx1"}, | 616 | "affordances": { |
2887 | 617 | "some_affordance": ["old_series_overriden"] | ||
2888 | 618 | } | ||
2889 | 619 | } | ||
2890 | 501 | }, | 620 | }, |
2891 | 621 | "overrides": [ | ||
2892 | 622 | { | ||
2893 | 623 | "selector": {"series": series_selector}, | ||
2894 | 624 | "affordances": { | ||
2895 | 625 | "some_affordance": ["series_overriden"] | ||
2896 | 626 | }, | ||
2897 | 627 | }, | ||
2898 | 628 | { | ||
2899 | 629 | "selector": {"cloud": cloud_selector}, | ||
2900 | 630 | "affordances": { | ||
2901 | 631 | "some_affordance": ["cloud_overriden"] | ||
2902 | 632 | }, | ||
2903 | 633 | }, | ||
2904 | 634 | { | ||
2905 | 635 | "selector": { | ||
2906 | 636 | "series": series_selector, | ||
2907 | 637 | "cloud": series_cloud_selector, | ||
2908 | 638 | }, | ||
2909 | 639 | "affordances": {"some_affordance": ["both_overriden"]}, | ||
2910 | 640 | }, | ||
2911 | 641 | ], | ||
2912 | 502 | } | 642 | } |
2913 | 503 | } | 643 | } |
2914 | 644 | |||
2915 | 504 | expected = { | 645 | expected = { |
2916 | 505 | "entitlement": { | 646 | "entitlement": { |
2920 | 506 | "a": {"a1": "av1", "a2": {"aa2": "xxv2"}}, | 647 | "affordances": {"some_affordance": [expected_value]} |
2918 | 507 | "b": "bx1", | ||
2919 | 508 | "c": "c1", | ||
2921 | 509 | } | 648 | } |
2922 | 510 | } | 649 | } |
2924 | 511 | util.apply_series_overrides(orig_access) | 650 | |
2925 | 651 | util.apply_contract_overrides(orig_access) | ||
2926 | 512 | assert orig_access == expected | 652 | assert orig_access == expected |
2927 | 513 | 653 | ||
2928 | 514 | @mock.patch( | 654 | @mock.patch( |
2930 | 515 | "uaclient.util.get_platform_info", return_value={"series": "xenial"} | 655 | "uaclient.util.get_platform_info", return_value={"series": "ubuntuX"} |
2931 | 656 | ) | ||
2932 | 657 | @mock.patch( | ||
2933 | 658 | "uaclient.clouds.identity.get_cloud_type", | ||
2934 | 659 | return_value=("cloudX", None), | ||
2935 | 516 | ) | 660 | ) |
2937 | 517 | def test_missing_keys_are_handled(self, _): | 661 | def test_different_overrides_applied_together( |
2938 | 662 | self, _m_cloud_type, _m_platform_info | ||
2939 | 663 | ): | ||
2940 | 664 | """Apply different overrides from different matching selectors.""" | ||
2941 | 518 | orig_access = { | 665 | orig_access = { |
2942 | 519 | "entitlement": { | 666 | "entitlement": { |
2944 | 520 | "series": {"xenial": {"directives": {"suites": ["xenial"]}}} | 667 | "affordances": {"some_affordance": ["original_affordance"]}, |
2945 | 668 | "directives": {"some_directive": ["original_directive"]}, | ||
2946 | 669 | "obligations": {"some_obligation": False}, | ||
2947 | 670 | "series": { | ||
2948 | 671 | "ubuntuX": { | ||
2949 | 672 | "affordances": { | ||
2950 | 673 | "new_affordance": ["new_affordance_value"] | ||
2951 | 674 | } | ||
2952 | 675 | } | ||
2953 | 676 | }, | ||
2954 | 677 | "overrides": [ | ||
2955 | 678 | { | ||
2956 | 679 | "selector": {"series": "ubuntuX"}, | ||
2957 | 680 | "affordances": { | ||
2958 | 681 | "some_affordance": ["series_overriden"] | ||
2959 | 682 | }, | ||
2960 | 683 | }, | ||
2961 | 684 | { | ||
2962 | 685 | "selector": {"cloud": "cloudX"}, | ||
2963 | 686 | "directives": {"some_directive": ["cloud_overriden"]}, | ||
2964 | 687 | }, | ||
2965 | 688 | { | ||
2966 | 689 | "selector": {"series": "ubuntuX", "cloud": "cloudX"}, | ||
2967 | 690 | "obligations": { | ||
2968 | 691 | "new_obligation": True, | ||
2969 | 692 | "some_obligation": True, | ||
2970 | 693 | }, | ||
2971 | 694 | }, | ||
2972 | 695 | ], | ||
2973 | 521 | } | 696 | } |
2974 | 522 | } | 697 | } |
2975 | 523 | expected = {"entitlement": {"directives": {"suites": ["xenial"]}}} | ||
2976 | 524 | 698 | ||
2978 | 525 | util.apply_series_overrides(orig_access) | 699 | expected = { |
2979 | 700 | "entitlement": { | ||
2980 | 701 | "affordances": { | ||
2981 | 702 | "new_affordance": ["new_affordance_value"], | ||
2982 | 703 | "some_affordance": ["series_overriden"], | ||
2983 | 704 | }, | ||
2984 | 705 | "directives": {"some_directive": ["cloud_overriden"]}, | ||
2985 | 706 | "obligations": { | ||
2986 | 707 | "new_obligation": True, | ||
2987 | 708 | "some_obligation": True, | ||
2988 | 709 | }, | ||
2989 | 710 | } | ||
2990 | 711 | } | ||
2991 | 526 | 712 | ||
2993 | 527 | assert expected == orig_access | 713 | util.apply_contract_overrides(orig_access) |
2994 | 714 | assert orig_access == expected | ||
2995 | 528 | 715 | ||
2996 | 529 | 716 | ||
2997 | 530 | class TestGetMachineId: | 717 | class TestGetMachineId: |
2998 | @@ -1263,13 +1450,18 @@ class TestShouldReboot: | |||
2999 | 1263 | assert 1 == m_load_file.call_count | 1450 | assert 1 == m_load_file.call_count |
3000 | 1264 | 1451 | ||
3001 | 1265 | @pytest.mark.parametrize( | 1452 | @pytest.mark.parametrize( |
3003 | 1266 | "installed_pkgs,reboot_required_pkgs,expected_ret", | 1453 | "installed_pkgs,installed_pkgs_regex,reboot_required_pkgs," |
3004 | 1454 | "expected_ret", | ||
3005 | 1267 | ( | 1455 | ( |
3011 | 1268 | (set(["a", "b", "c"]), "", False), | 1456 | (set(["a", "b", "c"]), None, "", False), |
3012 | 1269 | (set(["a", "b", "c"]), "a", True), | 1457 | (set(["a", "b", "c"]), None, "a", True), |
3013 | 1270 | (set(["a", "b", "c"]), "a\ne", True), | 1458 | (set(["a", "b", "c"]), None, "a\ne", True), |
3014 | 1271 | (set(["a", "b", "c"]), "d\ne", False), | 1459 | (set(["a", "b", "c"]), None, "d\ne", False), |
3015 | 1272 | (None, "a\ne", True), | 1460 | (set(["a", "b", "c"]), set(["t.."]), "a\ne", True), |
3016 | 1461 | (set(["a", "b", "c"]), set(["t.."]), "one\ntwo", True), | ||
3017 | 1462 | (None, set(["^t..$"]), "one\ntwo", True), | ||
3018 | 1463 | (None, set(["^t..$"]), "one\nthree", False), | ||
3019 | 1464 | (None, None, "a\ne", True), | ||
3020 | 1273 | ), | 1465 | ), |
3021 | 1274 | ) | 1466 | ) |
3022 | 1275 | @mock.patch("os.path.exists") | 1467 | @mock.patch("os.path.exists") |
3023 | @@ -1279,11 +1471,13 @@ class TestShouldReboot: | |||
3024 | 1279 | m_load_file, | 1471 | m_load_file, |
3025 | 1280 | m_path, | 1472 | m_path, |
3026 | 1281 | installed_pkgs, | 1473 | installed_pkgs, |
3027 | 1474 | installed_pkgs_regex, | ||
3028 | 1282 | reboot_required_pkgs, | 1475 | reboot_required_pkgs, |
3029 | 1283 | expected_ret, | 1476 | expected_ret, |
3030 | 1284 | ): | 1477 | ): |
3031 | 1285 | m_path.return_value = True | 1478 | m_path.return_value = True |
3032 | 1286 | m_load_file.return_value = reboot_required_pkgs | 1479 | m_load_file.return_value = reboot_required_pkgs |
3033 | 1287 | assert expected_ret == util.should_reboot( | 1480 | assert expected_ret == util.should_reboot( |
3035 | 1288 | installed_pkgs=installed_pkgs | 1481 | installed_pkgs=installed_pkgs, |
3036 | 1482 | installed_pkgs_regex=installed_pkgs_regex, | ||
3037 | 1289 | ) | 1483 | ) |
3038 | diff --git a/uaclient/util.py b/uaclient/util.py | |||
3039 | index 674f302..346f202 100644 | |||
3040 | --- a/uaclient/util.py | |||
3041 | +++ b/uaclient/util.py | |||
3042 | @@ -44,6 +44,8 @@ PROXY_VALIDATION_APT_HTTPS_URL = "https://esm.ubuntu.com" | |||
3043 | 44 | PROXY_VALIDATION_SNAP_HTTP_URL = "http://api.snapcraft.io" | 44 | PROXY_VALIDATION_SNAP_HTTP_URL = "http://api.snapcraft.io" |
3044 | 45 | PROXY_VALIDATION_SNAP_HTTPS_URL = "https://api.snapcraft.io" | 45 | PROXY_VALIDATION_SNAP_HTTPS_URL = "https://api.snapcraft.io" |
3045 | 46 | 46 | ||
3046 | 47 | OVERRIDE_SELECTOR_WEIGHTS = {"series_overrides": 1, "series": 2, "cloud": 3} | ||
3047 | 48 | |||
3048 | 47 | event = event_logger.get_event_logger() | 49 | event = event_logger.get_event_logger() |
3049 | 48 | 50 | ||
3050 | 49 | 51 | ||
3051 | @@ -100,7 +102,43 @@ class DatetimeAwareJSONDecoder(json.JSONDecoder): | |||
3052 | 100 | return o | 102 | return o |
3053 | 101 | 103 | ||
3054 | 102 | 104 | ||
3056 | 103 | def apply_series_overrides( | 105 | def _get_override_weight( |
3057 | 106 | override_selector: Dict[str, str], selector_values: Dict[str, str] | ||
3058 | 107 | ) -> int: | ||
3059 | 108 | override_weight = 0 | ||
3060 | 109 | for selector, value in override_selector.items(): | ||
3061 | 110 | if (selector, value) not in selector_values.items(): | ||
3062 | 111 | return 0 | ||
3063 | 112 | override_weight += OVERRIDE_SELECTOR_WEIGHTS[selector] | ||
3064 | 113 | |||
3065 | 114 | return override_weight | ||
3066 | 115 | |||
3067 | 116 | |||
3068 | 117 | def _select_overrides( | ||
3069 | 118 | entitlement: Dict[str, Any], series_name: str, cloud_type: str | ||
3070 | 119 | ) -> Dict[int, Dict[str, Any]]: | ||
3071 | 120 | overrides = {} | ||
3072 | 121 | |||
3073 | 122 | selector_values = {"series": series_name, "cloud": cloud_type} | ||
3074 | 123 | |||
3075 | 124 | series_overrides = entitlement.pop("series", {}).pop(series_name, {}) | ||
3076 | 125 | if series_overrides: | ||
3077 | 126 | overrides[ | ||
3078 | 127 | OVERRIDE_SELECTOR_WEIGHTS["series_overrides"] | ||
3079 | 128 | ] = series_overrides | ||
3080 | 129 | |||
3081 | 130 | general_overrides = entitlement.pop("overrides", []) | ||
3082 | 131 | for override in general_overrides: | ||
3083 | 132 | weight = _get_override_weight( | ||
3084 | 133 | override.pop("selector"), selector_values | ||
3085 | 134 | ) | ||
3086 | 135 | if weight: | ||
3087 | 136 | overrides[weight] = override | ||
3088 | 137 | |||
3089 | 138 | return overrides | ||
3090 | 139 | |||
3091 | 140 | |||
3092 | 141 | def apply_contract_overrides( | ||
3093 | 104 | orig_access: Dict[str, Any], series: str = None | 142 | orig_access: Dict[str, Any], series: str = None |
3094 | 105 | ) -> None: | 143 | ) -> None: |
3095 | 106 | """Apply series-specific overrides to an entitlement dict. | 144 | """Apply series-specific overrides to an entitlement dict. |
3096 | @@ -117,23 +155,30 @@ def apply_series_overrides( | |||
3097 | 117 | 155 | ||
3098 | 118 | :param orig_access: Dict with original entitlement access details | 156 | :param orig_access: Dict with original entitlement access details |
3099 | 119 | """ | 157 | """ |
3100 | 158 | from uaclient.clouds.identity import get_cloud_type | ||
3101 | 159 | |||
3102 | 120 | if not all([isinstance(orig_access, dict), "entitlement" in orig_access]): | 160 | if not all([isinstance(orig_access, dict), "entitlement" in orig_access]): |
3103 | 121 | raise RuntimeError( | 161 | raise RuntimeError( |
3104 | 122 | 'Expected entitlement access dict. Missing "entitlement" key:' | 162 | 'Expected entitlement access dict. Missing "entitlement" key:' |
3105 | 123 | " {}".format(orig_access) | 163 | " {}".format(orig_access) |
3106 | 124 | ) | 164 | ) |
3107 | 165 | |||
3108 | 125 | series_name = get_platform_info()["series"] if series is None else series | 166 | series_name = get_platform_info()["series"] if series is None else series |
3109 | 167 | cloud_type, _ = get_cloud_type() | ||
3110 | 126 | orig_entitlement = orig_access.get("entitlement", {}) | 168 | orig_entitlement = orig_access.get("entitlement", {}) |
3121 | 127 | overrides = orig_entitlement.pop("series", {}).pop(series_name, {}) | 169 | |
3122 | 128 | for key, value in overrides.items(): | 170 | overrides = _select_overrides(orig_entitlement, series_name, cloud_type) |
3123 | 129 | current = orig_access["entitlement"].get(key) | 171 | |
3124 | 130 | if isinstance(current, dict): | 172 | for _weight, overrides_to_apply in sorted(overrides.items()): |
3125 | 131 | # If the key already exists and is a dict, update that dict using | 173 | for key, value in overrides_to_apply.items(): |
3126 | 132 | # the override | 174 | current = orig_access["entitlement"].get(key) |
3127 | 133 | current.update(value) | 175 | if isinstance(current, dict): |
3128 | 134 | else: | 176 | # If the key already exists and is a dict, |
3129 | 135 | # Otherwise, replace it wholesale | 177 | # update that dict using the override |
3130 | 136 | orig_access["entitlement"][key] = value | 178 | current.update(value) |
3131 | 179 | else: | ||
3132 | 180 | # Otherwise, replace it wholesale | ||
3133 | 181 | orig_access["entitlement"][key] = value | ||
3134 | 137 | 182 | ||
3135 | 138 | 183 | ||
3136 | 139 | def del_file(path: str) -> None: | 184 | def del_file(path: str) -> None: |
3137 | @@ -431,13 +476,16 @@ def prompt_choices(msg: str = "", valid_choices: List[str] = []) -> str: | |||
3138 | 431 | return value | 476 | return value |
3139 | 432 | 477 | ||
3140 | 433 | 478 | ||
3142 | 434 | def prompt_for_confirmation(msg: str = "", assume_yes: bool = False) -> bool: | 479 | def prompt_for_confirmation( |
3143 | 480 | msg: str = "", assume_yes: bool = False, default: bool = False | ||
3144 | 481 | ) -> bool: | ||
3145 | 435 | """ | 482 | """ |
3146 | 436 | Display a confirmation prompt, returning a bool indicating the response | 483 | Display a confirmation prompt, returning a bool indicating the response |
3147 | 437 | 484 | ||
3148 | 438 | :param msg: String custom prompt text to emit from input call. | 485 | :param msg: String custom prompt text to emit from input call. |
3149 | 439 | :param assume_yes: Boolean set True to skip confirmation input and return | 486 | :param assume_yes: Boolean set True to skip confirmation input and return |
3150 | 440 | True. | 487 | True. |
3151 | 488 | :param default: Boolean to return when user doesn't enter any text | ||
3152 | 441 | 489 | ||
3153 | 442 | This function will only prompt a single time, and defaults to "no" (i.e. it | 490 | This function will only prompt a single time, and defaults to "no" (i.e. it |
3154 | 443 | returns False). | 491 | returns False). |
3155 | @@ -446,8 +494,10 @@ def prompt_for_confirmation(msg: str = "", assume_yes: bool = False) -> bool: | |||
3156 | 446 | return True | 494 | return True |
3157 | 447 | if not msg: | 495 | if not msg: |
3158 | 448 | msg = status.PROMPT_YES_NO | 496 | msg = status.PROMPT_YES_NO |
3161 | 449 | value = input(msg) | 497 | value = input(msg).lower().strip() |
3162 | 450 | if value.lower().strip() in ["y", "yes"]: | 498 | if value == "": |
3163 | 499 | return default | ||
3164 | 500 | if value in ["y", "yes"]: | ||
3165 | 451 | return True | 501 | return True |
3166 | 452 | return False | 502 | return False |
3167 | 453 | 503 | ||
3168 | @@ -756,14 +806,26 @@ def redact_sensitive_logs( | |||
3169 | 756 | return redacted_log | 806 | return redacted_log |
3170 | 757 | 807 | ||
3171 | 758 | 808 | ||
3173 | 759 | def should_reboot(installed_pkgs: Optional[Set[str]] = None) -> bool: | 809 | def should_reboot( |
3174 | 810 | installed_pkgs: Optional[Set[str]] = None, | ||
3175 | 811 | installed_pkgs_regex: Optional[Set[str]] = None, | ||
3176 | 812 | ) -> bool: | ||
3177 | 760 | """Check if the system needs to be rebooted. | 813 | """Check if the system needs to be rebooted. |
3178 | 761 | 814 | ||
3184 | 762 | :param installed_pkgs: If provided, verify if the any packages in | 815 | :param installed_pkgs: If provided, verify if the any packages in |
3185 | 763 | the list are present on /var/run/reboot-required.pkgs. If that | 816 | the list are present on /var/run/reboot-required.pkgs. If that |
3186 | 764 | param is provided, we will only return true if we have the | 817 | param is provided, we will only return true if we have the |
3187 | 765 | reboot-required marker file and any package in reboot-required.pkgs | 818 | reboot-required marker file and any package in reboot-required.pkgs |
3188 | 766 | file. | 819 | file. When both installed_pkgs and installed_pkgs_regex are |
3189 | 820 | provided, they act as an OR, so only one of the two lists must have | ||
3190 | 821 | a match to return True. | ||
3191 | 822 | :param installed_pkgs_regex: If provided, verify if the any regex in | ||
3192 | 823 | the list matches any line in /var/run/reboot-required.pkgs. If that | ||
3193 | 824 | param is provided, we will only return true if we have the | ||
3194 | 825 | reboot-required marker file and any match in reboot-required.pkgs | ||
3195 | 826 | file. When both installed_pkgs and installed_pkgs_regex are | ||
3196 | 827 | provided, they act as an OR, so only one of the two lists must have | ||
3197 | 828 | a match to return True. | ||
3198 | 767 | """ | 829 | """ |
3199 | 768 | 830 | ||
3200 | 769 | # If the reboot marker file doesn't exist, we don't even | 831 | # If the reboot marker file doesn't exist, we don't even |
3201 | @@ -773,7 +835,7 @@ def should_reboot(installed_pkgs: Optional[Set[str]] = None) -> bool: | |||
3202 | 773 | 835 | ||
3203 | 774 | # If there is no installed_pkgs to check, we will rely only | 836 | # If there is no installed_pkgs to check, we will rely only |
3204 | 775 | # on the existence of the reboot marker file | 837 | # on the existence of the reboot marker file |
3206 | 776 | if installed_pkgs is None: | 838 | if installed_pkgs is None and installed_pkgs_regex is None: |
3207 | 777 | return True | 839 | return True |
3208 | 778 | 840 | ||
3209 | 779 | try: | 841 | try: |
3210 | @@ -784,8 +846,18 @@ def should_reboot(installed_pkgs: Optional[Set[str]] = None) -> bool: | |||
3211 | 784 | # If the file doesn't exist, we will default to the | 846 | # If the file doesn't exist, we will default to the |
3212 | 785 | # reboot marker file | 847 | # reboot marker file |
3213 | 786 | return True | 848 | return True |
3216 | 787 | else: | 849 | |
3217 | 788 | return len(installed_pkgs.intersection(reboot_required_pkgs)) != 0 | 850 | if installed_pkgs is not None: |
3218 | 851 | if len(installed_pkgs.intersection(reboot_required_pkgs)) != 0: | ||
3219 | 852 | return True | ||
3220 | 853 | |||
3221 | 854 | if installed_pkgs_regex is not None: | ||
3222 | 855 | for pkg_name in reboot_required_pkgs: | ||
3223 | 856 | for pkg_regex in installed_pkgs_regex: | ||
3224 | 857 | if re.search(pkg_regex, pkg_name): | ||
3225 | 858 | return True | ||
3226 | 859 | |||
3227 | 860 | return False | ||
3228 | 789 | 861 | ||
3229 | 790 | 862 | ||
3230 | 791 | def is_installed(package_name: str) -> bool: | 863 | def is_installed(package_name: str) -> bool: |
3231 | diff --git a/uaclient/version.py b/uaclient/version.py | |||
3232 | index f65a60c..b99afa0 100644 | |||
3233 | --- a/uaclient/version.py | |||
3234 | +++ b/uaclient/version.py | |||
3235 | @@ -8,7 +8,7 @@ import os.path | |||
3236 | 8 | 8 | ||
3237 | 9 | from uaclient import exceptions, util | 9 | from uaclient import exceptions, util |
3238 | 10 | 10 | ||
3240 | 11 | __VERSION__ = "27.7" | 11 | __VERSION__ = "27.8" |
3241 | 12 | PACKAGED_VERSION = "@@PACKAGED_VERSION@@" | 12 | PACKAGED_VERSION = "@@PACKAGED_VERSION@@" |
3242 | 13 | VERSION_TMPL = "{version}{feature_suffix}" | 13 | VERSION_TMPL = "{version}{feature_suffix}" |
3243 | 14 | 14 |
+1 from an SRU perspective. I would like the usual QA done on this though. For a 0-day SRU, I'm not sure how this would work and have asked in #ubuntu-release. The upload can go in now though as it'll be held in Unapproved since it's seeded.