Merge ~orndorffgrant/ubuntu/+source/ubuntu-advantage-tools:upload-27.3-impish into ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel

Proposed by Grant Orndorff
Status: Approved
Approved by: Sergio Durigan Junior
Approved revision: 0ac54c3eb996b0f31c009490486ed4b42bbf997c
Proposed branch: ~orndorffgrant/ubuntu/+source/ubuntu-advantage-tools:upload-27.3-impish
Merge into: ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel
Diff against target: 14912 lines (+6589/-2545)
133 files modified
.gitignore (+42/-0)
.pre-commit-config.yaml (+4/-0)
Jenkinsfile (+8/-1)
README.md (+87/-6)
RELEASES.md (+239/-132)
debian/changelog (+74/-0)
debian/rules (+7/-3)
debian/ubuntu-advantage-tools.logrotate (+4/-1)
debian/ubuntu-advantage-tools.postinst (+77/-9)
debian/ubuntu-advantage-tools.postrm (+2/-0)
dev-requirements.txt (+3/-2)
features/_version.feature (+1/-2)
features/attach_invalidtoken.feature (+4/-4)
features/attach_validtoken.feature (+96/-204)
features/attached_commands.feature (+266/-76)
features/attached_enable.feature (+199/-6)
features/attached_status.feature (+29/-0)
features/aws-ids.yaml (+3/-3)
features/cloud.py (+111/-69)
features/enable_fips_cloud.feature (+606/-0)
features/enable_fips_vm.feature (+410/-0)
features/environment.py (+73/-86)
features/install_uninstall.feature (+46/-0)
features/license_check.feature (+120/-0)
features/proxy_config.feature (+7/-0)
features/staging_commands.feature (+2/-534)
features/steps/steps.py (+243/-46)
features/ubuntu_pro.feature (+27/-27)
features/ubuntu_upgrade.feature (+100/-13)
features/ubuntu_upgrade_unattached.feature (+91/-0)
features/unattached_commands.feature (+74/-24)
features/unattached_status.feature (+47/-15)
features/util.py (+90/-64)
help_data.yaml (+19/-1)
integration-requirements.txt (+1/-1)
lib/license_check.py (+28/-0)
lib/patch_status_json.py (+2/-2)
lib/reboot_cmds.py (+6/-7)
lib/timer.py (+121/-0)
lib/upgrade_lts_contract.py (+2/-2)
pyproject.toml (+4/-0)
setup.py (+1/-0)
sru/release-27.3/gcp_auto_attach_test.sh (+35/-0)
sru/release-27.3/ua-messaging-disabled.sh (+28/-0)
systemd/ua-license-check.path (+14/-0)
systemd/ua-license-check.service (+11/-0)
systemd/ua-license-check.timer (+12/-0)
systemd/ua-timer.service (+2/-3)
systemd/ua-timer.timer (+2/-3)
tools/refresh-aws-pro-ids (+15/-4)
tools/refresh-keyrings.sh (+4/-1)
tools/run-integration-tests.py (+191/-0)
tools/ua-test-credentials.example.yaml (+20/-0)
tox.ini (+13/-9)
uaclient-devel.conf (+5/-0)
uaclient.conf (+4/-0)
uaclient/apt.py (+5/-13)
uaclient/cli.py (+204/-75)
uaclient/clouds/__init__.py (+2/-7)
uaclient/clouds/aws.py (+3/-9)
uaclient/clouds/azure.py (+4/-11)
uaclient/clouds/gcp.py (+28/-10)
uaclient/clouds/identity.py (+24/-48)
uaclient/clouds/tests/test_aws.py (+1/-1)
uaclient/clouds/tests/test_azure.py (+3/-3)
uaclient/clouds/tests/test_gcp.py (+1/-1)
uaclient/clouds/tests/test_identity.py (+29/-74)
uaclient/config.py (+154/-62)
uaclient/conftest.py (+6/-10)
uaclient/contract.py (+68/-28)
uaclient/defaults.py (+4/-0)
uaclient/entitlements/__init__.py (+9/-13)
uaclient/entitlements/base.py (+221/-48)
uaclient/entitlements/cc.py (+3/-9)
uaclient/entitlements/cis.py (+3/-9)
uaclient/entitlements/esm.py (+8/-11)
uaclient/entitlements/fips.py (+59/-43)
uaclient/entitlements/livepatch.py (+17/-24)
uaclient/entitlements/repo.py (+28/-64)
uaclient/entitlements/ros.py (+28/-0)
uaclient/entitlements/tests/conftest.py (+23/-27)
uaclient/entitlements/tests/test_base.py (+150/-18)
uaclient/entitlements/tests/test_cc.py (+2/-4)
uaclient/entitlements/tests/test_cis.py (+2/-5)
uaclient/entitlements/tests/test_esm.py (+3/-5)
uaclient/entitlements/tests/test_fips.py (+82/-23)
uaclient/entitlements/tests/test_livepatch.py (+4/-13)
uaclient/entitlements/tests/test_repo.py (+2/-6)
uaclient/jobs/__init__.py (+14/-0)
uaclient/jobs/license_check.py (+62/-0)
uaclient/jobs/metering.py (+29/-0)
uaclient/jobs/tests/__init__.py (+0/-0)
uaclient/jobs/tests/test_gcp_auto_attach.py (+144/-0)
uaclient/jobs/update_messaging.py (+8/-24)
uaclient/jobs/update_state.py (+10/-0)
uaclient/pip.py (+0/-2)
uaclient/security.py (+63/-65)
uaclient/serviceclient.py (+78/-13)
uaclient/snap.py (+1/-2)
uaclient/status.py (+29/-15)
uaclient/tests/test_apt.py (+8/-9)
uaclient/tests/test_cli.py (+94/-11)
uaclient/tests/test_cli_attach.py (+6/-6)
uaclient/tests/test_cli_auto_attach.py (+10/-11)
uaclient/tests/test_cli_collect_logs.py (+135/-0)
uaclient/tests/test_cli_config_set.py (+32/-12)
uaclient/tests/test_cli_config_show.py (+8/-6)
uaclient/tests/test_cli_config_unset.py (+10/-8)
uaclient/tests/test_cli_detach.py (+7/-8)
uaclient/tests/test_cli_disable.py (+6/-7)
uaclient/tests/test_cli_enable.py (+15/-6)
uaclient/tests/test_cli_fix.py (+3/-4)
uaclient/tests/test_cli_refresh.py (+17/-19)
uaclient/tests/test_cli_status.py (+33/-13)
uaclient/tests/test_config.py (+75/-12)
uaclient/tests/test_contract.py (+58/-9)
uaclient/tests/test_gpg.py (+1/-0)
uaclient/tests/test_patch_status_json.py (+2/-2)
uaclient/tests/test_pip.py (+3/-3)
uaclient/tests/test_reboot_cmds.py (+6/-7)
uaclient/tests/test_security.py (+169/-110)
uaclient/tests/test_serviceclient.py (+110/-12)
uaclient/tests/test_snap.py (+0/-1)
uaclient/tests/test_status.py (+4/-3)
uaclient/tests/test_ua_timer.py (+138/-0)
uaclient/tests/test_update_messaging.py (+13/-14)
uaclient/tests/test_upgrade_lts_contract.py (+1/-0)
uaclient/tests/test_util.py (+72/-20)
uaclient/tests/test_version.py (+2/-3)
uaclient/types.py (+3/-0)
uaclient/util.py (+122/-69)
uaclient/version.py (+2/-2)
ubuntu-advantage.1 (+74/-3)
Reviewer Review Type Date Requested Status
Athos Ribeiro (community) Approve
Canonical Server Core Reviewers Pending
Review via email: mp+409097@code.launchpad.net

Description of the change

New release 27.3.

Sync upstream commits (and retain rich git commit history) with the following:

git rebase --onto pkg/ubuntu/devel 27.2.2 27.3 # 27.2.2 and 27.3 are upstream annotated tags in the upstream/release-27 branch at https://github.com/canonical/ubuntu-advantage-client/tree/release-27

Please see https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bug/1942929 for details of what is included in this release.

To post a comment you must log in.
304f2dd... by Renan Rodrigo

timer: set the frequency to 6h

Signed-off-by: Renan Rodrigo <email address hidden>

627d068... by Lucas Albuquerque Medeiros de Moura

postinst: make check for gce instance more robust

Currently, we have a check on postinst to verify
if we are on a gce cloud. We only verify if the gce
string is in the cloud-id of the instance. Therefore,
we are open to matching non-gce clouds that have the gce string
on their cloud-id. We are now updating this part of the code
to make the match more robust by verifying if the cloud-id starts
if the gce string.

38ae43f... by Grant Orndorff

license-check: add explanation to systemd units

446e0db... by Grant Orndorff

changelog: add missing LP bug refs for 27.3

1ae5f45... by Grant Orndorff

changelog: update ua-timer.timer frequency

0d23326... by Chad Smith

logs: update logrotate to glob capture all /var/log/ubuntu-advantage*log

Provide `su root root` to avoid messaging about parent directory perms
being insecure and allowing syslog group to write this file.

0c86d04... by Lucas Albuquerque Medeiros de Moura

postinst: mask ua-timer if ua-messaging disabled

If the user manually disabled ua-messaging we are now assuming
that the user want the same behavior for ua-timer as well. We are
now masking the ua-timer service if we detect that ua-messaging was
manually disabled by the user

c60f80a... by Chad Smith

logrotate: fix perms as root:root add ubuntu-advantage-timer.log

005567c... by Chad Smith

changelog

ea2cd37... by Lucas Albuquerque Medeiros de Moura

postrm: Remove extra ubuntu-advantage log on purge

69dbb6d... by Lucas Albuquerque Medeiros de Moura

logrotate: move su command inside log entry

05e8510... by Lucas Albuquerque Medeiros de Moura

postinst: properly configure extra logs

b8c3cbd... by Lucas Albuquerque Medeiros de Moura

postinst: check for systemd before using systemctl

0ac54c3... by Lucas Albuquerque Medeiros de Moura

changelog: fix lintian warning for long line

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

LGTM

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Thank you for the hard work, guys.

Uploaded:

$ dput ubuntu-advantage-tools_27.3~21.10.1_source.changes
Trying to upload package to ubuntu
Checking signature on .changes
gpg: /home/sergio/work/ubuntu-advantage-tools/ubuntu-advantage-tools_27.3~21.10.1_source.changes: Valid signature from 106DA1C8C3CBBF14
Checking signature on .dsc
gpg: /home/sergio/work/ubuntu-advantage-tools/ubuntu-advantage-tools_27.3~21.10.1.dsc: Valid signature from 106DA1C8C3CBBF14
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.3~21.10.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.3~21.10.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.3~21.10.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.3~21.10.1_source.changes: done.
Successfully uploaded packages.

f93544a... by Grant Orndorff

postinst: simplify disable_new_timer_if_old_timer_already_disabled

Unmerged commits

f93544a... by Grant Orndorff

postinst: simplify disable_new_timer_if_old_timer_already_disabled

0ac54c3... by Lucas Albuquerque Medeiros de Moura

changelog: fix lintian warning for long line

b8c3cbd... by Lucas Albuquerque Medeiros de Moura

postinst: check for systemd before using systemctl

05e8510... by Lucas Albuquerque Medeiros de Moura

postinst: properly configure extra logs

69dbb6d... by Lucas Albuquerque Medeiros de Moura

logrotate: move su command inside log entry

ea2cd37... by Lucas Albuquerque Medeiros de Moura

postrm: Remove extra ubuntu-advantage log on purge

0c86d04... by Lucas Albuquerque Medeiros de Moura

postinst: mask ua-timer if ua-messaging disabled

If the user manually disabled ua-messaging we are now assuming
that the user want the same behavior for ua-timer as well. We are
now masking the ua-timer service if we detect that ua-messaging was
manually disabled by the user

627d068... by Lucas Albuquerque Medeiros de Moura

postinst: make check for gce instance more robust

Currently, we have a check on postinst to verify
if we are on a gce cloud. We only verify if the gce
string is in the cloud-id of the instance. Therefore,
we are open to matching non-gce clouds that have the gce string
on their cloud-id. We are now updating this part of the code
to make the match more robust by verifying if the cloud-id starts
if the gce string.

005567c... by Chad Smith

changelog

c60f80a... by Chad Smith

logrotate: fix perms as root:root add ubuntu-advantage-timer.log

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2new file mode 100644
3index 0000000..97ab34b
4--- /dev/null
5+++ b/.gitignore
6@@ -0,0 +1,42 @@
7+artifacts/*
8+*debhelper*
9+debian/ubuntu-advantage-tools/
10+debian/ubuntu-advantage-tools.substvars
11+dev/entitlement-creds.json.*
12+*.pyc
13+*.pyo
14+__pycache__
15+.tox
16+.pybuild
17+.coverage
18+.cache
19+*.egg-info/
20+.mypy_cache/
21+
22+# Ignore artifacts generated by bddeb
23+*-1~bddeb*
24+ubuntu-advantage-tools_*.orig.tar.gz
25+ubuntu-advantage-tools_all.deb
26+ubuntu_advantage_tools.dsc
27+
28+# test/jenkins artifacts
29+pytest_results.xml
30+reports/
31+
32+# integration test artifacts
33+azure-priv-*.pem
34+azure-pub-*.txt
35+ec2-*.pem
36+gcp-pub-*
37+gcp-priv-*
38+lxd-*-uaclient-ci-*
39+build-from-source.sh
40+test-results*
41+
42+# credentials - don't commit credentials
43+tools/ua-test-credentials.yaml
44+
45+# apt-hook build artifacts
46+apt-hook/hook
47+apt-hook/ubuntu-advantage.pot
48+apt-hook/json-hook-src/json-hook
49diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
50index 0c6ffae..8bffa3e 100644
51--- a/.pre-commit-config.yaml
52+++ b/.pre-commit-config.yaml
53@@ -3,3 +3,7 @@ repos:
54 rev: 19.3b0 # Also stored in dev-requirements.txt; update both together!
55 hooks:
56 - id: black
57+ - repo: https://github.com/pycqa/isort
58+ rev: 5.8.0 # Also stored in dev-requirements.txt; update both together!
59+ hooks:
60+ - id: isort
61diff --git a/Jenkinsfile b/Jenkinsfile
62index 8723fde..17dfc00 100644
63--- a/Jenkinsfile
64+++ b/Jenkinsfile
65@@ -53,7 +53,7 @@ pipeline {
66 steps {
67 sh '''
68 set +x
69- tox -e black
70+ tox -e black -e isort
71 '''
72 }
73 }
74@@ -149,6 +149,8 @@ pipeline {
75 environment {
76 UACLIENT_BEHAVE_DEBS_PATH = "${TMPDIR}xenial/"
77 UACLIENT_BEHAVE_ARTIFACT_DIR = "artifacts/behave-lxd-16.04"
78+ UACLIENT_BEHAVE_EPHEMERAL_INSTANCE = 1
79+ UACLIENT_BEHAVE_SNAPSHOT_STRATEGY = 1
80 }
81 steps {
82 sh '''
83@@ -162,6 +164,8 @@ pipeline {
84 environment {
85 UACLIENT_BEHAVE_DEBS_PATH = "${TMPDIR}bionic/"
86 UACLIENT_BEHAVE_ARTIFACT_DIR = "artifacts/behave-lxd-18.04"
87+ UACLIENT_BEHAVE_EPHEMERAL_INSTANCE = 1
88+ UACLIENT_BEHAVE_SNAPSHOT_STRATEGY = 1
89 }
90 steps {
91 sh '''
92@@ -175,6 +179,8 @@ pipeline {
93 environment {
94 UACLIENT_BEHAVE_DEBS_PATH = "${TMPDIR}focal/"
95 UACLIENT_BEHAVE_ARTIFACT_DIR = "artifacts/behave-lxd-20.04"
96+ UACLIENT_BEHAVE_EPHEMERAL_INSTANCE = 1
97+ UACLIENT_BEHAVE_SNAPSHOT_STRATEGY = 1
98 }
99 steps {
100 sh '''
101@@ -188,6 +194,7 @@ pipeline {
102 environment {
103 UACLIENT_BEHAVE_DEBS_PATH = "${TMPDIR}focal/"
104 UACLIENT_BEHAVE_ARTIFACT_DIR = "artifacts/behave-vm-20.04"
105+ UACLIENT_BEHAVE_EPHEMERAL_INSTANCE = 1
106 }
107 steps {
108 sh '''
109diff --git a/README.md b/README.md
110index caac630..c2c236b 100644
111--- a/README.md
112+++ b/README.md
113@@ -9,6 +9,7 @@ following entitlements are supported:
114 - [Common Criteria EAL2 certification artifacts provisioning](https://ubuntu.com/cc-eal)
115 - [Canonical CIS Benchmark Audit Tool](https://ubuntu.com/cis-audit)
116 - [Ubuntu Extended Security Maintenance](https://ubuntu.com/esm)
117+- [Robot Operating System Extended Security Maintenance](https://ubuntu.com/robotics/ros-esm)
118 - [FIPS 140-2 Certified Modules](https://ubuntu.com/fips)
119 - [FIPS 140-2 Non-Certified Module Updates](https://ubuntu.com/fips)
120 - [Livepatch Service](https://www.ubuntu.com/livepatch)
121@@ -141,6 +142,49 @@ by a string formatted as:
122
123 `<protocol>://[<username>:<password>@]<fqdn>:<port>`
124
125+### Timer jobs
126+UA client sets up a systemd timer to run jobs that need to be executed recurrently.
127+The timer itself ticks every 5 minutes on average, and decides which jobs need
128+to be executed based on their _intervals_.
129+
130+Jobs are executed by the timer script if:
131+- The script has not yet run successfully, or
132+- Their interval since last successful run is already exceeded.
133+
134+There is a random delay applied to the timer, to desynchronize job execution time
135+on machines spinned at the same time, avoiding multiple synchronized calls to the
136+same service.
137+
138+Current jobs being checked and executed are:
139+
140+| Job | Description | Interval |
141+| --- | ----------- | -------- |
142+| update_messaging | Update MOTD and APT messages | 6 hours |
143+| update_status | Update UA status | 12 hours |
144+| gcp_auto_attach | Try to auto-attach on a GCP instance | 5 minutes |
145+
146+- The `update_messaging` job makes sure that the MOTD and APT messages match the
147+available/enabled services on the system, showing information about available
148+packages or security updates. See [MOTD messages](#motd-messages).
149+- The `update_status` job makes sure the `ua status` command will have the latest
150+information even when executed by a non-root user, updating the
151+`/var/lib/ubuntu-advantage/status.json` file.
152+- The `gcp_auto_attach` job is only operable on Google Cloud Platform (GCP) generic
153+Ubuntu VMs without an active Ubuntu Advantage license. It polls GCP metadata every 5
154+minutes to discover if a license has been attached to the VM through Google Cloud and
155+will perform `ua auto-attach` in that case.
156+
157+The timer intervals can be changed using the `ua config set` command.
158+```bash
159+# Make the update_status job run hourly
160+$ sudo ua config set update_status_timer=3600
161+```
162+Setting an interval to zero disables the job.
163+```bash
164+# Disable the update_status job
165+$ sudo ua config set update_status_timer=0
166+```
167+
168 ## Directory layout
169 The following describes the intent of UA client related directories:
170
171@@ -162,6 +206,20 @@ The following describes the intent of UA client related directories:
172 | /var/log/ubuntu-advantage.log | `root` read-only log of ubuntu-advantage operations |
173
174
175+## Collecting logs
176+The `ua collect-logs` command creates a tarball with all relevant data for debugging possible problems with UA. It puts together:
177+- The UA Client configuration file (the default is `/etc/ubuntu-advantage/uaclient.conf`)
178+- The UA Client log files (the default is `/var/log/ubuntu-advantage*`)
179+- The files in `/etc/apt/sources.list.d/*` related to UA
180+- Output of `systemctl status` for the UA Client related services
181+- Status of the timer jobs, `canonical-livepatch`, and the systemd timers
182+- Output of `cloud-id`, `dmesg` and `journalctl`
183+
184+Files with sensitive data are not included in the tarball. As of now, the command must be run as root.
185+
186+Running the command creates a `ua_logs.tar.gz` file in the current directory.
187+The output file path/name can be changed using the `-o` option.
188+
189 ## Testing
190
191 All unit and lint tests are run using `tox`. We also use `tox-pip-version` to specify an older pip version as a workaround: we have some required dependencies that can't meet the strict compatibility checks of current pip versions.
192@@ -288,6 +346,25 @@ you need to add `-D reuse_container=container_name`:
193 tox -e behave -D reuse_container=container_name
194 ```
195
196+#### Optimizing total run time of integration tests with snapshots
197+When `UACLIENT_BEHAVE_SNAPSHOT_STRATEGY=1` we create a snapshot of an instance
198+with ubuntu-advantage-tools installed and restore from that snapshot for all tests.
199+This adds an upfront cost that is amortized across several test scenarios.
200+
201+Based on some rough testing in July 2021, these are the situations
202+when you should set UACLIENT_BEHAVE_SNAPSHOT_STRATEGY=1
203+
204+> At time of writing, starting a lxd.vm instance from a local snapshot takes
205+> longer than starting a fresh lxd.vm instance and installing ua.
206+
207+| machine_type | condition |
208+| ------------- | ------------------ |
209+| lxd.container | num_scenarios > 7 |
210+| lxd.vm | never |
211+| gcp* | num_scenarios > 5 |
212+| azure* | num_scenarios > 14 |
213+| aws* | num_scenarios > 11 |
214+
215 #### Integration testing on EC2
216 The following tox environments allow for testing focal on EC2:
217
218@@ -394,11 +471,12 @@ ua version
219 # Make apt aware of the ESM source files
220 sudo apt update
221 # Generates ubuntu-advantage-tools messages that should be delivered to MOTD
222-# This script is trigged by a systemd timer once a day. To test it, we need to
223-# enforce that it was already executed.
224-sudo systemctl start ua-messaging.service
225+# This script is triggered by the systemd timer 4 times a day. To test it, we need
226+# to enforce that it was already executed.
227+sudo systemctl start ua-timer.service
228 # Force updating MOTD messages related to update-notifier
229-/usr/lib/update-notifier/update-motd-updates-available --force
230+sudo rm /var/lib/ubuntu-advantage/jobs-status.json
231+sudo python3 /usr/lib/ubuntu-advantage/timer.py
232 # Update MOTD and display the message
233 run-parts /etc/update-motd.d/
234 ```
235@@ -449,12 +527,15 @@ multipass connect dev-f
236 ## Code Formatting
237
238 The `ubuntu-advantage-client` code base is formatted using
239-[black](https://github.com/psf/black). When making changes, you should
240-ensure that your code is blackened, or it will be rejected by CI.
241+[black](https://github.com/psf/black), and imports are sorted with
242+[isort](https://github.com/PyCQA/isort). When making changes, you
243+should ensure that your code is blackened and isorted, or it will
244+be rejected by CI.
245 Formatting the whole codebase is as simple as running:
246
247 ```shell
248 black uaclient/
249+isort uaclient/
250 ```
251
252 To make it easier to avoid committing incorrectly formatted code, this
253diff --git a/RELEASES.md b/RELEASES.md
254index 261ec7a..a48b607 100644
255--- a/RELEASES.md
256+++ b/RELEASES.md
257@@ -1,6 +1,10 @@
258 # Ubuntu Advantage Client Releases
259
260-## Release versioning schemes:
261+## Supported Ubuntu Releases
262+
263+See the table under "Support Matrix for the client" in the [readme](./README.md).
264+
265+## Release versioning schemes
266
267 Below are the versioning schemes used for publishing debs:
268
269@@ -22,148 +26,251 @@ Below are the versioning schemes used for publishing debs:
270 | Ubuntu PRO to latest <series>-updates | `20.3+202004011202~ubuntu1~14.04.1` -> `20.4~ubuntu1~14.04.1` |
271 | Ubuntu PRO to Daily PPA | `20.3+202004011202~ubuntu1~14.04.1` -> `20.4+202004021202~ubuntu1~14.04.1` |
272
273-## Devel Release Process
274-
275-Below is the procedure used to release ubuntu-advantage-client to an Ubuntu series. It makes the following assumptions:
276-* The current ubuntu devel release is impish
277-* We are releasing version 27.1
278-* The previous release was 27.0.2
279-* The commits for 27.0.2 and 27.1 on https://github.com/canonical/ubuntu-advantage-client are tagged with `27.0.2` and `27.1` respectively.
280- * These tags should be on the correct commits on the `release-27` branch
281- * `27.1`, which is the tag of the release we are making, has not yet been uploaded to `pkg/ubuntu/devel`
282-
283- 1. git-ubuntu clone ubuntu-advantage-tools; cd ubuntu-advantage-tools
284- 2. git remote add upstream git@github.com:canonical/ubuntu-advantage-client.git
285- 3. git fetch upstream
286- 4. git rebase --onto pkg/ubuntu/devel 27.0.2 27.1
287- 5. git checkout -B upload-27.1-impish # to create a new local branch name based on your detached branch in step 4
288- 6. Make sure the changelog version contains the release version on the name (For example, 27.1~21.10.1)
289- 7. git push `<your_launchpad_user>` upload-27.1-impish
290- 8. Create a PPA for upload reviewers at `https://launchpad.net/~<YOUR_LP_USER>/+activate-ppa`
291- 9. Push to your test PPA so upload reviewers can easily install and test packages during review
292- ```bash
293- debuild -S
294- dput ppa:<YOUR_LAUNCHPAD_USER>/ua-client-uploads ./ubuntu-advantage-tools_*_source.changes
295-```
296- 10. Create a merge proposal for 27.1 which targets `ubuntu/devel`
297- * For an example, see the [27.0.2 merge proposal](https://code.launchpad.net/~chad.smith/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/+merge/402459)
298- 11. Add 2 review slots for `canonical-server` and `canonical-server-core-reviewers`
299-
300-## SRU Release Process
301-Below is the procedure used to SRU ubuntu-advantage-client to a stable Ubuntu series. It makes the following assumptions:
302-* The procedure for the Devel Release Process has just completed
303-* A local git branch representing the MP most recently released to the Ubuntu devel release is `upload-27.1-impish`
304-
305- 1. Create an "upload a new version bug" in https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bugs
306- * Describe the need, provide testing PPA and describe test instructions
307- * For examples, see [27.0](https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bug/1926361) or [20.3](https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bug/1869980)
308- 2. Create a PR for each target series based off your local `release-${UA_VERSION}-impish` branch:
309- ```bash
310- UA_VERSION=<UA-VERSION>
311- SRU_BUG=<SRU-BUG>
312- LP_USER=<LAUNCHPAD-USERNAME>
313-
314- for release in xenial bionic focal groovy hirsute
315- do
316- rm -rf ../out
317- rm ubuntu-advantage-*
318- git checkout upload-${UA_VERSION}-impish -B upload-${UA_VERSION}-$release
319- case "${release}" in
320- xenial) version=${UA_VERSION}~16.04.1;;
321- bionic) version=${UA_VERSION}~18.04.1;;
322- focal) version=${UA_VERSION}~20.04.1;;
323- groovy) version=${UA_VERSION}~20.10.1;;
324- hirsute) version=${UA_VERSION}~21.04.1;;
325- esac
326- dch -v ${version} -D ${release} -b "Backport new upstream release: (LP: #${SRU_BUG}) to $release"
327- git commit -m "changelog backport to ${release}" debian/changelog
328- build-package # to create release-specific dsc files used to upload in step 16
329- sbuild-it ../out/ubuntu-*.dsc
330- git push $LP_USER upload-${UA_VERSION}-$release
331- done
332- ```
333- 3. Create merge proposals for each SRU target release @ `https://code.launchpad.net/~<YOUR_LP_USER></YOUR_LAUNCHPAD_USER>/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/`. Make sure each PR targets your `upload-${UA_VERSION}-impish` branch.
334- 4. Add both `canonical-server` and `canonical-server-core-reviewers` as review slots on the MP.
335- 5. Upload each release (including impish) to `ppa:ua-client/staging`
336- ```bash
337- for changes_file in ../out/*changes; do
338- dput ppa:ua-client/staging $changes_file
339- done
340- ```
341- 6. Ping ~Server channel member with upload rights for a review of your MR
342- 7. Address MR review comments or file issues for future until MR accepted and uploaded to the [proper upload release queue](https://launchpad.net/ubuntu/hirsute/+queue?queue_state=1&queue_text=ubuntu-advantage-tools)
343- 8. Ping [appropriate daily SRU vanguard for acceptance of ua-tools into -proposed](https://wiki.ubuntu.com/StableReleaseUpdates#Publishing)FreeNode #ubuntu-release
344- 9. Once [ubuntu-advantage-tools shows up in the pending_sru page](https://people.canonical.com/~ubuntu-archive/pending-sru.html), perform the [Ubuntu-advantage-client SRU verification steps](https://wiki.ubuntu.com/UbuntuAdvantageToolsUpdates)
345-10. When SRU verification is complete, mark any SRU-related bugs with 'verification-done' tags as each bug, task, or release verified and completes successfully
346-11. Once all SRU bugs are tagged as `verification*-done`, all SRU-bugs should be listed as green in [the pending_sru page](https://people.canonical.com/~ubuntu-archive/pending-sru.html). It is now time to ping the [current SRU vanguard](https://wiki.ubuntu.com/StableReleaseUpdates#Publishing) for acceptance of ubuntu-advantage-tools into -updates
347+## Process
348
349-## Ubuntu PRO Release Process
350
351-Below is the procedure used to release ubuntu-advantage-tools to Ubuntu PRO images:
352+### Background
353
354- 1. [Open Daily PPA copy-package operation](https://code.launchpad.net/~ua-client/+archive/ubuntu/daily/+copy-packages)
355- 2. Check Trusty, Xenial, Bionic package
356- 3. Select Destination PPA: UA Client Premium [~ua-client/ubuntu/staging]
357- 4. Select Destination series: The same series
358- 5. Copy options: "Copy existing binaries"
359- 6. Click Copy packages
360- 7. Notify Pro Image creators about expected Premium PPA version (patviafore/rcj/powersj)
361+The release process for ubuntu-advantage-tools has three overarching steps/goals.
362+
363+1. Release to our team infrastructure. This includes Github and the `ua-client` PPAs.
364+2. Release to the latest ubuntu devel release.
365+3. Release to the supported ubuntu past releases via [SRU](https://wiki.ubuntu.com/StableReleaseUpdates) using the [ubuntu-advantage-tools specific SRU process](https://wiki.ubuntu.com/UbuntuAdvantageToolsUpdates).
366
367+Generally speaking, these steps happen in order, but there is some overlap. Also we may backtrack if issues are found part way through the process.
368
369-## Release to PPA
370+An average release should take somewhere between 10 and 14 calendar days if things go smoothly, starting at the decision to release and ending at the new version being available in all supported ubuntu releases. Note that it is not 2 weeks of full time work. Most of the time is spent waiting for review or sitting in proposed.
371
372-We manually upload the packages to our staging/stable PPAs. If you want to cut a new release and
373-upload to one of these PPAs, follow these steps:
374+### Prerequisites
375+
376+If this is your first time releasing ubuntu-advantage-tools, you'll need to do the following before getting started:
377+
378+* Add the team helper scripts to your PATH: [uss-tableflip](https://github.com/canonical/uss-tableflip).
379+* If you don't yet have a gpg key set up, follow the instructions
380+ [here](https://help.launchpad.net/YourAccount/ImportingYourPGPKey) to create a key,
381+ publish it to `hkp://keyserver.ubuntu.com`, and import it into Launchpad.
382+* Before you run `sbuild-it` for the first time, you'll need to set up a chroot for each Ubuntu release.
383+ Follow [these instructions](https://gist.github.com/smoser/14df5f0cd621e10d2282d7c90345e322#new-sbuild-creation)
384+ to create a chroot for each supported release.
385+* You must have launchpad already properly configured in your system in order to upload packages to the PPAs. Follow [this guide](https://help.launchpad.net/Packaging/PPA/Uploading) to get set up.
386+
387+### I. Preliminary/staging release to team infrastructure
388+1. Create a release PR
389+
390+ a. Move the desired commits from our `main` branch onto the desired release branch
391+
392+ * This step is currently not well defined. We currently are using `release-27` for all `27.X` releases and have been cherry-picking/rebasing all commits from `main` into this branch for a release.
393+
394+ b Create a new entry in the `debian/changelog` file:
395
396- 1. Do a `git cherry-pick` on the commits that should be included in the release
397- 2. Update the debian/changelog file:
398- * Create a new entry in the `debian/changelog` file:
399 * You can do that by running ` dch --newversion <version-name>`
400- * Remember to update the release from `UNRELEASED` to the most recently supported
401- ubuntu release
402- * Populate `debian/changelog` with the commits you have cherry-picked
403+ * Remember to update the release from `UNRELEASED` to the ubuntu/devel release. Edit the version to look like: `27.2~21.10.1`, with the appropriate ua and ubuntu/devel version numbers.
404+ * Populate `debian/changelog` with the commits you have cherry-picked
405 * You can do that by running `git log <first-cherry-pick-commit>..<last-cherry-pick-commit> | log2dch`
406- * This will generate a list of commits that could be included in the changelog. If you don't
407- have `log2dch`, you can get it from the [uss-tableflip](https://github.com/canonical/uss-tableflip)
408+ * This will generate a list of commits that could be included in the changelog.
409 * You don't need to include all of the commits generated. Remember that the changelog should
410 be read by the user to understand the new features/modifications in the package. If you
411 think a commit will not add that much to the user experience, you can drop it from the
412 changelog
413- * To structure the changelog you can use the other entries as example. But we basically try
414- keep this order: debian changes, new features/modifications, testing
415- 3. Start building the package:
416- * *WARNING* Build the package in a clean environment. The reason for that is because the package
417- will contain everything that it is present in the folder. If you are storing credentials or
418- other sensible development information in your folder, they will be uploaded too when we send
419- the package to the ppa. A clean environment is the safest way to perform this.
420- * Build the necessary artifacts that allow building the package
421- * Guarantee that you have a gpg key in the system. You will use that gpg key to sign the
422- package.
423- * If you don't yet have a gpg key set up, follow the instructions
424- [here](https://help.launchpad.net/YourAccount/ImportingYourPGPKey) to create a key,
425- publish it to `hkp://keyserver.ubuntu.com`, and import it into Launchpad.
426- * We can achieve that by running the `build-package` command when your current folder is the
427- top of source tree. This script is also found on the [uss-tableflip](https://github.com/canonical/uss-tableflip) repo.
428+ * To structure the changelog you can use the other entries as example. But we basically try to
429+ keep this order: debian changes, new features/modifications, testing. Within each section, bullet points should be alphabetized.
430+
431+ c. Create a PR on github into the release branch. Ask in the UA channel on mattermost for review.
432+
433+ d. When reviewing the release PR, please use the following guidelines when reviewing the new changelog entry:
434+
435+ * Is the version correctly updated ? We must ensure that the new version on the changelog is
436+ correct and it also targets the latest Ubuntu release at the moment.
437+ * Is the entry useful for the user ? The changelog entries should be user focused, meaning
438+ that we should only add entries that we think users will care about (i.e. we don't need
439+ entries when fixing a test, as this doesn't provide meaningful information to the user)
440+ * Is this entry redundant ? Sometimes we may have changes that affect separate modules of the
441+ code. We should have an entry only for the module that was most affected by it
442+ * Is the changelog entry unique ? We need to verify that the changelog entry is not already
443+ reflected in an earlier version of the changelog. If it is, we need not only to remove but double
444+ check the process we are using to cherry-pick the commits
445+ * Is this entry actually reflected on the code ? Sometimes, we can have changelog entries
446+ that are not reflected in the code anymore. This can happen during development when we are
447+ still unsure about the behavior of a feature or when we fix a bug that removes the code
448+ that was added. We must verify each changelog entry that is added to be sure of their
449+ presence in the product.
450+
451+2. After the release PR is merged, tag the head of the release branch with the version number, e.g. `27.1`. Push this tag to Github.
452+
453+3. Build the package for all Ubuntu releases and upload to `ppa:ua-client/staging`
454+
455+ a. Clone the repository in a clean directory and switch to the release branch
456+ * *WARNING* Build the package in a clean environment. The reason for that is because the package
457+ will contain everything that it is present in the folder. If you are storing credentials or
458+ other sensible development information in your folder, they will be uploaded too when we send
459+ the package to the ppa. A clean environment is the safest way to perform this.
460+
461+ b. Edit the changelog:
462+ * List yourself as the author of this release.
463+ * Edit the version number to look like: `27.2~20.04.1-rc1` (`<version>~<ubuntu-release-number>.<revno>-rc<release-candidate-number>`)
464+ * Edit the ubuntu release name. Start with the ubuntu/devel release (e.g. `impish`).
465+ * `git commit -m "throwaway"` Do **not** push this commit!
466+
467+ c. `build-package`
468 * This script will generate all the package artifacts in the parent directory as `../out`.
469- * Verify if we can build the package:
470- * We can achieve that by running the `sbuild-it` command. This script is also found on the
471- [uss-tableflip](https://github.com/canonical/uss-tableflip) repo.
472- * Before you run `sbuild-it` for the first time, you'll need to set up a chroot for each Ubuntu release.
473- Follow [these instructions](https://gist.github.com/smoser/14df5f0cd621e10d2282d7c90345e322#new-sbuild-creation)
474- to create a chroot for each supported release.
475- * To use it, you can just run `sbuild-it ../out/<package_name>.dsc
476- * If the package was built sucessfully, you can move to the next step.
477- 4. Repeat that for older ubuntu releases:
478- * Currently, we test this build process for `Trusty(14.04)`, `Xenial(16.04)`, `Bionic(18.04)`,
479- `Focal(20.10)`, `Groovy(20.10)` and `Hirsute(21.04)`
480- * To test this other releases, just change the changelog to target those releases.
481- PS: remember to also change the version number on the changelog. For example, suppose
482- the new version is `1.1~20.04.1`. If you want to test Bionic now, change it to
483- `1.1~18.04.1`.
484- * Commit those changes and perform the `build-package` and `sbuild-it` steps for the release.
485- * These commits are just local commits for this build process - do not push them to remote repository.
486- 5. After all of the releases are tested, we can start uploading to the ppa. For each release, run
487- the command `dput ppa:ua-client/stable ../out/<package_name>_source.changes`
488- * Run this command for each release you are going to upload
489- * Remember to have launchpad already properly configured in your system to allow you uploading
490- packages to the ppa.
491+
492+ d. `sbuild-it ../out/<package_name>.dsc`
493+ * If this succeeds move on. If this fails, debug and fix before continuing.
494+
495+ e. Repeat 3.b through 3.d for all supported Ubuntu Releases
496+ * PS: remember to also change the version number on the changelog. For example, suppose
497+ the new version is `1.1~20.04.1-rc1`. If you want to test Bionic now, change it to
498+ `1.1~18.04.1-rc1`.
499+
500+ f. For each release, dput to the staging PPA:
501+ * `dput ppa:ua-client/staging ../out/<package_name>_source.changes`
502+ * After each `dput` wait for the "Accepted" email from Launchpad before moving on.
503+
504+### II. Release to Ubuntu (devel and SRU)
505+
506+> Note: `impish` is used throughout as a reference to the current devel release. This will change.
507+
508+1. Prepare SRU Launchpad bugs.
509+
510+ a. We do this even before a succesful merge into ubuntu/devel because the context added to these bugs is useful for the Server Team reviewer.
511+
512+ b. Create a new bug on Launchpad for ubuntu-advantage-tools and use the format defined [here](https://wiki.ubuntu.com/UbuntuAdvantageToolsUpdates#SRU_Template) for the description.
513+ * The title should be in the format `[SRU] ubuntu-advantage-tools (27.1 -> 27.2) Xenial, Bionic, Focal, Hirsute`, substituting version numbers and release names as necessary.
514+
515+ c. For each Launchpad bug fixed by this release (which should all be referenced in our changelog), add the SRU template to the description and fill out each section.
516+ * Leave the original description in the bug at the bottom under the header `[Original Description]`.
517+ * For the testing steps, include steps to reproduce the bug. Then include instructions for adding `ppa:ua-client/staging`, and steps to verify the bug is no longer present.
518+
519+2. Set up the Merge Proposal (MP) for ubuntu/devel
520+
521+ a. `git-ubuntu clone ubuntu-advantage-tools; cd ubuntu-advantage-tools`
522+
523+ b. `git remote add upstream git@github.com:canonical/ubuntu-advantage-client.git`
524+
525+ c. `git fetch upstream`
526+
527+ d. `git rebase --onto pkg/ubuntu/devel <last-version-tag> <this-version-tag>`
528+ * e.g. `git rebase --onto pkg/ubuntu/devel 27.0.2 27.1`
529+ * You may need to resolve conflicts, but hopefully these will be minimal.
530+ * You'll end up in a detached state
531+
532+ e. `git checkout -B upload-<this-version>-impish`
533+ * This creates a new local branch name based on your detached branch
534+
535+ f. Make sure the changelog version contains the release version in the name (For example, `27.1~21.10.1`)
536+
537+ g. `git push <your_launchpad_user> upload-<this-version>-impish`
538+
539+ h. On Launchpad, create a merge proposal for this version which targets `ubuntu/devel`
540+ * For an example, see the [27.0.2 merge proposal](https://code.launchpad.net/~chad.smith/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/+merge/402459)
541+ * Add 2 review slots for `canonical-server` and `canonical-server-core-reviewers`
542+3. Set up the MP for past Ubuntu releases based on the ubuntu/devel PR
543+
544+ a. Create a PR for each target series based off your local `release-${UA_VERSION}-impish` branch:
545+ ```bash
546+ UA_VERSION=<UA-VERSION>
547+ SRU_BUG=<SRU-BUG>
548+ LP_USER=<LAUNCHPAD-USERNAME>
549+
550+ for release in xenial bionic focal groovy hirsute
551+ do
552+ rm ubuntu-advantage-*
553+ git checkout upload-${UA_VERSION}-impish -B upload-${UA_VERSION}-$release
554+ case "${release}" in
555+ xenial) version=${UA_VERSION}~16.04.1;;
556+ bionic) version=${UA_VERSION}~18.04.1;;
557+ focal) version=${UA_VERSION}~20.04.1;;
558+ groovy) version=${UA_VERSION}~20.10.1;;
559+ hirsute) version=${UA_VERSION}~21.04.1;;
560+ esac
561+ dch -v ${version} -D ${release} -b "Backport new upstream release: (LP: #${SRU_BUG}) to $release"
562+ git commit -m "changelog backport to ${release}" debian/changelog
563+ git push $LP_USER upload-${UA_VERSION}-$release
564+ done
565+ ```
566+
567+ b. Create merge proposals for each SRU target release @ `https://code.launchpad.net/~<YOUR_LP_USER></YOUR_LAUNCHPAD_USER>/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/`. Make sure each MP targets your `upload-${UA_VERSION}-impish` branch (the branch you are MP-ing into ubuntu/devel).
568+
569+ c. Add both `canonical-server` and `canonical-server-core-reviewers` as review slots on each MP.
570+
571+4. Server Team Review
572+
573+ a. Ask in ~Server for a review of your MPs. Include a link to the primary MP into ubuntu/devel and mention the other MPs are only changelog MPs for the SRUs into past releases.
574+
575+ b. If they request changes, create a PR into `main` on github and ask UAClient team for review. After a merge, open another PR on github, cherry-picking the change into the release branch. After that is merged, cherry-pick the commit into your `upload-<this-version>-impish` branch and push to launchpad. Then notify the Server Team member that you have addressed their requests. (This can probably be simplified).
576+ * Some issues may just be filed for addressing in the future if they are not urgent or pertinent to this release.
577+ * Unless the changes are very minor, or only testing related, you should upload a new release candidate version to `ppa:ua-client/staging` as descibed in I.3.
578+
579+ c. Once review is complete and approved, confirm that Ubuntu Server approver will be tagging the PR with the appropriate `upload/<version>` tag so git-ubuntu will import rich commit history.
580+
581+ d. Check `rmadison ubuntu-advantage-tools` for updated version in devel release
582+
583+ e. Confirm availability in <devel>-updates pocket via `lxc launch ubuntu-daily:impish dev-i; lxc exec dev-i -- apt update; lxc exec dev-i -- apt-cache policy ubuntu-advantage-tools`
584+ * Note that any changes to the code after this point will likely require a bump in the patch version of the release.
585+
586+ f. Ask Ubuntu Server approver if they also have upload rights to the proposed queue. If they do, request that they upload ubuntu-advantage-tools for all releases. If they do not, ask in ~Server channel for a Ubuntu Server team member with upload rights for an upload review of the MP for the proposed queue.
587+
588+ g. Once upload review is complete and approved, confirm that Ubuntu Server approver will upload ua-tools via dput to the `-proposed` queue.
589+
590+ h. Check the [-proposed release queue](https://launchpad.net/ubuntu/xenial/+queue?queue_state=1&queue_text=ubuntu-advantage-tools) for presence of ua-tools in unapproved state for each supported release. Note: libera chat #ubuntu-release IRC channel has a bot that reports queued uploads of any package in a message like "Unapproved: ubuntu-advantage-tools .. version".
591+
592+5. SRU Review
593+
594+ a. Once unapproved ua-tools package is listed in the pending queue for each target release, [ping appropriate daily SRU vanguard for review of ua-tools into -proposed](https://wiki.ubuntu.com/StableReleaseUpdates#Publishing)via the libera.chat #ubuntu-release channel
595+
596+ b. As soon as the SRU vanguard approves the packages, a bot in #ubuntu-release will announce that ubuntu-advantage-tools is accepted into the applicable -proposed pockets, or the [Xenial -proposed release rejection queue](https://launchpad.net/ubuntu/xenial/+queue?queue_state=4&queue_text=ubuntu-advantage-tools) will contain a reason for rejections. Double check the SRU process bug for any actionable review feedback.
597+
598+ c. Once accepted into `-proposed` by an SRU vanguard [ubuntu-advantage-tools shows up in the pending_sru page](https://people.canonical.com/~ubuntu-archive/pending-sru.html), check `rmadison ubuntu-advantage-tools | grep -proposed` to see if the upload exists in -proposed yet.
599+
600+ d. Confirm availability in <devel>-proposed pocket via
601+ ```bash
602+ cat > setup_proposed.sh <<EOF
603+ #/bin/bash
604+ mirror=http://archive.ubuntu.com/ubuntu
605+ echo deb \$mirror \$(lsb_release -sc)-proposed main | tee /etc/apt/sources.list.d/proposed.list
606+ apt-get update -q;
607+ apt-get install -qy ubuntu-advantage-tools;
608+ apt-cache policy ubuntu-advantage-tools;
609+ EOF
610+
611+ lxc launch ubuntu-daily:impish dev-i;
612+ lxc file push setup_proposed.sh
613+ lxc exec dev-i -- bash /setup_proposed.sh
614+ ```
615+
616+ e. Once [ubuntu-advantage-tools shows up in the pending_sru page](https://people.canonical.com/~ubuntu-archive/pending-sru.html), perform the [Ubuntu-advantage-client SRU verification steps](https://wiki.ubuntu.com/UbuntuAdvantageToolsUpdates). This typically involves running all behave targets with `UACLIENT_BEHAVE_ENABLE_PROPOSED=1 UACLIENT_BEHAVE_CHECK_VERSION=<this-version>` and saving the output.
617+
618+ f. After all tests have passed, tarball all of the output files and upload them to the SRU bug with a message that looks like this:
619+ ```
620+ We have run the full ubuntu-advantage-tools integration test suite against the version in -proposed. The results are attached. All tests passed (or call out specific explained failures).
621+
622+ You can verify the correct version was used by checking the output of the first test in each file, which prints the version number.
623+
624+ I am marking the verification done for this SRU.
625+ ```
626+ Change the tags on the bug from `verification-needed` to `verification-done` (including the verification tags for each release).
627+
628+ g. For any other related Launchpad bugs that are fixed in this release. Perform the verification steps necessary for those bugs and mark them `verification-done` as needed. This will likely involve following the test steps, but instead of adding the staging PPA, enabling -proposed.
629+
630+ h. Once all SRU bugs are tagged as `verification*-done`, all SRU-bugs should be listed as green in [the pending_sru page](https://people.canonical.com/~ubuntu-archive/pending-sru.html).
631+
632+ i. After the pending_sru page says that ubuntu-advantage-tools has been in proposed for 7 days, it is now time to ping the [current SRU vanguard](https://wiki.ubuntu.com/StableReleaseUpdates#Publishing) for acceptance of ubuntu-advantage-tools into -updates.
633+
634+### III. Final release to team infrastructure
635+
636+1. Ensure the version tag is correct on github. The `version` git tag should point to the commit that was released as that version to ubuntu -updates. If changes were made in response to feedback during the release process, the tag may have to be moved.
637+2. Perform the steps from `I.3` above but don't include a `-rcX` in the version name, and upload to `ppa:ua-client/stable` instead of staging.
638+3. Bring in any changes that were made to the release branch into `main` via PR (e.g. Changelog edits).
639+
640+## Ubuntu PRO Release Process
641+
642+Below is the procedure used to release ubuntu-advantage-tools to Ubuntu PRO images:
643+
644+ 1. [Open Daily PPA copy-package operation](https://code.launchpad.net/~ua-client/+archive/ubuntu/daily/+copy-packages)
645+ 2. Check Xenial, Bionic, Focal, Hirsute, Impish packages
646+ 3. Select Destination PPA: UA Client Premium [~ua-client/ubuntu/staging]
647+ 4. Select Destination series: The same series
648+ 5. Copy options: "Copy existing binaries"
649+ 6. Click Copy packages
650+ 7. Notify Pro Image creators about expected Premium PPA version (patviafore/powersj)
651+ 8. Once new PRO AMIs are publicly available run `./tools/refresh-aws-pro-ids` to update AMIs we test during CI runs
652diff --git a/debian/changelog b/debian/changelog
653index 266050a..470a90c 100644
654--- a/debian/changelog
655+++ b/debian/changelog
656@@ -1,3 +1,77 @@
657+ubuntu-advantage-tools (27.3~21.10.1) impish; urgency=medium
658+
659+ * d/tools.postinst:
660+ - consider cloud to be "none" on any cloud-id error
661+ - purge old ua-messaging.timer/service files
662+ - keep ua-timer.timer disabled if ua-messaging.timer was disabled by
663+ the user
664+ - properly configure both ubuntu-advantage-timer and
665+ ubuntu-advantage-licence-check logs
666+ * d/tools.postrm:
667+ - remove ubuntu-advantage-timer and ubuntu-advantage-license-check logs
668+ during purge
669+ * systemd:
670+ - remove ua-messaging.timer/service
671+ - add new ua-timer.timer that runs every 6 hours
672+ - add new ua-license_check.timer that runs every 5 minutes only if
673+ activated by ua-license-check.path
674+ * New upstream release 27.3 (LP: #1942929)
675+ - ros:
676+ + add beta support to enable ros and ros-updates
677+ + add support for "required services" so that esm-infra and esm-apps
678+ get auto-enabled when enabling ros or ros-updates
679+ + add support for "dependent services" so that user gets prompted to
680+ disable ros/ros-updates if they disable esm-infra/esm-apps
681+ - fips:
682+ + allow fips on GCP bionic now that optimized kernel is ready
683+ + disallow enabling fips on focal on clouds until cloud-optimized focal
684+ fips-certified kernel is ready (LP: #1939449, LP: #1939932)
685+ + print warning about generic fips kernel if cloud-id fails
686+ - cloud:
687+ + rely only on cloud-id to determine cloud type (LP: #1940131)
688+ + catch errors when determining cloud type
689+ (LP: #1938207, LP: #1944676) (GH: #1541)
690+ - azure:
691+ + bump IMDS API version to support Azure published images
692+ - cli:
693+ + collect-logs command that creates a tar file with debug-relevant logs
694+ and status info (GH: #463)
695+ + clean locks on exceptions more thoroughly to avoid false "Operation in
696+ progress" status messages
697+ + retain past service state after detach
698+ + shows better error message when a port value in a proxy is invalid
699+ - non-unicode locale support:
700+ + remove unicode-only characters from help file
701+ + don't print unicode-only characters in ua fix if non-utf8 locale
702+ (GH: #1463)
703+ - logrotate:
704+ + add logrotate functionality for ubuntu-advantage-timer.log.
705+ + Fix root:root logrotate permissions.
706+ - ua-timer.timer:
707+ + introduce a single systemd timer to handle ua recurring jobs
708+ + timer runs every 2 hours to support most frequent timer job
709+ + recurring job intervals are configurable in uaclient.conf
710+ + individual jobs are disabled if their interval is set to 0
711+ - status job:
712+ + update ua status every 12 hours
713+ - messaging job:
714+ + update APT/MOTD ESM messaging every 6 hours
715+ - metering job:
716+ + disabled until infrastructure is ready
717+ + for attached machines only, periodically update contract server with
718+ status information for proper contract metering
719+ - ua-license-check.timer:
720+ + only runs on LTS GCP instances that are not attached
721+ + runs every 5 minutes to check if gcp instance has license required to
722+ auto-attach
723+ - logs:
724+ + fixes duplicate logging (GH: #553)
725+ - tests and support:
726+ + remove groovy integration tests
727+ + various improvements to integration tests
728+
729+ -- Grant Orndorff <grant.orndorff@canonical.com> Tue, 21 Sep 2021 09:02:06 -0400
730+
731 ubuntu-advantage-tools (27.2.2~21.10.1) impish; urgency=medium
732
733 * d/tools.postinst:
734diff --git a/debian/rules b/debian/rules
735index 0b8c7e6..83680bb 100755
736--- a/debian/rules
737+++ b/debian/rules
738@@ -54,11 +54,15 @@ override_dh_gencontrol:
739 override_dh_systemd_enable:
740 dh_systemd_enable -pubuntu-advantage-pro ua-auto-attach.service
741 dh_systemd_enable -pubuntu-advantage-tools ua-reboot-cmds.service
742- dh_systemd_enable -pubuntu-advantage-tools ua-messaging.timer
743- dh_systemd_enable -pubuntu-advantage-tools ua-messaging.service
744+ dh_systemd_enable -pubuntu-advantage-tools ua-timer.timer
745+ dh_systemd_enable -pubuntu-advantage-tools ua-timer.service
746+ dh_systemd_enable -pubuntu-advantage-tools ua-license-check.timer
747+ dh_systemd_enable -pubuntu-advantage-tools ua-license-check.service
748+ dh_systemd_enable -pubuntu-advantage-tools ua-license-check.path
749
750 override_dh_systemd_start:
751- dh_systemd_start -pubuntu-advantage-tools ua-messaging.timer
752+ dh_systemd_start -pubuntu-advantage-tools ua-timer.timer
753+ dh_systemd_start -pubuntu-advantage-tools ua-license-check.path
754
755 override_dh_auto_install:
756 dh_auto_install --destdir=debian/ubuntu-advantage-tools
757diff --git a/debian/ubuntu-advantage-tools.logrotate b/debian/ubuntu-advantage-tools.logrotate
758index 1dede3f..76e6b47 100644
759--- a/debian/ubuntu-advantage-tools.logrotate
760+++ b/debian/ubuntu-advantage-tools.logrotate
761@@ -1,4 +1,7 @@
762-/var/log/ubuntu-advantage.log {
763+# use the root group by default, since this is the owning group
764+# of /var/log/ubuntu-advantage*.log files.
765+/var/log/ubuntu-advantage*.log {
766+ su root root
767 rotate 6
768 monthly
769 compress
770diff --git a/debian/ubuntu-advantage-tools.postinst b/debian/ubuntu-advantage-tools.postinst
771index f99c02e..ab9eddb 100644
772--- a/debian/ubuntu-advantage-tools.postinst
773+++ b/debian/ubuntu-advantage-tools.postinst
774@@ -32,6 +32,9 @@ ESM_APPS_APT_SOURCE_FILE="$APT_SRC_DIR/ubuntu-esm-apps.list"
775 FIPS_APT_SOURCE_FILE="$APT_SRC_DIR/ubuntu-fips.list"
776
777 OLD_CLIENT_FIPS_PPA="private-ppa.launchpad.net/ubuntu-advantage/fips/ubuntu"
778+UA_TIMER_NAME="ua-timer.timer"
779+OLD_MESSAGING_TIMER="ua-messaging.timer"
780+OLD_MESSAGING_TIMER_MASKED_LOCATION="/etc/systemd/system/timers.target.wants/$OLD_MESSAGING_TIMER"
781
782 ESM_APT_PREF_FILE_TRUSTY="$APT_PREFERENCES_DIR/ubuntu-esm-trusty"
783 ESM_INFRA_OLD_APT_PREF_FILE_TRUSTY="$APT_PREFERENCES_DIR/ubuntu-esm-infra-trusty"
784@@ -46,6 +49,9 @@ SYSTEMD_HELPER_ENABLED_AUTO_ATTACH_DSH="/var/lib/systemd/deb-systemd-helper-enab
785 SYSTEMD_HELPER_ENABLED_WANTS_LINK="/var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants/ua-auto-attach.service"
786
787 REBOOT_CMD_MARKER_FILE="/var/lib/ubuntu-advantage/marker-reboot-cmds-required"
788+LICENSE_CHECK_MARKER_FILE="/var/lib/ubuntu-advantage/marker-license-check"
789+
790+MACHINE_TOKEN_FILE="/var/lib/ubuntu-advantage/private/machine-token.json"
791
792 # Rename apt config files for ua services removing ubuntu release names
793 redact_ubuntu_release_from_ua_apt_filenames() {
794@@ -290,10 +296,7 @@ notify_wrong_fips_metapackage_on_cloud() {
795
796 fips_metapkg="ubuntu-fips"
797
798- cloud_id=""
799- if command -v "cloud-id" > /dev/null && [ -f /run/cloud-init/instance-data.json ] ; then
800- cloud_id=$(cloud-id)
801- fi
802+ cloud_id=$(cloud-id 2>/dev/null) || cloud_id=""
803
804 # If the package is not installed, we don't want the postinst script to fail
805 fips_installed=$(dpkg-query -W --showformat='${db:Status-Status}\n' $fips_metapkg 2>/dev/null || true)
806@@ -305,6 +308,69 @@ notify_wrong_fips_metapackage_on_cloud() {
807 fi
808 }
809
810+enable_periodic_license_check() {
811+ cloud_id=$(cloud-id 2>/dev/null) || cloud_id=""
812+ if echo "$cloud_id" | grep -q "^gce"; then
813+ if check_is_lts "${UBUNTU_CODENAME}"; then
814+ if [ ! -f $MACHINE_TOKEN_FILE ]; then
815+ touch $LICENSE_CHECK_MARKER_FILE
816+ fi
817+ fi
818+ fi
819+}
820+
821+disable_new_timer_if_old_timer_already_disabled() {
822+ # If the user has disabled the ua-messaging
823+ # then we will assume that the user would want the
824+ # ua-timer to be disabled as well. In that case, we will
825+ # disable the ua-timer here.
826+ PREVIOUS_PKG_VER=$1
827+
828+ # We should only perform this check on UA version that have the
829+ # ua-messaging.timer: 27.0 until 27.2. This will also guarantee
830+ # that on 27.3 and forward, we will not run this logic.
831+ if dpkg --compare-versions "$PREVIOUS_PKG_VER" lt "27.0~" \
832+ || dpkg --compare-versions "$PREVIOUS_PKG_VER" ge "27.3~"; then
833+ return
834+ fi
835+ if ! deb-systemd-helper --quiet was-enabled $OLD_MESSAGING_TIMER; then
836+ # We have the following entry on our rules file:
837+ # dh_systemd_enable -pubuntu-advantage-tools ua-timer.timer
838+ # This rule will append some code at the end of the postinst script
839+ # that checks if the ua-timer.timer was already enabled on the system.
840+ # This means that if we manually disable the service here, that logic will
841+ # still enable it in the end of the postinst script.
842+ # Because of this logic we are now manually enabling ua-timer.timer here
843+ # and then we manually disable it. This will guarantee that the was-enabled
844+ # logic introduced by the rules file will not be triggered and we will not
845+ # re-enable the ua-timer.timer service after calling this function.
846+ echo "$OLD_MESSAGING_TIMER was disabled. Disabling $UA_TIMER_NAME." >&2
847+ deb-systemd-helper enable $UA_TIMER_NAME > /dev/null 2>&1 || true
848+ deb-systemd-helper disable $UA_TIMER_NAME > /dev/null 2>&1 || true
849+ fi
850+}
851+
852+remove_old_systemd_timers() {
853+ # These are the commands that are run when the package is purged.
854+ # Since we actually want to remove this service from now on
855+ # we have replicated that behavior here
856+ if [ -L $OLD_MESSAGING_TIMER_MASKED_LOCATION ]; then
857+ if [ -x "/usr/bin/deb-systemd-helper" ]; then
858+ deb-systemd-helper purge ua-messaging.timer > /dev/null || true
859+ deb-systemd-helper unmask ua-messaging.timer > /dev/null || true
860+ fi
861+ fi
862+}
863+
864+configure_log_file() {
865+ log_path=$1
866+ if [ ! -f $log_path ]; then
867+ touch $log_path
868+ fi
869+ chmod 0600 $log_path
870+ chown root:root $log_path
871+}
872+
873 case "$1" in
874 configure)
875 PREVIOUS_PKG_VER=$2
876@@ -362,11 +428,10 @@ case "$1" in
877 fi
878 fi
879
880- if [ ! -f /var/log/ubuntu-advantage.log ]; then
881- touch /var/log/ubuntu-advantage.log
882- fi
883- chmod 0600 /var/log/ubuntu-advantage.log
884- chown root:root /var/log/ubuntu-advantage.log
885+ configure_log_file /var/log/ubuntu-advantage.log
886+ configure_log_file /var/log/ubuntu-advantage-timer.log
887+ configure_log_file /var/log/ubuntu-advantage-license-check.log
888+
889 private_dir="/var/lib/ubuntu-advantage/private"
890 if [ -d "$private_dir" ]; then
891 chmod 0700 "$private_dir"
892@@ -378,6 +443,9 @@ case "$1" in
893 fi
894 fi
895 mark_reboot_for_fips_pro
896+ enable_periodic_license_check
897+ disable_new_timer_if_old_timer_already_disabled $PREVIOUS_PKG_VER
898+ remove_old_systemd_timers
899 ;;
900 esac
901
902diff --git a/debian/ubuntu-advantage-tools.postrm b/debian/ubuntu-advantage-tools.postrm
903index fb84664..978b492 100644
904--- a/debian/ubuntu-advantage-tools.postrm
905+++ b/debian/ubuntu-advantage-tools.postrm
906@@ -14,6 +14,8 @@ remove_cache_dir(){
907
908 remove_logs(){
909 rm -f /var/log/ubuntu-advantage.log*
910+ rm -f /var/log/ubuntu-advantage-timer.log*
911+ rm -f /var/log/ubuntu-advantage-license-check.log*
912 }
913
914 remove_gpg_files(){
915diff --git a/dev-requirements.txt b/dev-requirements.txt
916index 13c99e2..c373b55 100644
917--- a/dev-requirements.txt
918+++ b/dev-requirements.txt
919@@ -1,4 +1,5 @@
920-# The black version is also in .pre-commit-config.yaml; make sure to update
921-# both together
922+# The black and isort versions are also in .pre-commit-config.yaml; make sure
923+# to update both together
924 black==19.3b0
925+isort==5.8.0
926 pre-commit
927diff --git a/features/_version.feature b/features/_version.feature
928index e39601c..655f915 100644
929--- a/features/_version.feature
930+++ b/features/_version.feature
931@@ -22,11 +22,11 @@ Feature: UA is expected version
932 | xenial |
933 | bionic |
934 | focal |
935- | groovy |
936 | hirsute |
937
938 @series.all
939 @uses.config.check_version
940+ @uses.config.machine_type.lxd.container
941 @upgrade
942 Scenario Outline: Check ua version
943 Given a `<release>` machine with ubuntu-advantage-tools installed
944@@ -40,5 +40,4 @@ Feature: UA is expected version
945 | xenial |
946 | bionic |
947 | focal |
948- | groovy |
949 | hirsute |
950diff --git a/features/attach_invalidtoken.feature b/features/attach_invalidtoken.feature
951index 722ae82..faee67e 100644
952--- a/features/attach_invalidtoken.feature
953+++ b/features/attach_invalidtoken.feature
954@@ -2,8 +2,9 @@ Feature: Command behaviour when trying to attach a machine to an Ubuntu
955 Advantage subscription using an invalid token
956
957 @series.all
958- Scenario Outline: Attach command in a machine
959- Given a `<release>` machine with ubuntu-advantage-tools installed
960+ @uses.config.machine_type.lxd.container
961+ Scenario Outline: Attach command failure on invalid token
962+ Given a `<release>` machine with ubuntu-advantage-tools installed
963 When I verify that running `ua attach INVALID_TOKEN` `with sudo` exits `1`
964 Then stderr matches regexp:
965 """
966@@ -19,11 +20,11 @@ Feature: Command behaviour when trying to attach a machine to an Ubuntu
967 | xenial |
968 | bionic |
969 | focal |
970- | groovy |
971 | hirsute |
972
973 @uses.config.contract_token_staging_expired
974 @series.all
975+ @uses.config.machine_type.lxd.container
976 Scenario Outline: Attach command failure on expired token
977 Given a `<release>` machine with ubuntu-advantage-tools installed
978 When I attempt to attach `contract_token_staging_expired` with sudo
979@@ -38,5 +39,4 @@ Feature: Command behaviour when trying to attach a machine to an Ubuntu
980 | xenial |
981 | bionic |
982 | focal |
983- | groovy |
984 | hirsute |
985diff --git a/features/attach_validtoken.feature b/features/attach_validtoken.feature
986index a164633..84e4f30 100644
987--- a/features/attach_validtoken.feature
988+++ b/features/attach_validtoken.feature
989@@ -2,9 +2,29 @@
990 Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
991 subscription using a valid token
992
993- @series.xenial
994- @series.bionic
995- @series.focal
996+ @series.hirsute
997+ @uses.config.machine_type.lxd.container
998+ Scenario Outline: Attached command in a non-lts ubuntu machine
999+ Given a `<release>` machine with ubuntu-advantage-tools installed
1000+ When I attach `contract_token` with sudo
1001+ And I run `ua status --all` as non-root
1002+ Then stdout matches regexp:
1003+ """
1004+ SERVICE ENTITLED STATUS DESCRIPTION
1005+ cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages
1006+ cis +yes +n/a +Center for Internet Security Audit Tools
1007+ esm-apps +yes +n/a +UA Apps: Extended Security Maintenance \(ESM\)
1008+ esm-infra +yes +n/a +UA Infra: Extended Security Maintenance \(ESM\)
1009+ fips +yes +n/a +NIST-certified core packages
1010+ fips-updates +yes +n/a +NIST-certified core packages with priority security updates
1011+ livepatch +yes +n/a +Canonical Livepatch service
1012+ """
1013+
1014+ Examples: ubuntu release
1015+ | release |
1016+ | hirsute |
1017+
1018+ @series.lts
1019 @uses.config.machine_type.lxd.container
1020 Scenario Outline: Attach command in a ubuntu lxd container
1021 Given a `<release>` machine with ubuntu-advantage-tools installed
1022@@ -38,6 +58,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1023 """
1024 SERVICE ENTITLED STATUS DESCRIPTION
1025 cis +yes +disabled +Center for Internet Security Audit Tools
1026+ esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\)
1027 esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\)
1028 fips +yes +n/a +NIST-certified core packages
1029 fips-updates +yes +n/a +NIST-certified core packages with priority security updates
1030@@ -47,13 +68,15 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1031 """
1032 Enabling default service esm-infra
1033 """
1034+ When I run `ua disable esm-apps --assume-yes` with sudo
1035 When I append the following on uaclient config:
1036 """
1037 features:
1038 allow_beta: true
1039 """
1040 And I run `apt update` with sudo
1041- And I run `python3 /usr/lib/ubuntu-advantage/ua_update_messaging.py` with sudo
1042+ And I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
1043+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1044 And I run `apt install update-motd` with sudo, retrying exit [100]
1045 And I run `update-motd` with sudo
1046 Then if `<release>` in `focal` and stdout matches regexp:
1047@@ -97,7 +120,8 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1048 To see these additional updates run: apt list --upgradable
1049 """
1050 When I update contract to use `effectiveTo` as `days=-20`
1051- And I run `python3 /usr/lib/ubuntu-advantage/ua_update_messaging.py` with sudo
1052+ And I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
1053+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1054 And I run `update-motd` with sudo
1055 Then if `<release>` in `xenial` and stdout matches regexp:
1056 """
1057@@ -136,7 +160,27 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1058 @uses.config.machine_type.aws.generic
1059 Scenario Outline: Attach command in an generic AWS Ubuntu VM
1060 Given a `<release>` machine with ubuntu-advantage-tools installed
1061- When I attach `contract_token` with sudo
1062+ When I create the file `/tmp/machine-token-overlay.json` with the following:
1063+ """
1064+ {
1065+ "machineTokenInfo": {
1066+ "contractInfo": {
1067+ "resourceEntitlements": [
1068+ {
1069+ "type": "esm-apps",
1070+ "entitled": false
1071+ }
1072+ ]
1073+ }
1074+ }
1075+ }
1076+ """
1077+ And I append the following on uaclient config:
1078+ """
1079+ features:
1080+ machine_token_overlay: "/tmp/machine-token-overlay.json"
1081+ """
1082+ And I attach `contract_token` with sudo
1083 Then stdout matches regexp:
1084 """
1085 UA Infra: ESM enabled
1086@@ -167,9 +211,29 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1087
1088 @series.all
1089 @uses.config.machine_type.azure.generic
1090- Scenario Outline: Attach command in a ubuntu lxd container
1091+ Scenario Outline: Attach command in an generic Azure Ubuntu VM
1092 Given a `<release>` machine with ubuntu-advantage-tools installed
1093- When I attach `contract_token` with sudo
1094+ When I create the file `/tmp/machine-token-overlay.json` with the following:
1095+ """
1096+ {
1097+ "machineTokenInfo": {
1098+ "contractInfo": {
1099+ "resourceEntitlements": [
1100+ {
1101+ "type": "esm-apps",
1102+ "entitled": false
1103+ }
1104+ ]
1105+ }
1106+ }
1107+ }
1108+ """
1109+ And I append the following on uaclient config:
1110+ """
1111+ features:
1112+ machine_token_overlay: "/tmp/machine-token-overlay.json"
1113+ """
1114+ And I attach `contract_token` with sudo
1115 Then stdout matches regexp:
1116 """
1117 UA Infra: ESM enabled
1118@@ -200,9 +264,29 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1119
1120 @series.all
1121 @uses.config.machine_type.gcp.generic
1122- Scenario Outline: Attach command in a ubuntu lxd container
1123+ Scenario Outline: Attach command in an generic GCP Ubuntu VM
1124 Given a `<release>` machine with ubuntu-advantage-tools installed
1125- When I attach `contract_token` with sudo
1126+ When I create the file `/tmp/machine-token-overlay.json` with the following:
1127+ """
1128+ {
1129+ "machineTokenInfo": {
1130+ "contractInfo": {
1131+ "resourceEntitlements": [
1132+ {
1133+ "type": "esm-apps",
1134+ "entitled": false
1135+ }
1136+ ]
1137+ }
1138+ }
1139+ }
1140+ """
1141+ And I append the following on uaclient config:
1142+ """
1143+ features:
1144+ machine_token_overlay: "/tmp/machine-token-overlay.json"
1145+ """
1146+ And I attach `contract_token` with sudo
1147 Then stdout matches regexp:
1148 """
1149 UA Infra: ESM enabled
1150@@ -228,197 +312,5 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Advantage
1151 Examples: ubuntu release livepatch status
1152 | release | lp_status | fips_status |
1153 | xenial | n/a | n/a |
1154- | bionic | n/a | n/a |
1155- | focal | n/a | n/a |
1156-
1157- @series.bionic
1158- @uses.config.machine_type.azure.generic
1159- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
1160- Given a `<release>` machine with ubuntu-advantage-tools installed
1161- When I attach `contract_token_staging` with sudo
1162- 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
1163- And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
1164- And I run `ua enable <fips-service> --assume-yes` with sudo
1165- Then stdout matches regexp:
1166- """
1167- Updating package lists
1168- Installing <fips-name> packages
1169- <fips-name> enabled
1170- A reboot is required to complete install
1171- """
1172- When I run `ua status --all` with sudo
1173- Then stdout matches regexp:
1174- """
1175- <fips-service> +yes enabled
1176- """
1177- And I verify that running `apt update` `with sudo` exits `0`
1178- And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
1179- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
1180- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
1181- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
1182- And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
1183- And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
1184- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
1185- When I run `apt-cache policy ubuntu-azure-fips` as non-root
1186- Then stdout does not match regexp:
1187- """
1188- .*Installed: \(none\)
1189- """
1190- When I reboot the `<release>` machine
1191- And I run `uname -r` as non-root
1192- Then stdout matches regexp:
1193- """
1194- azure-fips
1195- """
1196- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
1197- Then I will see the following on stdout:
1198- """
1199- 1
1200- """
1201- When I run `ua disable <fips-service> --assume-yes` with sudo
1202- Then stdout matches regexp:
1203- """
1204- Updating package lists
1205- """
1206- When I run `apt-cache policy ubuntu-azure-fips` as non-root
1207- Then stdout matches regexp:
1208- """
1209- .*Installed: \(none\)
1210- """
1211- When I reboot the `<release>` machine
1212- Then I verify that `openssh-server` installed version matches regexp `fips`
1213- And I verify that `openssh-client` installed version matches regexp `fips`
1214- And I verify that `strongswan` installed version matches regexp `fips`
1215- And I verify that `openssh-server-hmac` installed version matches regexp `fips`
1216- And I verify that `openssh-client-hmac` installed version matches regexp `fips`
1217- And I verify that `strongswan-hmac` installed version matches regexp `fips`
1218- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
1219- Then I will see the following on stdout:
1220- """
1221- openssh-client was already not hold.
1222- openssh-server was already not hold.
1223- strongswan was already not hold.
1224- """
1225- When I run `ua status --all` with sudo
1226- Then stdout matches regexp:
1227- """
1228- <fips-service> +yes disabled
1229- """
1230-
1231- Examples: ubuntu release
1232- | release | fips-name | fips-service |fips-apt-source |
1233- | bionic | FIPS | fips |https://esm.staging.ubuntu.com/fips/ubuntu bionic/main |
1234-
1235- @series.bionic
1236- @uses.config.machine_type.aws.generic
1237- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
1238- Given a `<release>` machine with ubuntu-advantage-tools installed
1239- When I attach `contract_token_staging` with sudo
1240- And I run `ua disable livepatch` with sudo
1241- 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
1242- And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
1243- And I run `ua enable <fips-service> --assume-yes` with sudo
1244- Then stdout matches regexp:
1245- """
1246- Updating package lists
1247- Installing <fips-name> packages
1248- <fips-name> enabled
1249- A reboot is required to complete install
1250- """
1251- When I run `ua status --all` with sudo
1252- Then stdout matches regexp:
1253- """
1254- <fips-service> +yes enabled
1255- """
1256- And I verify that running `apt update` `with sudo` exits `0`
1257- And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
1258- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
1259- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
1260- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
1261- And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
1262- And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
1263- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
1264- When I run `apt-cache policy ubuntu-aws-fips` as non-root
1265- Then stdout does not match regexp:
1266- """
1267- .*Installed: \(none\)
1268- """
1269- When I reboot the `<release>` machine
1270- And I run `uname -r` as non-root
1271- Then stdout matches regexp:
1272- """
1273- aws-fips
1274- """
1275- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
1276- Then I will see the following on stdout:
1277- """
1278- 1
1279- """
1280- When I run `ua disable <fips-service> --assume-yes` with sudo
1281- Then stdout matches regexp:
1282- """
1283- Updating package lists
1284- """
1285- When I run `apt-cache policy ubuntu-aws-fips` as non-root
1286- Then stdout matches regexp:
1287- """
1288- .*Installed: \(none\)
1289- """
1290- When I reboot the `<release>` machine
1291- Then I verify that `openssh-server` installed version matches regexp `fips`
1292- And I verify that `openssh-client` installed version matches regexp `fips`
1293- And I verify that `strongswan` installed version matches regexp `fips`
1294- And I verify that `openssh-server-hmac` installed version matches regexp `fips`
1295- And I verify that `openssh-client-hmac` installed version matches regexp `fips`
1296- And I verify that `strongswan-hmac` installed version matches regexp `fips`
1297- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
1298- Then I will see the following on stdout:
1299- """
1300- openssh-client was already not hold.
1301- openssh-server was already not hold.
1302- strongswan was already not hold.
1303- """
1304- When I run `ua status --all` with sudo
1305- Then stdout matches regexp:
1306- """
1307- <fips-service> +yes disabled
1308- """
1309-
1310- Examples: ubuntu release
1311- | release | fips-name | fips-service |fips-apt-source |
1312- | bionic | FIPS | fips |https://esm.staging.ubuntu.com/fips/ubuntu bionic/main |
1313-
1314- @series.xenial
1315- @uses.config.machine_type.azure.generic
1316- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
1317- Given a `xenial` machine with ubuntu-advantage-tools installed
1318- When I attach `contract_token_staging` with sudo
1319- Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
1320- And stdout matches regexp:
1321- """
1322- Ubuntu Xenial does not provide an Azure optimized FIPS kernel
1323- """
1324-
1325- Examples: fips
1326- | fips_service |
1327- | fips |
1328- | fips-updates |
1329-
1330- @series.bionic
1331- @series.xenial
1332- @uses.config.machine_type.gcp.generic
1333- Scenario Outline: Attached enable of fips services in an ubuntu gcp vm
1334- Given a `<release>` machine with ubuntu-advantage-tools installed
1335- When I attach `contract_token_staging` with sudo
1336- Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
1337- And stdout matches regexp:
1338- """
1339- Ubuntu <release_title> does not provide a GCP optimized FIPS kernel
1340- """
1341-
1342- Examples: fips
1343- | release | release_title | fips_service |
1344- | xenial | Xenial | fips |
1345- | xenial | Xenial | fips-updates |
1346- | bionic | Bionic | fips |
1347- | bionic | Bionic | fips-updates |
1348+ | bionic | n/a | disabled |
1349+ | focal | enabled | n/a |
1350diff --git a/features/attached_commands.feature b/features/attached_commands.feature
1351index cc4f22a..6ec84d3 100644
1352--- a/features/attached_commands.feature
1353+++ b/features/attached_commands.feature
1354@@ -2,6 +2,7 @@
1355 Feature: Command behaviour when attached to an UA subscription
1356
1357 @series.all
1358+ @uses.config.machine_type.lxd.container
1359 Scenario Outline: Attached refresh in a ubuntu machine
1360 Given a `<release>` machine with ubuntu-advantage-tools installed
1361 When I attach `contract_token` with sudo
1362@@ -26,6 +27,23 @@ Feature: Command behaviour when attached to an UA subscription
1363 """
1364 Successfully refreshed your subscription.
1365 """
1366+ When I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1367+ And I run `sh -c "ls /var/log/ubuntu-advantage* | sort -d"` as non-root
1368+ Then stdout matches regexp:
1369+ """
1370+ /var/log/ubuntu-advantage-license-check.log
1371+ /var/log/ubuntu-advantage.log
1372+ /var/log/ubuntu-advantage-timer.log
1373+ """
1374+ When I run `logrotate --force /etc/logrotate.d/ubuntu-advantage-tools` with sudo
1375+ And I run `sh -c "ls /var/log/ubuntu-advantage* | sort -d"` as non-root
1376+ # We don't rotate empty log files. That's why the license-check logs are not rotated
1377+ Then stdout matches regexp:
1378+ """
1379+ /var/log/ubuntu-advantage-license-check.log
1380+ /var/log/ubuntu-advantage.log.1
1381+ /var/log/ubuntu-advantage-timer.log.1
1382+ """
1383
1384 Examples: ubuntu release
1385 | release |
1386@@ -33,9 +51,9 @@ Feature: Command behaviour when attached to an UA subscription
1387 | focal |
1388 | xenial |
1389 | hirsute |
1390- | groovy |
1391
1392 @series.all
1393+ @uses.config.machine_type.lxd.container
1394 Scenario Outline: Attached disable of an already disabled service in a ubuntu machine
1395 Given a `<release>` machine with ubuntu-advantage-tools installed
1396 When I attach `contract_token` with sudo
1397@@ -57,9 +75,9 @@ Feature: Command behaviour when attached to an UA subscription
1398 | focal |
1399 | xenial |
1400 | hirsute |
1401- | groovy |
1402
1403 @series.lts
1404+ @uses.config.machine_type.lxd.container
1405 Scenario Outline: Attached disable of a service in a ubuntu machine
1406 Given a `<release>` machine with ubuntu-advantage-tools installed
1407 When I attach `contract_token` with sudo
1408@@ -72,7 +90,8 @@ Feature: Command behaviour when attached to an UA subscription
1409 And stderr matches regexp:
1410 """
1411 Cannot disable unknown service 'foobar'.
1412- Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch.
1413+ Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros,
1414+ ros-updates.
1415 """
1416 And I verify that running `ua disable esm-infra` `as non-root` exits `1`
1417 And stderr matches regexp:
1418@@ -97,30 +116,8 @@ Feature: Command behaviour when attached to an UA subscription
1419 | focal |
1420 | xenial |
1421
1422- @series.groovy
1423- @series.hirsute
1424- Scenario Outline: Attached detach in an ubuntu machine
1425- Given a `<release>` machine with ubuntu-advantage-tools installed
1426- When I attach `contract_token` with sudo
1427- And I run `ua status --all` as non-root
1428- Then stdout matches regexp:
1429- """
1430- SERVICE ENTITLED STATUS DESCRIPTION
1431- cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages
1432- cis +yes +n/a +Center for Internet Security Audit Tools
1433- esm-apps +no +— +UA Apps: Extended Security Maintenance \(ESM\)
1434- esm-infra +yes +n/a +UA Infra: Extended Security Maintenance \(ESM\)
1435- fips +yes +n/a +NIST-certified core packages
1436- fips-updates +yes +n/a +NIST-certified core packages with priority security updates
1437- livepatch +yes +n/a +Canonical Livepatch service
1438- """
1439-
1440- Examples: ubuntu release
1441- | release |
1442- | groovy |
1443- | hirsute |
1444-
1445 @series.lts
1446+ @uses.config.machine_type.lxd.container
1447 Scenario Outline: Attached detach in an ubuntu machine
1448 Given a `<release>` machine with ubuntu-advantage-tools installed
1449 When I attach `contract_token` with sudo
1450@@ -132,23 +129,27 @@ Feature: Command behaviour when attached to an UA subscription
1451 When I run `ua detach --assume-yes` with sudo
1452 Then I will see the following on stdout:
1453 """
1454- Detach will disable the following service:
1455+ Detach will disable the following services:
1456+ esm-apps
1457 esm-infra
1458 Updating package lists
1459+ Updating package lists
1460 This machine is now detached.
1461 """
1462 When I run `ua status --all` as non-root
1463 Then stdout matches regexp:
1464- """
1465- SERVICE AVAILABLE DESCRIPTION
1466- cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages
1467- cis +<cis> +Center for Internet Security Audit Tools
1468- esm-apps +<esm-apps> +UA Apps: Extended Security Maintenance \(ESM\)
1469- esm-infra +yes +UA Infra: Extended Security Maintenance \(ESM\)
1470- fips +<fips> +NIST-certified core packages
1471- fips-updates +<fips> +NIST-certified core packages with priority security updates
1472- livepatch +yes +Canonical Livepatch service
1473- """
1474+ """
1475+ SERVICE AVAILABLE DESCRIPTION
1476+ cc-eal +<cc-eal> +Common Criteria EAL2 Provisioning Packages
1477+ cis +<cis> +Center for Internet Security Audit Tools
1478+ esm-apps +<esm-apps> +UA Apps: Extended Security Maintenance \(ESM\)
1479+ esm-infra +yes +UA Infra: Extended Security Maintenance \(ESM\)
1480+ fips +<fips> +NIST-certified core packages
1481+ fips-updates +<fips> +NIST-certified core packages with priority security updates
1482+ livepatch +yes +Canonical Livepatch service
1483+ ros +<ros> +Security Updates for the Robot Operating System
1484+ ros-updates +<ros> +All Updates for the Robot Operating System
1485+ """
1486 And stdout matches regexp:
1487 """
1488 This machine is not attached to a UA subscription.
1489@@ -156,12 +157,13 @@ Feature: Command behaviour when attached to an UA subscription
1490 And I verify that running `apt update` `with sudo` exits `0`
1491
1492 Examples: ubuntu release
1493- | release | esm-apps | cc-eal | cis | fips | fips-update |
1494- | bionic | yes | no | yes | yes | yes |
1495- | focal | yes | no | yes | no | no |
1496- | xenial | yes | yes | yes | yes | yes |
1497+ | release | esm-apps | cc-eal | cis | fips | fips-update | ros |
1498+ | bionic | yes | no | yes | yes | yes | yes |
1499+ | focal | yes | no | yes | yes | yes | no |
1500+ | xenial | yes | yes | yes | yes | yes | yes |
1501
1502 @series.all
1503+ @uses.config.machine_type.lxd.container
1504 Scenario Outline: Attached auto-attach in a ubuntu machine
1505 Given a `<release>` machine with ubuntu-advantage-tools installed
1506 When I attach `contract_token` with sudo
1507@@ -182,9 +184,9 @@ Feature: Command behaviour when attached to an UA subscription
1508 | focal |
1509 | xenial |
1510 | hirsute |
1511- | groovy |
1512
1513 @series.all
1514+ @uses.config.machine_type.lxd.container
1515 Scenario Outline: Attached show version in a ubuntu machine
1516 Given a `<release>` machine with ubuntu-advantage-tools installed
1517 When I attach `contract_token` with sudo
1518@@ -203,9 +205,9 @@ Feature: Command behaviour when attached to an UA subscription
1519 | focal |
1520 | xenial |
1521 | hirsute |
1522- | groovy |
1523
1524 @series.all
1525+ @uses.config.machine_type.lxd.container
1526 Scenario Outline: Unattached status in a ubuntu machine with feature overrides
1527 Given a `<release>` machine with ubuntu-advantage-tools installed
1528 When I create the file `/tmp/machine-token-overlay.json` with the following:
1529@@ -253,9 +255,9 @@ Feature: Command behaviour when attached to an UA subscription
1530 | focal |
1531 | xenial |
1532 | hirsute |
1533- | groovy |
1534
1535 @series.lts
1536+ @uses.config.machine_type.lxd.container
1537 Scenario Outline: Attached disable of different services in a ubuntu machine
1538 Given a `<release>` machine with ubuntu-advantage-tools installed
1539 When I attach `contract_token` with sudo
1540@@ -274,7 +276,8 @@ Feature: Command behaviour when attached to an UA subscription
1541 And stderr matches regexp:
1542 """
1543 Cannot disable unknown service 'foobar'.
1544- Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch.
1545+ Try cc-eal, cis, esm-apps, esm-infra, fips, fips-updates, livepatch, ros,
1546+ ros-updates.
1547 """
1548 When I run `ua status` with sudo
1549 Then stdout matches regexp:
1550@@ -289,6 +292,7 @@ Feature: Command behaviour when attached to an UA subscription
1551 | xenial |
1552
1553 @series.all
1554+ @uses.config.machine_type.lxd.container
1555 Scenario Outline: Help command on an attached machine
1556 Given a `<release>` machine with ubuntu-advantage-tools installed
1557 When I attach `contract_token` with sudo
1558@@ -371,6 +375,10 @@ Feature: Command behaviour when attached to an UA subscription
1559 \(https://ubuntu.com/security/certifications#fips\)
1560 - livepatch: Canonical Livepatch service
1561 \(https://ubuntu.com/security/livepatch\)
1562+ - ros-updates: All Updates for the Robot Operating System
1563+ \(https://ubuntu.com/robotics/ros-esm\)
1564+ - ros: Security Updates for the Robot Operating System
1565+ \(https://ubuntu.com/robotics/ros-esm\)
1566 """
1567
1568 Examples: ubuntu release
1569@@ -379,38 +387,9 @@ Feature: Command behaviour when attached to an UA subscription
1570 | focal | enabled |
1571 | xenial | enabled |
1572 | hirsute | n/a |
1573- | groovy | n/a |
1574-
1575- @series.lts
1576- Scenario Outline: Purge package after attaching it to a machine
1577- Given a `<release>` machine with ubuntu-advantage-tools installed
1578- When I attach `contract_token` with sudo
1579- And I run `touch /etc/apt/preferences.d/ubuntu-esm-infra` with sudo
1580- Then I verify that files exist matching `/var/log/ubuntu-advantage.log`
1581- And I verify that running `test -d /var/lib/ubuntu-advantage` `with sudo` exits `0`
1582- And I verify that files exist matching `/etc/apt/auth.conf.d/90ubuntu-advantage`
1583- And I verify that files exist matching `/etc/apt/trusted.gpg.d/ubuntu-advantage-esm-infra-trusty.gpg`
1584- And I verify that files exist matching `/etc/apt/sources.list.d/ubuntu-esm-infra.list`
1585- And I verify that files exist matching `/etc/apt/preferences.d/ubuntu-esm-infra`
1586- When I run `apt-get purge ubuntu-advantage-tools -y` with sudo, retrying exit [100]
1587- Then stdout matches regexp:
1588- """
1589- Purging configuration files for ubuntu-advantage-tools
1590- """
1591- And I verify that no files exist matching `/var/log/ubuntu-advantage.log`
1592- And I verify that no files exist matching `/var/lib/ubuntu-advantage`
1593- And I verify that no files exist matching `/etc/apt/auth.conf.d/90ubuntu-advantage`
1594- And I verify that no files exist matching `/etc/apt/sources.list.d/ubuntu-*`
1595- And I verify that no files exist matching `/etc/apt/trusted.gpg.d/ubuntu-advantage-*`
1596- And I verify that no files exist matching `/etc/apt/preferences.d/ubuntu-*`
1597-
1598- Examples: ubuntu release
1599- | release |
1600- | bionic |
1601- | focal |
1602- | xenial |
1603
1604 @series.lts
1605+ @uses.config.machine_type.lxd.container
1606 Scenario Outline: Enable command with invalid repositories in user machine
1607 Given a `<release>` machine with ubuntu-advantage-tools installed
1608 When I attach `contract_token` with sudo
1609@@ -418,7 +397,7 @@ Feature: Command behaviour when attached to an UA subscription
1610 And I run `add-apt-repository ppa:cloud-init-dev/daily -y` with sudo, retrying exit [1]
1611 And I run `apt update` with sudo
1612 And I run `sed -i 's/ubuntu/ubun/' /etc/apt/sources.list.d/<ppa_file>.list` with sudo
1613- And I run `ua enable esm-infra` with sudo
1614+ And I verify that running `ua enable esm-infra` `with sudo` exits `1`
1615 Then stdout matches regexp:
1616 """
1617 One moment, checking your subscription first
1618@@ -433,3 +412,214 @@ Feature: Command behaviour when attached to an UA subscription
1619 | xenial | cloud-init-dev-ubuntu-daily-xenial |
1620 | bionic | cloud-init-dev-ubuntu-daily-bionic |
1621 | focal | cloud-init-dev-ubuntu-daily-focal |
1622+
1623+ @series.all
1624+ @uses.config.machine_type.lxd.container
1625+ Scenario Outline: Run timer script on an attached machine
1626+ Given a `<release>` machine with ubuntu-advantage-tools installed
1627+ When I run `systemctl stop ua-timer.timer` with sudo
1628+ And I attach `contract_token` with sudo
1629+ Then I verify that running `ua config set update_messaging_timer=-2` `with sudo` exits `1`
1630+ And stderr matches regexp:
1631+ """
1632+ Cannot set update_messaging_timer to -2: <value> for interval must be a positive integer.
1633+ """
1634+ When I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1635+ And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
1636+ Then stdout matches regexp:
1637+ """"
1638+ "update_messaging":
1639+ """
1640+ And stdout matches regexp:
1641+ """"
1642+ "update_status":
1643+ """
1644+ When I run `ua config show` with sudo
1645+ Then stdout matches regexp:
1646+ """
1647+ update_messaging_timer +21600
1648+ update_status_timer +43200
1649+ """
1650+ When I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
1651+ And I run `ua config set update_messaging_timer=0` with sudo
1652+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1653+ And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
1654+ Then stdout does not match regexp:
1655+ """"
1656+ "update_messaging":
1657+ """
1658+ And stdout matches regexp:
1659+ """"
1660+ "update_status":
1661+ """
1662+ When I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
1663+ And I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
1664+ """
1665+ contract_url: https://contracts.canonical.com
1666+ data_dir: /var/lib/ubuntu-advantage
1667+ log_file: /var/log/ubuntu-advantage.log
1668+ log_level: debug
1669+ security_url: https://ubuntu.com/security
1670+ ua_config:
1671+ apt_http_proxy: null
1672+ apt_https_proxy: null
1673+ http_proxy: null
1674+ https_proxy: null
1675+ update_messaging_timer: 14400
1676+ update_status_timer: 0
1677+ metering_timer: 0
1678+ """
1679+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1680+ And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
1681+ Then stdout matches regexp:
1682+ """"
1683+ "update_messaging":
1684+ """
1685+ And stdout does not match regexp:
1686+ """"
1687+ "update_status":
1688+ """
1689+ When I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
1690+ And I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
1691+ """
1692+ contract_url: https://contracts.canonical.com
1693+ data_dir: /var/lib/ubuntu-advantage
1694+ log_file: /var/log/ubuntu-advantage.log
1695+ log_level: debug
1696+ security_url: https://ubuntu.com/security
1697+ ua_config:
1698+ apt_http_proxy: null
1699+ apt_https_proxy: null
1700+ http_proxy: null
1701+ https_proxy: null
1702+ update_messaging_timer: -10
1703+ update_status_timer: notanumber
1704+ metering_timer: 0
1705+ """
1706+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1707+ Then I verify that running `grep "Invalid value for update_messaging interval found in config." /var/log/ubuntu-advantage-timer.log` `with sudo` exits `0`
1708+ And I verify that running `grep "Invalid value for update_status interval found in config." /var/log/ubuntu-advantage-timer.log` `with sudo` exits `0`
1709+ And I verify that the timer interval for `update_messaging` is `21600`
1710+ And I verify that the timer interval for `update_status` is `43200`
1711+
1712+ Examples: ubuntu release
1713+ | release |
1714+ | xenial |
1715+ | bionic |
1716+ | focal |
1717+ | hirsute |
1718+
1719+ @series.lts
1720+ @uses.config.machine_type.lxd.container
1721+ Scenario Outline: Run timer script on an attached machine
1722+ Given a `<release>` machine with ubuntu-advantage-tools installed
1723+ When I attach `contract_token` with sudo
1724+ And I create the file `/tmp/machine-token-overlay.json` with the following:
1725+ """
1726+ {
1727+ "machineTokenInfo": {
1728+ "contractInfo": {
1729+ "id": "testCID"
1730+ },
1731+ "machineId": "testMID"
1732+ }
1733+ }
1734+ """
1735+ And I create the file `/tmp/response-overlay.json` with the following:
1736+ """
1737+ {
1738+ "https://contracts.canonical.com/v1/contracts/testCID/machine-activity/testMID": [
1739+ {
1740+ "code": 200,
1741+ "response": {
1742+ "activityToken": "test",
1743+ "activityID": "ac-id",
1744+ "machineTokenInfo": {
1745+ "contractInfo": {
1746+ "resourceEntitlements": [
1747+ {
1748+ "type": "cc-eal",
1749+ "entitled": false
1750+ }
1751+ ]
1752+ },
1753+ "machineId": "new-machine-id"
1754+ }
1755+ }
1756+ }
1757+ ]
1758+ }
1759+ """
1760+ And I append the following on uaclient config:
1761+ """
1762+ features:
1763+ machine_token_overlay: "/tmp/machine-token-overlay.json"
1764+ serviceclient_url_responses: "/tmp/response-overlay.json"
1765+ """
1766+ And I run `ua config set metering_timer=14400` with sudo
1767+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1768+ Then I verify that running `grep -q activityToken /var/lib/ubuntu-advantage/private/machine-token.json` `with sudo` exits `0`
1769+ And I verify that running `grep -q activityID /var/lib/ubuntu-advantage/private/machine-token.json` `with sudo` exits `0`
1770+ When I run `cat /var/lib/ubuntu-advantage/private/machine-id` with sudo
1771+ Then stdout matches regexp:
1772+ """
1773+ new-machine-id
1774+ """
1775+ When I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
1776+ Then stdout matches regexp:
1777+ """
1778+ \"metering\"
1779+ """
1780+
1781+ Examples: ubuntu release
1782+ | release |
1783+ | xenial |
1784+ | bionic |
1785+ | focal |
1786+
1787+ @series.lts
1788+ @uses.config.machine_type.lxd.container
1789+ Scenario Outline: Run collect-logs on an attached machine
1790+ Given a `<release>` machine with ubuntu-advantage-tools installed
1791+ When I attach `contract_token` with sudo
1792+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
1793+ And I verify that running `ua collect-logs` `as non-root` exits `1`
1794+ Then I will see the following on stderr:
1795+ """
1796+ This command must be run as root (try using sudo).
1797+ """
1798+ When I run `ua collect-logs` with sudo
1799+ Then I verify that files exist matching `ua_logs.tar.gz`
1800+ When I run `tar zxf ua_logs.tar.gz` as non-root
1801+ Then I verify that files exist matching `logs/`
1802+ When I run `sh -c "ls -1 logs/ | sort -d"` as non-root
1803+ # On Xenial, the return value for inexistent services is the same as for dead ones (3).
1804+ # So the -error suffix does not appear there.
1805+ Then stdout matches regexp:
1806+ """
1807+ cloud-id.txt
1808+ jobs-status.json
1809+ journalctl.txt
1810+ livepatch-status.txt-error
1811+ systemd-timers.txt
1812+ ua-auto-attach.path.txt(-error)?
1813+ ua-auto-attach.service.txt(-error)?
1814+ uaclient.conf
1815+ ua-license-check.path.txt
1816+ ua-license-check.service.txt
1817+ ua-license-check.timer.txt
1818+ ua-reboot-cmds.service.txt
1819+ ua-status.json
1820+ ua-timer.service.txt
1821+ ua-timer.timer.txt
1822+ ubuntu-advantage-license-check.log
1823+ ubuntu-advantage.log
1824+ ubuntu-advantage-timer.log
1825+ ubuntu-esm-apps.list
1826+ ubuntu-esm-infra.list
1827+ """
1828+ Examples: ubuntu release
1829+ | release |
1830+ | xenial |
1831+ | bionic |
1832+ | focal |
1833diff --git a/features/attached_enable.feature b/features/attached_enable.feature
1834index c8d49c2..63e8daa 100644
1835--- a/features/attached_enable.feature
1836+++ b/features/attached_enable.feature
1837@@ -1,8 +1,26 @@
1838 @uses.config.contract_token
1839 Feature: Enable command behaviour when attached to an UA subscription
1840
1841+ @series.xenial
1842+ @uses.config.machine_type.lxd.container
1843+ Scenario: Attached enable Common Criteria service in an ubuntu lxd container
1844+ Given a `xenial` machine with ubuntu-advantage-tools installed
1845+ When I attach `contract_token` with sudo
1846+ Then I verify that running `ua enable cc-eal` `as non-root` exits `1`
1847+ And I will see the following on stderr:
1848+ """
1849+ This command must be run as root (try using sudo).
1850+ """
1851+ When I verify that running `ua enable cc-eal --beta` `with sudo` exits `1`
1852+ Then I will see the following on stdout:
1853+ """
1854+ One moment, checking your subscription first
1855+ GPG key '/usr/share/keyrings/ubuntu-cc-keyring.gpg' not found.
1856+ """
1857+
1858 @series.all
1859- Scenario Outline: Attached enable Common Criteria service in a ubuntu machine
1860+ @uses.config.machine_type.lxd.container
1861+ Scenario Outline: Attached enable Common Criteria service in an ubuntu lxd container
1862 Given a `<release>` machine with ubuntu-advantage-tools installed
1863 When I attach `contract_token` with sudo
1864 Then I verify that running `ua enable cc-eal` `as non-root` exits `1`
1865@@ -31,10 +49,10 @@ Feature: Enable command behaviour when attached to an UA subscription
1866 | release | msg |
1867 | bionic | CC EAL2 is not available for Ubuntu 18.04 LTS (Bionic Beaver). |
1868 | focal | CC EAL2 is not available for Ubuntu 20.04 LTS (Focal Fossa). |
1869- | groovy | CC EAL2 is not available for Ubuntu 20.10 (Groovy Gorilla). |
1870 | hirsute | CC EAL2 is not available for Ubuntu 21.04 (Hirsute Hippo). |
1871
1872 @series.lts
1873+ @uses.config.machine_type.lxd.container
1874 Scenario Outline: Attached enable of a service in a ubuntu machine
1875 Given a `<release>` machine with ubuntu-advantage-tools installed
1876 When I attach `contract_token` with sudo
1877@@ -124,12 +142,32 @@ Feature: Enable command behaviour when attached to an UA subscription
1878 | bionic |
1879 | focal |
1880 | xenial |
1881- | groovy |
1882 | hirsute |
1883
1884 @series.lts
1885+ @uses.config.machine_type.lxd.container
1886 Scenario Outline: Attached enable not entitled service in a ubuntu machine
1887 Given a `<release>` machine with ubuntu-advantage-tools installed
1888+ When I create the file `/tmp/machine-token-overlay.json` with the following:
1889+ """
1890+ {
1891+ "machineTokenInfo": {
1892+ "contractInfo": {
1893+ "resourceEntitlements": [
1894+ {
1895+ "type": "esm-apps",
1896+ "entitled": false
1897+ }
1898+ ]
1899+ }
1900+ }
1901+ }
1902+ """
1903+ And I append the following on uaclient config:
1904+ """
1905+ features:
1906+ machine_token_overlay: "/tmp/machine-token-overlay.json"
1907+ """
1908 When I attach `contract_token` with sudo
1909 Then I verify that running `ua enable esm-apps` `as non-root` exits `1`
1910 And I will see the following on stderr:
1911@@ -151,6 +189,7 @@ Feature: Enable command behaviour when attached to an UA subscription
1912 | xenial |
1913
1914 @series.lts
1915+ @uses.config.machine_type.lxd.container
1916 Scenario Outline: Attached enable of cis service in a ubuntu machine
1917 Given a `<release>` machine with ubuntu-advantage-tools installed
1918 When I attach `contract_token` with sudo
1919@@ -245,13 +284,14 @@ Feature: Enable command behaviour when attached to an UA subscription
1920 @series.bionic
1921 @series.xenial
1922 @uses.config.machine_type.lxd.vm
1923- Scenario Outline: Attached enable of vm-based services in a bionic lxd vm
1924+ Scenario Outline: Attached disable of livepatch in a lxd vm
1925 Given a `<release>` machine with ubuntu-advantage-tools installed
1926 When I attach `contract_token` with sudo
1927 And I run `ua status` with sudo
1928 Then stdout matches regexp:
1929 """
1930 cis +yes +disabled +Center for Internet Security Audit Tools
1931+ esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\)
1932 esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\)
1933 fips +yes +disabled +NIST-certified core packages
1934 fips-updates +yes +disabled +NIST-certified core packages with priority security updates
1935@@ -268,6 +308,7 @@ Feature: Enable command behaviour when attached to an UA subscription
1936 Then stdout matches regexp:
1937 """
1938 cis +yes +disabled +Center for Internet Security Audit Tools
1939+ esm-apps +yes +enabled +UA Apps: Extended Security Maintenance \(ESM\)
1940 esm-infra +yes +enabled +UA Infra: Extended Security Maintenance \(ESM\)
1941 fips +yes +disabled +NIST-certified core packages
1942 fips-updates +yes +disabled +NIST-certified core packages with priority security updates
1943@@ -313,7 +354,7 @@ Feature: Enable command behaviour when attached to an UA subscription
1944
1945 @series.bionic
1946 @uses.config.machine_type.lxd.vm
1947- Scenario: Attached enable fips on a machine with livepatch active
1948+ Scenario: Attached enable livepatch on a machine with fips active
1949 Given a `bionic` machine with ubuntu-advantage-tools installed
1950 When I attach `contract_token` with sudo
1951 Then stdout matches regexp:
1952@@ -347,7 +388,7 @@ Feature: Enable command behaviour when attached to an UA subscription
1953
1954 @series.bionic
1955 @uses.config.machine_type.lxd.vm
1956- Scenario: Attached enable livepatch on a machine with fips active
1957+ Scenario: Attached enable fips on a machine with livepatch active
1958 Given a `bionic` machine with ubuntu-advantage-tools installed
1959 When I attach `contract_token` with sudo
1960 Then stdout matches regexp:
1961@@ -448,3 +489,155 @@ Feature: Enable command behaviour when attached to an UA subscription
1962 | release |
1963 | bionic |
1964 | xenial |
1965+
1966+ @series.lts
1967+ @uses.config.contract_token
1968+ @uses.config.machine_type.lxd.container
1969+ Scenario Outline: Attached enable ros on a machine
1970+ Given a `<release>` machine with ubuntu-advantage-tools installed
1971+ When I attach `contract_token` with sudo
1972+ And I run `ua status --all` as non-root
1973+ Then stdout matches regexp
1974+ """
1975+ ros yes disabled Security Updates for the Robot Operating System
1976+ """
1977+ When I run `ua enable ros --assume-yes --beta` with sudo
1978+ And I run `ua status --all` as non-root
1979+ Then stdout matches regexp
1980+ """
1981+ ros yes enabled Security Updates for the Robot Operating System
1982+ """
1983+ And stdout matches regexp
1984+ """
1985+ esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\)
1986+ """
1987+ And stdout matches regexp
1988+ """
1989+ esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\)
1990+ """
1991+ When I verify that running `ua disable esm-apps` `with sudo` and stdin `N` exits `1`
1992+ Then stdout matches regexp
1993+ """
1994+ ROS ESM Security Updates depends on UA Apps: ESM.
1995+ Disable ROS ESM Security Updates and proceed to disable UA Apps: ESM\? \(y\/N\) Cannot disable UA Apps: ESM when ROS ESM Security Updates is enabled.
1996+ """
1997+ When I run `ua disable esm-apps` `with sudo` and stdin `y`
1998+ Then stdout matches regexp
1999+ """
2000+ ROS ESM Security Updates depends on UA Apps: ESM.
2001+ Disable ROS ESM Security Updates and proceed to disable UA Apps: ESM\? \(y\/N\) Disabling dependent service: ROS ESM Security Updates
2002+ Updating package lists
2003+ """
2004+ When I run `ua status --all` as non-root
2005+ Then stdout matches regexp
2006+ """
2007+ ros yes disabled Security Updates for the Robot Operating System
2008+ """
2009+ And stdout matches regexp
2010+ """
2011+ esm-apps yes disabled UA Apps: Extended Security Maintenance \(ESM\)
2012+ """
2013+ When I verify that running `ua enable ros --beta` `with sudo` and stdin `N` exits `1`
2014+ Then stdout matches regexp
2015+ """
2016+ ROS ESM Security Updates cannot be enabled with UA Apps: ESM disabled.
2017+ Enable UA Apps: ESM and proceed to enable ROS ESM Security Updates\? \(y\/N\) Cannot enable ROS ESM Security Updates when UA Apps: ESM is disabled.
2018+ """
2019+
2020+ When I run `ua enable ros --beta` `with sudo` and stdin `y`
2021+ Then stdout matches regexp
2022+ """
2023+ One moment, checking your subscription first
2024+ ROS ESM Security Updates cannot be enabled with UA Apps: ESM disabled.
2025+ Enable UA Apps: ESM and proceed to enable ROS ESM Security Updates\? \(y\/N\) Enabling required service: UA Apps: ESM
2026+ UA Apps: ESM enabled
2027+ Updating package lists
2028+ ROS ESM Security Updates enabled
2029+ """
2030+ When I run `ua status --all` as non-root
2031+ Then stdout matches regexp
2032+ """
2033+ ros yes enabled Security Updates for the Robot Operating System
2034+ """
2035+ And stdout matches regexp
2036+ """
2037+ esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\)
2038+ """
2039+ And stdout matches regexp
2040+ """
2041+ esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\)
2042+ """
2043+ When I run `apt-cache policy` as non-root
2044+ Then apt-cache policy for the following url has permission `500`
2045+ """
2046+ <ros-security-source> amd64 Packages
2047+ """
2048+ When I run `apt install python3-catkin-pkg -y` with sudo
2049+ Then I verify that `python3-catkin-pkg` is installed from apt source `<ros-security-source>`
2050+
2051+ When I run `ua enable ros-updates --assume-yes --beta` with sudo
2052+ And I run `ua status --all` as non-root
2053+ Then stdout matches regexp
2054+ """
2055+ ros-updates yes enabled All Updates for the Robot Operating System
2056+ """
2057+ When I run `apt-cache policy` as non-root
2058+ Then apt-cache policy for the following url has permission `500`
2059+ """
2060+ <ros-updates-source> amd64 Packages
2061+ """
2062+ When I run `apt install python3-catkin-pkg -y` with sudo
2063+ Then I verify that `python3-catkin-pkg` is installed from apt source `<ros-updates-source>`
2064+ When I run `ua disable ros` `with sudo` and stdin `y`
2065+ Then stdout matches regexp
2066+ """
2067+ ROS ESM All Updates depends on ROS ESM Security Updates.
2068+ Disable ROS ESM All Updates and proceed to disable ROS ESM Security Updates\? \(y\/N\) Disabling dependent service: ROS ESM All Updates
2069+ Updating package lists
2070+ """
2071+ When I run `ua enable ros-updates --beta` `with sudo` and stdin `y`
2072+ Then stdout matches regexp
2073+ """
2074+ One moment, checking your subscription first
2075+ ROS ESM All Updates cannot be enabled with ROS ESM Security Updates disabled.
2076+ Enable ROS ESM Security Updates and proceed to enable ROS ESM All Updates\? \(y\/N\) Enabling required service: ROS ESM Security Updates
2077+ ROS ESM Security Updates enabled
2078+ Updating package lists
2079+ ROS ESM All Updates enabled
2080+ """
2081+ When I run `ua status --all` as non-root
2082+ Then stdout matches regexp
2083+ """
2084+ ros-updates yes enabled All Updates for the Robot Operating System
2085+ """
2086+ And stdout matches regexp
2087+ """
2088+ ros yes enabled Security Updates for the Robot Operating System
2089+ """
2090+ When I run `ua disable ros-updates --assume-yes` with sudo
2091+ When I run `ua disable ros --assume-yes` with sudo
2092+ When I run `ua disable esm-apps --assume-yes` with sudo
2093+ When I run `ua disable esm-infra --assume-yes` with sudo
2094+ When I run `ua enable ros-updates --assume-yes --beta` with sudo
2095+ When I run `ua status --all` as non-root
2096+ Then stdout matches regexp
2097+ """
2098+ ros-updates yes enabled All Updates for the Robot Operating System
2099+ """
2100+ And stdout matches regexp
2101+ """
2102+ ros yes enabled Security Updates for the Robot Operating System
2103+ """
2104+ And stdout matches regexp
2105+ """
2106+ esm-apps yes enabled UA Apps: Extended Security Maintenance \(ESM\)
2107+ """
2108+ And stdout matches regexp
2109+ """
2110+ esm-infra yes enabled UA Infra: Extended Security Maintenance \(ESM\)
2111+ """
2112+
2113+ Examples: ubuntu release
2114+ | release | ros-security-source | ros-updates-source |
2115+ | xenial | https://esm.ubuntu.com/ros/ubuntu xenial-security/main | https://esm.ubuntu.com/ros-updates/ubuntu xenial-updates/main |
2116+ | bionic | https://esm.ubuntu.com/ros/ubuntu bionic-security/main | https://esm.ubuntu.com/ros-updates/ubuntu bionic-updates/main |
2117diff --git a/features/attached_status.feature b/features/attached_status.feature
2118new file mode 100644
2119index 0000000..62da122
2120--- /dev/null
2121+++ b/features/attached_status.feature
2122@@ -0,0 +1,29 @@
2123+@uses.config.contract_token
2124+Feature: Attached status
2125+
2126+ @series.all
2127+ @uses.config.machine_type.lxd.container
2128+ Scenario Outline: Attached status in a ubuntu machine - formatted
2129+ Given a `<release>` machine with ubuntu-advantage-tools installed
2130+ When I attach `contract_token` with sudo
2131+ And I run `ua status --format json` as non-root
2132+ Then stdout is formatted as `json` and has keys:
2133+ """
2134+ _doc _schema_version account attached config config_path contract effective
2135+ environment_vars execution_details execution_status expires machine_id notices
2136+ services version
2137+ """
2138+ When I run `ua status --format yaml` as non-root
2139+ Then stdout is formatted as `yaml` and has keys:
2140+ """
2141+ _doc _schema_version account attached config config_path contract effective
2142+ environment_vars execution_details execution_status expires machine_id notices
2143+ services version
2144+ """
2145+
2146+ Examples: ubuntu release
2147+ | release |
2148+ | bionic |
2149+ | focal |
2150+ | xenial |
2151+ | hirsute |
2152diff --git a/features/aws-ids.yaml b/features/aws-ids.yaml
2153index 2167bf9..e0198a7 100644
2154--- a/features/aws-ids.yaml
2155+++ b/features/aws-ids.yaml
2156@@ -1,3 +1,3 @@
2157-bionic: ami-0e11aa8c6a6d58146
2158-focal: ami-0383ece2c0f6de239
2159-xenial: ami-09e110a448d322f4a
2160+bionic: ami-094e9c95623db463c
2161+focal: ami-0193aa0a9df84a08b
2162+xenial: ami-06e94647aeaed1e5c
2163diff --git a/features/cloud.py b/features/cloud.py
2164index 3b5e856..86671ad 100644
2165--- a/features/cloud.py
2166+++ b/features/cloud.py
2167@@ -1,15 +1,11 @@
2168 import json
2169-import os
2170 import logging
2171-import pycloudlib # type: ignore
2172+import os
2173 import time
2174-import yaml
2175+from typing import List, Optional, Tuple
2176
2177-try:
2178- from typing import Tuple, List, Optional # noqa
2179-except ImportError:
2180- # typing isn't available on trusty, so ignore its absence
2181- pass
2182+import pycloudlib # type: ignore
2183+import yaml
2184
2185
2186 class Cloud:
2187@@ -28,13 +24,13 @@ class Cloud:
2188
2189 name = ""
2190 pro_ids_path = ""
2191- env_vars: "Tuple[str, ...]" = ()
2192+ env_vars: Tuple[str, ...] = ()
2193
2194 def __init__(
2195 self,
2196 machine_type: str,
2197- region: "Optional[str]" = None,
2198- tag: "Optional[str]" = None,
2199+ region: Optional[str] = None,
2200+ tag: Optional[str] = None,
2201 timestamp_suffix: bool = True,
2202 ) -> None:
2203 if tag:
2204@@ -69,9 +65,10 @@ class Cloud:
2205 def _create_instance(
2206 self,
2207 series: str,
2208- instance_name: "Optional[str]" = None,
2209- image_name: "Optional[str]" = None,
2210- user_data: "Optional[str]" = None,
2211+ instance_name: Optional[str] = None,
2212+ image_name: Optional[str] = None,
2213+ user_data: Optional[str] = None,
2214+ ephemeral: bool = False,
2215 ) -> pycloudlib.instance:
2216 """Create an instance for on the cloud provider.
2217
2218@@ -85,6 +82,8 @@ class Cloud:
2219 The name of the image to be used when creating the instance
2220 :param user_data:
2221 The user data to be passed when creating the instance
2222+ :param ephemeral":
2223+ If instance should be ephemeral
2224
2225 :returns:
2226 A cloud provider instance
2227@@ -108,14 +107,15 @@ class Cloud:
2228 % (result.stdout, result.stderr)
2229 )
2230
2231- print("--- cloud-init succeeded")
2232+ logging.info("--- cloud-init succeeded")
2233
2234 def launch(
2235 self,
2236 series: str,
2237- instance_name: "Optional[str]" = None,
2238- image_name: "Optional[str]" = None,
2239- user_data: "Optional[str]" = None,
2240+ instance_name: Optional[str] = None,
2241+ image_name: Optional[str] = None,
2242+ user_data: Optional[str] = None,
2243+ ephemeral: bool = False,
2244 ) -> pycloudlib.instance.BaseInstance:
2245 """Create and wait for cloud provider instance to be ready.
2246
2247@@ -129,6 +129,8 @@ class Cloud:
2248 The name of the image to be used when creating the instance
2249 :param user_data:
2250 The user data to be passed when creating the instance
2251+ :param ephemeral":
2252+ If instance should be ephemeral
2253
2254 :returns:
2255 An cloud provider instance
2256@@ -138,8 +140,9 @@ class Cloud:
2257 instance_name=instance_name,
2258 image_name=image_name,
2259 user_data=user_data,
2260+ ephemeral=ephemeral,
2261 )
2262- print(
2263+ logging.info(
2264 "--- {} instance launched: {}. Waiting for ssh access".format(
2265 self.name, inst.name
2266 )
2267@@ -150,7 +153,7 @@ class Cloud:
2268 inst.wait()
2269 break
2270 except Exception as e:
2271- print("--- Retrying instance.wait on {}".format(str(e)))
2272+ logging.info("--- Retrying instance.wait on {}".format(str(e)))
2273
2274 self._check_cloudinit_status(inst)
2275 return inst
2276@@ -168,7 +171,7 @@ class Cloud:
2277 """
2278 return instance.id
2279
2280- def format_missing_env_vars(self, missing_env_vars: "List") -> "List[str]":
2281+ def format_missing_env_vars(self, missing_env_vars: List) -> List[str]:
2282 """Format missing env vars to be displayed in log.
2283
2284 :returns:
2285@@ -176,7 +179,7 @@ class Cloud:
2286 """
2287 return [" - {}\n".format(env_var) for env_var in missing_env_vars]
2288
2289- def missing_env_vars(self) -> "List[str]":
2290+ def missing_env_vars(self) -> List[str]:
2291 """Return a list of env variables necessary for this cloud provider.
2292
2293 :returns:
2294@@ -216,8 +219,8 @@ class Cloud:
2295
2296 def manage_ssh_key(
2297 self,
2298- private_key_path: "Optional[str]" = None,
2299- key_name: "Optional[str]" = None,
2300+ private_key_path: Optional[str] = None,
2301+ key_name: Optional[str] = None,
2302 ) -> None:
2303 """Create and manage ssh key pairs to be used in the cloud provider.
2304
2305@@ -265,19 +268,16 @@ class EC2(Cloud):
2306 """
2307
2308 name = "aws"
2309- env_vars: "Tuple[str, ...]" = (
2310- "aws_access_key_id",
2311- "aws_secret_access_key",
2312- )
2313+ env_vars: Tuple[str, ...] = ("aws_access_key_id", "aws_secret_access_key")
2314 pro_ids_path = "features/aws-ids.yaml"
2315
2316 def __init__(
2317 self,
2318- aws_access_key_id: "Optional[str]",
2319- aws_secret_access_key: "Optional[str]",
2320+ aws_access_key_id: Optional[str],
2321+ aws_secret_access_key: Optional[str],
2322 machine_type: str,
2323- region: "Optional[str]" = "us-east-2",
2324- tag: "Optional[str]" = None,
2325+ region: Optional[str] = "us-east-2",
2326+ tag: Optional[str] = None,
2327 timestamp_suffix: bool = True,
2328 ) -> None:
2329 self.aws_access_key_id = aws_access_key_id
2330@@ -308,8 +308,8 @@ class EC2(Cloud):
2331
2332 def manage_ssh_key(
2333 self,
2334- private_key_path: "Optional[str]" = None,
2335- key_name: "Optional[str]" = None,
2336+ private_key_path: Optional[str] = None,
2337+ key_name: Optional[str] = None,
2338 ) -> None:
2339 """Create and manage ssh key pairs to be used in the cloud provider.
2340
2341@@ -327,7 +327,7 @@ class EC2(Cloud):
2342 self.api.delete_key(self.key_name)
2343
2344 private_key_path = "ec2-{}.pem".format(self.key_name)
2345- print(
2346+ logging.info(
2347 "--- Creating local keyfile {} for EC2".format(
2348 private_key_path
2349 )
2350@@ -343,9 +343,10 @@ class EC2(Cloud):
2351 def _create_instance(
2352 self,
2353 series: str,
2354- instance_name: "Optional[str]" = None,
2355- image_name: "Optional[str]" = None,
2356- user_data: "Optional[str]" = None,
2357+ instance_name: Optional[str] = None,
2358+ image_name: Optional[str] = None,
2359+ user_data: Optional[str] = None,
2360+ ephemeral: bool = False,
2361 ) -> pycloudlib.instance:
2362 """Launch an instance on the cloud provider.
2363
2364@@ -359,6 +360,8 @@ class EC2(Cloud):
2365 The name of the image to be used when creating the instance
2366 :param user_data:
2367 The user data to be passed when creating the instance
2368+ :param ephemeral":
2369+ If instance should be ephemeral
2370
2371 :returns:
2372 An AWS cloud provider instance
2373@@ -366,13 +369,15 @@ class EC2(Cloud):
2374 if not image_name:
2375 image_name = self.locate_image_name(series)
2376
2377- print("--- Launching AWS image {}({})".format(image_name, series))
2378+ logging.info(
2379+ "--- Launching AWS image {}({})".format(image_name, series)
2380+ )
2381 vpc = self.api.get_or_create_vpc(name="uaclient-integration")
2382
2383 try:
2384 inst = self.api.launch(image_name, user_data=user_data, vpc=vpc)
2385 except Exception as e:
2386- print(str(e))
2387+ logging.error(str(e))
2388 raise
2389
2390 return inst
2391@@ -401,7 +406,7 @@ class Azure(Cloud):
2392 """
2393
2394 name = "Azure"
2395- env_vars: "Tuple[str, ...]" = (
2396+ env_vars: Tuple[str, ...] = (
2397 "az_client_id",
2398 "az_client_secret",
2399 "az_tenant_id",
2400@@ -412,13 +417,13 @@ class Azure(Cloud):
2401 def __init__(
2402 self,
2403 machine_type: str,
2404- region: "Optional[str]" = "centralus",
2405- tag: "Optional[str]" = None,
2406+ region: Optional[str] = "centralus",
2407+ tag: Optional[str] = None,
2408 timestamp_suffix: bool = True,
2409- az_client_id: "Optional[str]" = None,
2410- az_client_secret: "Optional[str]" = None,
2411- az_tenant_id: "Optional[str]" = None,
2412- az_subscription_id: "Optional[str]" = None,
2413+ az_client_id: Optional[str] = None,
2414+ az_client_secret: Optional[str] = None,
2415+ az_tenant_id: Optional[str] = None,
2416+ az_subscription_id: Optional[str] = None,
2417 ) -> None:
2418 self.az_client_id = az_client_id
2419 self.az_client_secret = az_client_secret
2420@@ -464,8 +469,8 @@ class Azure(Cloud):
2421
2422 def manage_ssh_key(
2423 self,
2424- private_key_path: "Optional[str]" = None,
2425- key_name: "Optional[str]" = None,
2426+ private_key_path: Optional[str] = None,
2427+ key_name: Optional[str] = None,
2428 ) -> None:
2429 """Create and manage ssh key pairs to be used in the cloud provider.
2430
2431@@ -476,7 +481,7 @@ class Azure(Cloud):
2432 if not private_key_path:
2433 private_key_path = "azure-priv-{}.pem".format(self.key_name)
2434 pub_key_path = "azure-pub-{}.txt".format(self.key_name)
2435- print(
2436+ logging.info(
2437 "--- Creating local keyfile {} for Azure".format(
2438 private_key_path
2439 )
2440@@ -500,9 +505,10 @@ class Azure(Cloud):
2441 def _create_instance(
2442 self,
2443 series: str,
2444- instance_name: "Optional[str]" = None,
2445- image_name: "Optional[str]" = None,
2446- user_data: "Optional[str]" = None,
2447+ instance_name: Optional[str] = None,
2448+ image_name: Optional[str] = None,
2449+ user_data: Optional[str] = None,
2450+ ephemeral: bool = False,
2451 ) -> pycloudlib.instance:
2452 """Launch an instance on the cloud provider.
2453
2454@@ -516,6 +522,8 @@ class Azure(Cloud):
2455 The name of the image to be used when creating the instance
2456 :param user_data:
2457 The user data to be passed when creating the instance
2458+ :param ephemeral":
2459+ If instance should be ephemeral
2460
2461 :returns:
2462 An AWS cloud provider instance
2463@@ -523,7 +531,9 @@ class Azure(Cloud):
2464 if not image_name:
2465 image_name = self.locate_image_name(series)
2466
2467- print("--- Launching Azure image {}({})".format(image_name, series))
2468+ logging.info(
2469+ "--- Launching Azure image {}({})".format(image_name, series)
2470+ )
2471 inst = self.api.launch(image_id=image_name, user_data=user_data)
2472 return inst
2473
2474@@ -549,17 +559,17 @@ class GCP(Cloud):
2475 of the provided tag.
2476 """
2477
2478- env_vars: "Tuple[str, ...]" = ("gcp_credentials_path", "gcp_project")
2479+ env_vars: Tuple[str, ...] = ("gcp_credentials_path", "gcp_project")
2480
2481 def __init__(
2482 self,
2483 machine_type: str,
2484- region: "Optional[str]" = "us-west2",
2485- tag: "Optional[str]" = None,
2486+ region: Optional[str] = "us-west2",
2487+ tag: Optional[str] = None,
2488 timestamp_suffix: bool = True,
2489- zone: "Optional[str]" = "a",
2490- gcp_credentials_path: "Optional[str]" = None,
2491- gcp_project: "Optional[str]" = None,
2492+ zone: Optional[str] = "a",
2493+ gcp_credentials_path: Optional[str] = None,
2494+ gcp_project: Optional[str] = None,
2495 ) -> None:
2496 self.gcp_credentials_path = gcp_credentials_path
2497 self.gcp_project = gcp_project
2498@@ -603,9 +613,10 @@ class GCP(Cloud):
2499 def _create_instance(
2500 self,
2501 series: str,
2502- instance_name: "Optional[str]" = None,
2503- image_name: "Optional[str]" = None,
2504- user_data: "Optional[str]" = None,
2505+ instance_name: Optional[str] = None,
2506+ image_name: Optional[str] = None,
2507+ user_data: Optional[str] = None,
2508+ ephemeral: bool = False,
2509 ) -> pycloudlib.instance:
2510 """Launch an instance on the cloud provider.
2511
2512@@ -619,6 +630,8 @@ class GCP(Cloud):
2513 The name of the image to be used when creating the instance
2514 :param user_data:
2515 The user data to be passed when creating the instance
2516+ :param ephemeral":
2517+ If instance should be ephemeral
2518
2519 :returns:
2520 An AWS cloud provider instance
2521@@ -626,7 +639,9 @@ class GCP(Cloud):
2522 if not image_name:
2523 image_name = self.locate_image_name(series)
2524
2525- print("--- Launching GCP image {}({})".format(image_name, series))
2526+ logging.info(
2527+ "--- Launching GCP image {}({})".format(image_name, series)
2528+ )
2529 inst = self.api.launch(image_id=image_name, user_data=user_data)
2530 return inst
2531
2532@@ -634,6 +649,20 @@ class GCP(Cloud):
2533 class _LXD(Cloud):
2534 name = "_lxd"
2535
2536+ def __init__(
2537+ self,
2538+ machine_type: str,
2539+ region: Optional[str] = None,
2540+ tag: Optional[str] = None,
2541+ timestamp_suffix: bool = True,
2542+ ) -> None:
2543+ super().__init__(
2544+ machine_type=machine_type,
2545+ region=region,
2546+ tag=tag,
2547+ timestamp_suffix=timestamp_suffix,
2548+ )
2549+
2550 @property
2551 def pycloudlib_cls(self):
2552 """Return the pycloudlib cls to be used as an api."""
2553@@ -642,9 +671,10 @@ class _LXD(Cloud):
2554 def _create_instance(
2555 self,
2556 series: str,
2557- instance_name: "Optional[str]" = None,
2558- image_name: "Optional[str]" = None,
2559- user_data: "Optional[str]" = None,
2560+ instance_name: Optional[str] = None,
2561+ image_name: Optional[str] = None,
2562+ user_data: Optional[str] = None,
2563+ ephemeral: bool = False,
2564 ) -> pycloudlib.instance:
2565 """Launch an instance on the cloud provider.
2566
2567@@ -658,6 +688,8 @@ class _LXD(Cloud):
2568 The name of the image to be used when creating the instance
2569 :param user_data:
2570 The user data to be passed when creating the instance
2571+ :param ephemeral":
2572+ If instance should be ephemeral
2573
2574 :returns:
2575 An AWS cloud provider instance
2576@@ -667,14 +699,24 @@ class _LXD(Cloud):
2577
2578 image_type = self.name.title().replace("-", " ")
2579
2580- print(
2581+ logging.info(
2582 "--- Launching {} image {}({})".format(
2583 image_type, image_name, series
2584 )
2585 )
2586
2587+ if self.name == "lxd-virtual-machine" and series == "xenial":
2588+ # Livepatch won't apply patches on Xenial with secure boot enabled
2589+ config_dict = {"security.secureboot": False}
2590+ else:
2591+ config_dict = {}
2592+
2593 inst = self.api.launch(
2594- name=instance_name, image_id=image_name, user_data=user_data
2595+ name=instance_name,
2596+ image_id=image_name,
2597+ user_data=user_data,
2598+ ephemeral=ephemeral,
2599+ config_dict=config_dict,
2600 )
2601 return inst
2602
2603diff --git a/features/enable_fips_cloud.feature b/features/enable_fips_cloud.feature
2604new file mode 100644
2605index 0000000..bab8338
2606--- /dev/null
2607+++ b/features/enable_fips_cloud.feature
2608@@ -0,0 +1,606 @@
2609+@uses.config.contract_token
2610+Feature: FIPS enablement in cloud based machines
2611+
2612+ @series.lts
2613+ @uses.config.machine_type.gcp.generic
2614+ Scenario Outline: Attached enable of FIPS services in an ubuntu gcp vm
2615+ Given a `<release>` machine with ubuntu-advantage-tools installed
2616+ When I attach `contract_token` with sudo
2617+ Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
2618+ And stdout matches regexp:
2619+ """
2620+ Ubuntu <release_title> does not provide a GCP optimized FIPS kernel
2621+ """
2622+
2623+ Examples: fips
2624+ | release | release_title | fips_service |
2625+ | xenial | Xenial | fips |
2626+ | xenial | Xenial | fips-updates |
2627+ | focal | Focal | fips |
2628+ | focal | Focal | fips-updates |
2629+
2630+ @series.xenial
2631+ @uses.config.machine_type.azure.generic
2632+ Scenario Outline: Enable FIPS services in an ubuntu Xenial Azure vm
2633+ Given a `xenial` machine with ubuntu-advantage-tools installed
2634+ When I attach `contract_token` with sudo
2635+ Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
2636+ And stdout matches regexp:
2637+ """
2638+ Ubuntu Xenial does not provide an Azure optimized FIPS kernel
2639+ """
2640+
2641+ Examples: fips
2642+ | fips_service |
2643+ | fips |
2644+ | fips-updates |
2645+
2646+ @series.focal
2647+ @uses.config.machine_type.azure.generic
2648+ Scenario Outline: Refuse to enable FIPS on a Focal Azure vm
2649+ Given a `focal` machine with ubuntu-advantage-tools installed
2650+ When I attach `contract_token` with sudo
2651+ Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
2652+ And stdout matches regexp:
2653+ """
2654+ Ubuntu Focal does not provide an Azure optimized FIPS kernel
2655+ """
2656+
2657+ Examples: fips
2658+ | fips_service |
2659+ | fips |
2660+ | fips-updates |
2661+
2662+ @series.focal
2663+ @uses.config.machine_type.aws.generic
2664+ Scenario Outline: Refuse to enable FIPS on a Focal AWS vm
2665+ Given a `focal` machine with ubuntu-advantage-tools installed
2666+ When I attach `contract_token` with sudo
2667+ Then I verify that running `ua enable <fips_service> --assume-yes` `with sudo` exits `1`
2668+ And stdout matches regexp:
2669+ """
2670+ Ubuntu Focal does not provide an AWS optimized FIPS kernel
2671+ """
2672+
2673+ Examples: fips
2674+ | fips_service |
2675+ | fips |
2676+ | fips-updates |
2677+
2678+
2679+ @series.bionic
2680+ @uses.config.machine_type.azure.generic
2681+ Scenario Outline: Enable FIPS in an ubuntu Bionic Azure vm
2682+ Given a `<release>` machine with ubuntu-advantage-tools installed
2683+ When I attach `contract_token` with sudo
2684+ 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
2685+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
2686+ And I run `ua enable <fips-service> --assume-yes` with sudo
2687+ Then stdout matches regexp:
2688+ """
2689+ Updating package lists
2690+ Installing <fips-name> packages
2691+ <fips-name> enabled
2692+ A reboot is required to complete install
2693+ """
2694+ When I run `ua status --all` with sudo
2695+ Then stdout matches regexp:
2696+ """
2697+ <fips-service> +yes enabled
2698+ """
2699+ And I verify that running `apt update` `with sudo` exits `0`
2700+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
2701+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
2702+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
2703+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
2704+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
2705+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
2706+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
2707+ When I run `apt-cache policy ubuntu-azure-fips` as non-root
2708+ Then stdout does not match regexp:
2709+ """
2710+ .*Installed: \(none\)
2711+ """
2712+ When I reboot the `<release>` machine
2713+ And I run `uname -r` as non-root
2714+ Then stdout matches regexp:
2715+ """
2716+ azure-fips
2717+ """
2718+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
2719+ Then I will see the following on stdout:
2720+ """
2721+ 1
2722+ """
2723+ When I run `ua disable <fips-service> --assume-yes` with sudo
2724+ Then stdout matches regexp:
2725+ """
2726+ Updating package lists
2727+ """
2728+ When I run `apt-cache policy ubuntu-azure-fips` as non-root
2729+ Then stdout matches regexp:
2730+ """
2731+ .*Installed: \(none\)
2732+ """
2733+ When I reboot the `<release>` machine
2734+ Then I verify that `openssh-server` installed version matches regexp `fips`
2735+ And I verify that `openssh-client` installed version matches regexp `fips`
2736+ And I verify that `strongswan` installed version matches regexp `fips`
2737+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
2738+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
2739+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
2740+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
2741+ Then I will see the following on stdout:
2742+ """
2743+ openssh-client was already not hold.
2744+ openssh-server was already not hold.
2745+ strongswan was already not hold.
2746+ """
2747+ When I run `ua status --all` with sudo
2748+ Then stdout matches regexp:
2749+ """
2750+ <fips-service> +yes disabled
2751+ """
2752+
2753+ Examples: ubuntu release
2754+ | release | fips-name | fips-service |fips-apt-source |
2755+ | bionic | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu bionic/main |
2756+
2757+ @series.focal
2758+ @uses.config.machine_type.azure.generic
2759+ Scenario Outline: Enable FIPS in an ubuntu Focal Azure vm
2760+ Given a `<release>` machine with ubuntu-advantage-tools installed
2761+ When I attach `contract_token` with sudo
2762+ 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
2763+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
2764+ And I append the following on uaclient config:
2765+ """
2766+ features:
2767+ allow_default_fips_metapackage_on_focal_cloud: true
2768+ """
2769+ And I run `ua enable <fips-service> --assume-yes` with sudo
2770+ Then stdout matches regexp:
2771+ """
2772+ Updating package lists
2773+ Installing <fips-name> packages
2774+ <fips-name> strongswan-hmac package could not be installed
2775+ <fips-name> enabled
2776+ A reboot is required to complete install
2777+ """
2778+ When I run `ua status --all` with sudo
2779+ Then stdout matches regexp:
2780+ """
2781+ <fips-service> +yes enabled
2782+ """
2783+ And I verify that running `apt update` `with sudo` exits `0`
2784+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
2785+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
2786+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
2787+ When I run `apt-cache policy ubuntu-fips` as non-root
2788+ Then stdout does not match regexp:
2789+ """
2790+ .*Installed: \(none\)
2791+ """
2792+ When I reboot the `<release>` machine
2793+ And I run `uname -r` as non-root
2794+ Then stdout matches regexp:
2795+ """
2796+ fips
2797+ """
2798+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
2799+ Then I will see the following on stdout:
2800+ """
2801+ 1
2802+ """
2803+ When I run `ua disable <fips-service> --assume-yes` with sudo
2804+ Then stdout matches regexp:
2805+ """
2806+ Updating package lists
2807+ """
2808+ When I run `apt-cache policy ubuntu-fips` as non-root
2809+ Then stdout matches regexp:
2810+ """
2811+ .*Installed: \(none\)
2812+ """
2813+ When I reboot the `<release>` machine
2814+ Then I verify that `openssh-server` installed version matches regexp `fips`
2815+ And I verify that `openssh-client` installed version matches regexp `fips`
2816+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
2817+ Then I will see the following on stdout:
2818+ """
2819+ openssh-client was already not hold.
2820+ openssh-server was already not hold.
2821+ strongswan was already not hold.
2822+ """
2823+ When I run `ua status --all` with sudo
2824+ Then stdout matches regexp:
2825+ """
2826+ <fips-service> +yes disabled
2827+ """
2828+
2829+ Examples: ubuntu release
2830+ | release | fips-name | fips-service |fips-apt-source |
2831+ | focal | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu focal/main |
2832+
2833+ @series.xenial
2834+ @uses.config.machine_type.aws.generic
2835+ Scenario Outline: Attached FIPS in an ubuntu Xenial AWS vm
2836+ Given a `<release>` machine with ubuntu-advantage-tools installed
2837+ When I attach `contract_token` with sudo
2838+ And I run `ua disable livepatch` with sudo
2839+ 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
2840+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
2841+ And I run `ua enable <fips-service> --assume-yes` with sudo
2842+ Then stdout matches regexp:
2843+ """
2844+ Updating package lists
2845+ Installing <fips-name> packages
2846+ <fips-name> enabled
2847+ A reboot is required to complete install
2848+ """
2849+ When I run `ua status --all` with sudo
2850+ Then stdout matches regexp:
2851+ """
2852+ <fips-service> +yes enabled
2853+ """
2854+ And I verify that running `apt update` `with sudo` exits `0`
2855+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
2856+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
2857+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
2858+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
2859+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
2860+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
2861+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
2862+ When I run `apt-cache policy ubuntu-fips` as non-root
2863+ Then stdout does not match regexp:
2864+ """
2865+ .*Installed: \(none\)
2866+ """
2867+ When I reboot the `<release>` machine
2868+ And I run `uname -r` as non-root
2869+ Then stdout matches regexp:
2870+ """
2871+ fips
2872+ """
2873+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
2874+ Then I will see the following on stdout:
2875+ """
2876+ 1
2877+ """
2878+ When I run `ua disable <fips-service> --assume-yes` with sudo
2879+ Then stdout matches regexp:
2880+ """
2881+ Updating package lists
2882+ """
2883+ When I run `apt-cache policy ubuntu-fips` as non-root
2884+ Then stdout matches regexp:
2885+ """
2886+ .*Installed: \(none\)
2887+ """
2888+ When I reboot the `<release>` machine
2889+ Then I verify that `openssh-server` installed version matches regexp `fips`
2890+ And I verify that `openssh-client` installed version matches regexp `fips`
2891+ And I verify that `strongswan` installed version matches regexp `fips`
2892+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
2893+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
2894+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
2895+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
2896+ Then I will see the following on stdout:
2897+ """
2898+ openssh-client was already not hold.
2899+ openssh-server was already not hold.
2900+ strongswan was already not hold.
2901+ """
2902+ When I run `ua status --all` with sudo
2903+ Then stdout matches regexp:
2904+ """
2905+ <fips-service> +yes disabled
2906+ """
2907+
2908+ Examples: ubuntu release
2909+ | release | fips-name | fips-service |fips-apt-source |
2910+ | xenial | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu xenial/main |
2911+
2912+ @series.bionic
2913+ @uses.config.machine_type.aws.generic
2914+ Scenario Outline: Attached enable of FIPS in an ubuntu Bionic AWS vm
2915+ Given a `<release>` machine with ubuntu-advantage-tools installed
2916+ When I attach `contract_token` with sudo
2917+ And I run `ua disable livepatch` with sudo
2918+ 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
2919+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
2920+ And I run `ua enable <fips-service> --assume-yes` with sudo
2921+ Then stdout matches regexp:
2922+ """
2923+ Updating package lists
2924+ Installing <fips-name> packages
2925+ <fips-name> enabled
2926+ A reboot is required to complete install
2927+ """
2928+ When I run `ua status --all` with sudo
2929+ Then stdout matches regexp:
2930+ """
2931+ <fips-service> +yes enabled
2932+ """
2933+ And I verify that running `apt update` `with sudo` exits `0`
2934+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
2935+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
2936+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
2937+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
2938+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
2939+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
2940+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
2941+ When I run `apt-cache policy ubuntu-aws-fips` as non-root
2942+ Then stdout does not match regexp:
2943+ """
2944+ .*Installed: \(none\)
2945+ """
2946+ When I reboot the `<release>` machine
2947+ And I run `uname -r` as non-root
2948+ Then stdout matches regexp:
2949+ """
2950+ aws-fips
2951+ """
2952+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
2953+ Then I will see the following on stdout:
2954+ """
2955+ 1
2956+ """
2957+ When I run `ua disable <fips-service> --assume-yes` with sudo
2958+ Then stdout matches regexp:
2959+ """
2960+ Updating package lists
2961+ """
2962+ When I run `apt-cache policy ubuntu-aws-fips` as non-root
2963+ Then stdout matches regexp:
2964+ """
2965+ .*Installed: \(none\)
2966+ """
2967+ When I reboot the `<release>` machine
2968+ Then I verify that `openssh-server` installed version matches regexp `fips`
2969+ And I verify that `openssh-client` installed version matches regexp `fips`
2970+ And I verify that `strongswan` installed version matches regexp `fips`
2971+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
2972+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
2973+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
2974+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
2975+ Then I will see the following on stdout:
2976+ """
2977+ openssh-client was already not hold.
2978+ openssh-server was already not hold.
2979+ strongswan was already not hold.
2980+ """
2981+ When I run `ua status --all` with sudo
2982+ Then stdout matches regexp:
2983+ """
2984+ <fips-service> +yes disabled
2985+ """
2986+
2987+ Examples: ubuntu release
2988+ | release | fips-name | fips-service |fips-apt-source |
2989+ | bionic | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu bionic/main |
2990+
2991+ @series.focal
2992+ @uses.config.machine_type.aws.generic
2993+ Scenario Outline: Attached enable of FIPS in an ubuntu Focal AWS vm
2994+ Given a `<release>` machine with ubuntu-advantage-tools installed
2995+ When I attach `contract_token` with sudo
2996+ And I run `ua disable livepatch` with sudo
2997+ 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
2998+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
2999+ And I append the following on uaclient config:
3000+ """
3001+ features:
3002+ allow_default_fips_metapackage_on_focal_cloud: true
3003+ """
3004+ And I run `ua enable <fips-service> --assume-yes` with sudo
3005+ Then stdout matches regexp:
3006+ """
3007+ Updating package lists
3008+ Installing <fips-name> packages
3009+ <fips-name> strongswan-hmac package could not be installed
3010+ <fips-name> enabled
3011+ A reboot is required to complete install
3012+ """
3013+ When I run `ua status --all` with sudo
3014+ Then stdout matches regexp:
3015+ """
3016+ <fips-service> +yes enabled
3017+ """
3018+ And I verify that running `apt update` `with sudo` exits `0`
3019+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
3020+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3021+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3022+ When I run `apt-cache policy ubuntu-fips` as non-root
3023+ Then stdout does not match regexp:
3024+ """
3025+ .*Installed: \(none\)
3026+ """
3027+ When I reboot the `<release>` machine
3028+ And I run `uname -r` as non-root
3029+ Then stdout matches regexp:
3030+ """
3031+ fips
3032+ """
3033+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3034+ Then I will see the following on stdout:
3035+ """
3036+ 1
3037+ """
3038+ When I run `ua disable <fips-service> --assume-yes` with sudo
3039+ Then stdout matches regexp:
3040+ """
3041+ Updating package lists
3042+ """
3043+ When I run `apt-cache policy ubuntu-fips` as non-root
3044+ Then stdout matches regexp:
3045+ """
3046+ .*Installed: \(none\)
3047+ """
3048+ When I reboot the `<release>` machine
3049+ Then I verify that `openssh-server` installed version matches regexp `fips`
3050+ And I verify that `openssh-client` installed version matches regexp `fips`
3051+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3052+ Then I will see the following on stdout:
3053+ """
3054+ openssh-client was already not hold.
3055+ openssh-server was already not hold.
3056+ strongswan was already not hold.
3057+ """
3058+ When I run `ua status --all` with sudo
3059+ Then stdout matches regexp:
3060+ """
3061+ <fips-service> +yes disabled
3062+ """
3063+
3064+ Examples: ubuntu release
3065+ | release | fips-name | fips-service |fips-apt-source |
3066+ | focal | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu focal/main |
3067+
3068+ @series.bionic
3069+ @uses.config.machine_type.gcp.generic
3070+ Scenario Outline: Attached enable of FIPS in an ubuntu Bionic GCP vm
3071+ Given a `<release>` machine with ubuntu-advantage-tools installed
3072+ When I attach `contract_token` with sudo
3073+ 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
3074+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
3075+ And I run `ua enable <fips-service> --assume-yes` with sudo
3076+ Then stdout matches regexp:
3077+ """
3078+ Updating package lists
3079+ Installing <fips-name> packages
3080+ <fips-name> enabled
3081+ A reboot is required to complete install
3082+ """
3083+ When I run `ua status --all` with sudo
3084+ Then stdout matches regexp:
3085+ """
3086+ <fips-service> +yes enabled
3087+ """
3088+ And I verify that running `apt update` `with sudo` exits `0`
3089+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
3090+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3091+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3092+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3093+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
3094+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
3095+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3096+ When I run `apt-cache policy ubuntu-gcp-fips` as non-root
3097+ Then stdout does not match regexp:
3098+ """
3099+ .*Installed: \(none\)
3100+ """
3101+ When I reboot the `<release>` machine
3102+ And I run `uname -r` as non-root
3103+ Then stdout matches regexp:
3104+ """
3105+ gcp-fips
3106+ """
3107+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3108+ Then I will see the following on stdout:
3109+ """
3110+ 1
3111+ """
3112+ When I run `ua disable <fips-service> --assume-yes` with sudo
3113+ Then stdout matches regexp:
3114+ """
3115+ Updating package lists
3116+ """
3117+ When I run `apt-cache policy ubuntu-gcp-fips` as non-root
3118+ Then stdout matches regexp:
3119+ """
3120+ .*Installed: \(none\)
3121+ """
3122+ When I reboot the `<release>` machine
3123+ Then I verify that `openssh-server` installed version matches regexp `fips`
3124+ And I verify that `openssh-client` installed version matches regexp `fips`
3125+ And I verify that `strongswan` installed version matches regexp `fips`
3126+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
3127+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
3128+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
3129+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3130+ Then I will see the following on stdout:
3131+ """
3132+ openssh-client was already not hold.
3133+ openssh-server was already not hold.
3134+ strongswan was already not hold.
3135+ """
3136+ When I run `ua status --all` with sudo
3137+ Then stdout matches regexp:
3138+ """
3139+ <fips-service> +yes disabled
3140+ """
3141+
3142+ Examples: ubuntu release
3143+ | release | fips-name | fips-service |fips-apt-source |
3144+ | bionic | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu bionic/main |
3145+
3146+ @series.bionic
3147+ @uses.config.machine_type.gcp.generic
3148+ Scenario Outline: Attached enable of FIPS in an ubuntu GCP AWS vm
3149+ Given a `<release>` machine with ubuntu-advantage-tools installed
3150+ When I attach `contract_token` with sudo
3151+ 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
3152+ And I run `ua enable <fips-service> --assume-yes` with sudo
3153+ Then stdout matches regexp:
3154+ """
3155+ Updating package lists
3156+ Installing <fips-name> packages
3157+ <fips-name> enabled
3158+ A reboot is required to complete install
3159+ """
3160+ When I run `ua status --all` with sudo
3161+ Then stdout matches regexp:
3162+ """
3163+ <fips-service> +yes enabled
3164+ """
3165+ And I verify that running `apt update` `with sudo` exits `0`
3166+ And I verify that running `grep Traceback /var/log/ubuntu-advantage.log` `with sudo` exits `1`
3167+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3168+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3169+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3170+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
3171+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
3172+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3173+ When I run `apt-cache policy ubuntu-gcp-fips` as non-root
3174+ Then stdout does not match regexp:
3175+ """
3176+ .*Installed: \(none\)
3177+ """
3178+ When I reboot the `<release>` machine
3179+ And I run `uname -r` as non-root
3180+ Then stdout matches regexp:
3181+ """
3182+ gcp-fips
3183+ """
3184+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3185+ Then I will see the following on stdout:
3186+ """
3187+ 1
3188+ """
3189+ When I run `ua disable <fips-service> --assume-yes` with sudo
3190+ Then stdout matches regexp:
3191+ """
3192+ Updating package lists
3193+ """
3194+ When I run `apt-cache policy ubuntu-gcp-fips` as non-root
3195+ Then stdout matches regexp:
3196+ """
3197+ .*Installed: \(none\)
3198+ """
3199+ When I reboot the `<release>` machine
3200+ Then I verify that `openssh-server` installed version matches regexp `fips`
3201+ And I verify that `openssh-client` installed version matches regexp `fips`
3202+ And I verify that `strongswan` installed version matches regexp `fips`
3203+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
3204+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
3205+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
3206+ When I run `ua status --all` with sudo
3207+ Then stdout matches regexp:
3208+ """
3209+ <fips-service> +yes disabled
3210+ """
3211+
3212+ Examples: ubuntu release
3213+ | release | fips-name | fips-service |fips-apt-source |
3214+ | bionic | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu bionic-updates/main |
3215diff --git a/features/enable_fips_vm.feature b/features/enable_fips_vm.feature
3216new file mode 100644
3217index 0000000..69b0b78
3218--- /dev/null
3219+++ b/features/enable_fips_vm.feature
3220@@ -0,0 +1,410 @@
3221+@uses.config.contract_token
3222+Feature: FIPS enablement in lxd VMs
3223+
3224+ @series.xenial
3225+ @series.bionic
3226+ @uses.config.machine_type.lxd.vm
3227+ Scenario Outline: Attached enable of FIPS in an ubuntu lxd vm
3228+ Given a `<release>` machine with ubuntu-advantage-tools installed
3229+ When I attach `contract_token` with sudo
3230+ And I run `ua disable livepatch` with sudo
3231+ 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]
3232+ And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
3233+ And I run `ua enable <fips-service> --assume-yes` with sudo
3234+ Then stdout matches regexp:
3235+ """
3236+ Updating package lists
3237+ Installing <fips-name> packages
3238+ <fips-name> enabled
3239+ A reboot is required to complete install
3240+ """
3241+ When I run `ua status --all` with sudo
3242+ Then stdout matches regexp:
3243+ """
3244+ <fips-service> +yes enabled
3245+ """
3246+ And stdout matches regexp:
3247+ """
3248+ FIPS support requires system reboot to complete configuration
3249+ """
3250+ And I verify that running `apt update` `with sudo` exits `0`
3251+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3252+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3253+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3254+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
3255+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
3256+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3257+ When I reboot the `<release>` machine
3258+ And I run `uname -r` as non-root
3259+ Then stdout matches regexp:
3260+ """
3261+ fips
3262+ """
3263+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3264+ Then I will see the following on stdout:
3265+ """
3266+ 1
3267+ """
3268+ When I run `ua status --all` with sudo
3269+ Then stdout does not match regexp:
3270+ """
3271+ FIPS support requires system reboot to complete configuration
3272+ """
3273+ When I run `ua disable <fips-service> --assume-yes` with sudo
3274+ Then stdout matches regexp:
3275+ """
3276+ Updating package lists
3277+ A reboot is required to complete disable operation
3278+ """
3279+ When I run `ua status --all` with sudo
3280+ Then stdout matches regexp:
3281+ """
3282+ Disabling FIPS requires system reboot to complete operation
3283+ """
3284+ When I run `apt-cache policy ubuntu-fips` as non-root
3285+ Then stdout matches regexp:
3286+ """
3287+ .*Installed: \(none\)
3288+ """
3289+ When I reboot the `<release>` machine
3290+ Then I verify that `openssh-server` installed version matches regexp `fips`
3291+ And I verify that `openssh-client` installed version matches regexp `fips`
3292+ And I verify that `strongswan` installed version matches regexp `fips`
3293+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
3294+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
3295+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
3296+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3297+ Then I will see the following on stdout:
3298+ """
3299+ openssh-client was already not hold.
3300+ openssh-server was already not hold.
3301+ strongswan was already not hold.
3302+ """
3303+ When I run `ua status --all` with sudo
3304+ Then stdout matches regexp:
3305+ """
3306+ <fips-service> +yes disabled
3307+ """
3308+ Then stdout does not match regexp:
3309+ """
3310+ Disabling FIPS requires system reboot to complete operation
3311+ """
3312+
3313+ Examples: ubuntu release
3314+ | release | fips-name | fips-service |fips-apt-source |
3315+ | xenial | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu xenial/main |
3316+ | bionic | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu bionic/main |
3317+
3318+ @series.xenial
3319+ @series.bionic
3320+ @uses.config.machine_type.lxd.vm
3321+ Scenario Outline: Attached enable of FIPS-updates in an ubuntu lxd vm
3322+ Given a `<release>` machine with ubuntu-advantage-tools installed
3323+ When I attach `contract_token` with sudo
3324+ And I run `ua disable livepatch` with sudo
3325+ 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]
3326+ When I run `ua enable <fips-service> --assume-yes` with sudo
3327+ Then stdout matches regexp:
3328+ """
3329+ Updating package lists
3330+ Installing <fips-name> packages
3331+ <fips-name> enabled
3332+ A reboot is required to complete install
3333+ """
3334+ When I run `ua status --all` with sudo
3335+ Then stdout matches regexp:
3336+ """
3337+ <fips-service> +yes enabled
3338+ """
3339+ And I verify that running `apt update` `with sudo` exits `0`
3340+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3341+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3342+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3343+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
3344+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
3345+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3346+ When I reboot the `<release>` machine
3347+ And I run `uname -r` as non-root
3348+ Then stdout matches regexp:
3349+ """
3350+ fips
3351+ """
3352+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3353+ Then I will see the following on stdout:
3354+ """
3355+ 1
3356+ """
3357+ When I run `ua disable <fips-service> --assume-yes` with sudo
3358+ Then stdout matches regexp:
3359+ """
3360+ Updating package lists
3361+ A reboot is required to complete disable operation
3362+ """
3363+ When I reboot the `<release>` machine
3364+ Then I verify that `openssh-server` installed version matches regexp `fips`
3365+ And I verify that `openssh-client` installed version matches regexp `fips`
3366+ And I verify that `strongswan` installed version matches regexp `fips`
3367+ And I verify that `openssh-server-hmac` installed version matches regexp `fips`
3368+ And I verify that `openssh-client-hmac` installed version matches regexp `fips`
3369+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
3370+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3371+ Then I will see the following on stdout:
3372+ """
3373+ openssh-client was already not hold.
3374+ openssh-server was already not hold.
3375+ strongswan was already not hold.
3376+ """
3377+ When I run `ua status --all` with sudo
3378+ Then stdout matches regexp:
3379+ """
3380+ <fips-service> +yes disabled
3381+ """
3382+ When I verify that running `ua enable fips --assume-yes` `with sudo` exits `1`
3383+ Then stdout matches regexp:
3384+ """
3385+ Cannot enable FIPS because FIPS Updates was once enabled.
3386+ """
3387+ And I verify that files exist matching `/var/lib/ubuntu-advantage/services-once-enabled`
3388+
3389+ Examples: ubuntu release
3390+ | release | fips-name | fips-service |fips-apt-source |
3391+ | xenial | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu xenial-updates/main |
3392+ | bionic | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu bionic-updates/main |
3393+
3394+ @series.focal
3395+ @uses.config.machine_type.lxd.vm
3396+ Scenario Outline: Attached enable of FIPS in an ubuntu lxd vm
3397+ Given a `<release>` machine with ubuntu-advantage-tools installed
3398+ When I attach `contract_token` with sudo
3399+ 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]
3400+ When I run `ua enable <fips-service> --assume-yes` with sudo
3401+ Then stdout matches regexp:
3402+ """
3403+ Updating package lists
3404+ Installing <fips-name> packages
3405+ FIPS strongswan-hmac package could not be installed
3406+ <fips-name> enabled
3407+ A reboot is required to complete install
3408+ """
3409+ When I run `ua status --all` with sudo
3410+ Then stdout matches regexp:
3411+ """
3412+ <fips-service> +yes enabled
3413+ """
3414+ And I verify that running `apt update` `with sudo` exits `0`
3415+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3416+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3417+ When I reboot the `<release>` machine
3418+ And I run `uname -r` as non-root
3419+ Then stdout matches regexp:
3420+ """
3421+ fips
3422+ """
3423+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3424+ Then I will see the following on stdout:
3425+ """
3426+ 1
3427+ """
3428+ When I run `ua disable <fips-service> --assume-yes` with sudo
3429+ Then stdout matches regexp:
3430+ """
3431+ Updating package lists
3432+ A reboot is required to complete disable operation
3433+ """
3434+ When I reboot the `<release>` machine
3435+ Then I verify that `openssh-server` installed version matches regexp `fips`
3436+ And I verify that `openssh-client` installed version matches regexp `fips`
3437+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3438+ Then I will see the following on stdout:
3439+ """
3440+ openssh-client was already not hold.
3441+ openssh-server was already not hold.
3442+ strongswan was already not hold.
3443+ """
3444+ When I run `ua status --all` with sudo
3445+ Then stdout matches regexp:
3446+ """
3447+ <fips-service> +yes disabled
3448+ """
3449+
3450+ Examples: ubuntu release
3451+ | release | fips-name | fips-service |fips-apt-source |
3452+ | focal | FIPS | fips |https://esm.ubuntu.com/fips/ubuntu focal/main |
3453+
3454+ @series.focal
3455+ @uses.config.machine_type.lxd.vm
3456+ Scenario Outline: Attached enable of FIPS-updates in an ubuntu lxd vm
3457+ Given a `<release>` machine with ubuntu-advantage-tools installed
3458+ When I attach `contract_token` with sudo
3459+ 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]
3460+ When I run `ua enable <fips-service> --assume-yes` with sudo
3461+ Then stdout matches regexp:
3462+ """
3463+ Updating package lists
3464+ Installing <fips-name> packages
3465+ <fips-name> enabled
3466+ A reboot is required to complete install
3467+ """
3468+ When I run `ua status --all` with sudo
3469+ Then stdout matches regexp:
3470+ """
3471+ <fips-service> +yes enabled
3472+ """
3473+ And I verify that running `apt update` `with sudo` exits `0`
3474+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3475+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3476+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3477+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3478+ When I reboot the `<release>` machine
3479+ And I run `uname -r` as non-root
3480+ Then stdout matches regexp:
3481+ """
3482+ fips
3483+ """
3484+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3485+ Then I will see the following on stdout:
3486+ """
3487+ 1
3488+ """
3489+ When I run `ua disable <fips-service> --assume-yes` with sudo
3490+ Then stdout matches regexp:
3491+ """
3492+ Updating package lists
3493+ A reboot is required to complete disable operation
3494+ """
3495+ When I reboot the `<release>` machine
3496+ Then I verify that `openssh-server` installed version matches regexp `fips`
3497+ And I verify that `openssh-client` installed version matches regexp `fips`
3498+ And I verify that `strongswan` installed version matches regexp `fips`
3499+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
3500+ When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
3501+ Then I will see the following on stdout:
3502+ """
3503+ openssh-client was already not hold.
3504+ openssh-server was already not hold.
3505+ strongswan was already not hold.
3506+ """
3507+ When I run `ua status --all` with sudo
3508+ Then stdout matches regexp:
3509+ """
3510+ <fips-service> +yes disabled
3511+ """
3512+ When I verify that running `ua enable fips --assume-yes` `with sudo` exits `1`
3513+ Then stdout matches regexp:
3514+ """
3515+ Cannot enable FIPS because FIPS Updates was once enabled.
3516+ """
3517+ And I verify that files exist matching `/var/lib/ubuntu-advantage/services-once-enabled`
3518+
3519+ Examples: ubuntu release
3520+ | release | fips-name | fips-service |fips-apt-source |
3521+ | focal | FIPS Updates | fips-updates |https://esm.ubuntu.com/fips-updates/ubuntu focal-updates/main |
3522+
3523+ @series.xenial
3524+ @series.bionic
3525+ @uses.config.machine_type.lxd.vm
3526+ Scenario Outline: Attached enable fips-updates on fips enabled vm
3527+ Given a `<release>` machine with ubuntu-advantage-tools installed
3528+ When I attach `contract_token` with sudo
3529+ And I run `ua disable livepatch` with sudo
3530+ 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]
3531+ And I run `ua enable fips --assume-yes` with sudo
3532+ Then stdout matches regexp:
3533+ """
3534+ Updating package lists
3535+ Installing FIPS packages
3536+ FIPS enabled
3537+ A reboot is required to complete install
3538+ """
3539+ When I run `ua status --all` with sudo
3540+ Then stdout matches regexp:
3541+ """
3542+ fips +yes enabled
3543+ """
3544+ When I reboot the `<release>` machine
3545+ And I run `ua enable fips-updates --assume-yes` with sudo
3546+ Then stdout matches regexp:
3547+ """
3548+ Updating package lists
3549+ Installing FIPS Updates packages
3550+ FIPS Updates enabled
3551+ A reboot is required to complete install
3552+ """
3553+ When I run `ua status --all` with sudo
3554+ Then stdout matches regexp:
3555+ """
3556+ fips +yes n/a
3557+ """
3558+ And stdout matches regexp:
3559+ """
3560+ fips-updates +yes enabled
3561+ """
3562+ When I reboot the `<release>` machine
3563+ Then I verify that running `apt update` `with sudo` exits `0`
3564+ And I verify that `ubuntu-fips` is installed from apt source `<fips-apt-source>`
3565+ And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
3566+ And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
3567+ And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
3568+ And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
3569+ And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
3570+ And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
3571+ When I run `uname -r` as non-root
3572+ Then stdout matches regexp:
3573+ """
3574+ fips
3575+ """
3576+ When I run `cat /proc/sys/crypto/fips_enabled` with sudo
3577+ Then I will see the following on stdout:
3578+ """
3579+ 1
3580+ """
3581+
3582+ Examples: ubuntu release
3583+ | release | fips-apt-source |
3584+ | xenial | https://esm.ubuntu.com/fips-updates/ubuntu xenial-updates/main |
3585+ | bionic | https://esm.ubuntu.com/fips-updates/ubuntu bionic-updates/main |
3586+
3587+ @series.xenial
3588+ @series.bionic
3589+ @uses.config.machine_type.lxd.vm
3590+ Scenario Outline: FIPS enablement message when cloud init didn't run properly
3591+ Given a `<release>` machine with ubuntu-advantage-tools installed
3592+ When I delete the file `/run/cloud-init/instance-data.json`
3593+ And I attach `contract_token` with sudo
3594+ And I run `ua disable livepatch` with sudo
3595+ And I run `ua enable fips --assume-yes` with sudo
3596+ Then stderr matches regexp:
3597+ """
3598+ Could not determine cloud, defaulting to generic FIPS package.
3599+ """
3600+ When I run `ua status --all` with sudo
3601+ Then stdout matches regexp:
3602+ """
3603+ fips +yes enabled
3604+ """
3605+
3606+ Examples: ubuntu release
3607+ | release |
3608+ | xenial |
3609+ | bionic |
3610+
3611+ @series.focal
3612+ @uses.config.machine_type.lxd.vm
3613+ Scenario Outline: FIPS enablement message when cloud init didn't run properly
3614+ Given a `<release>` machine with ubuntu-advantage-tools installed
3615+ When I delete the file `/run/cloud-init/instance-data.json`
3616+ And I attach `contract_token` with sudo
3617+ And I run `ua enable fips --assume-yes` with sudo
3618+ Then stderr matches regexp:
3619+ """
3620+ Could not determine cloud, defaulting to generic FIPS package.
3621+ """
3622+ When I run `ua status --all` with sudo
3623+ Then stdout matches regexp:
3624+ """
3625+ fips +yes enabled
3626+ """
3627+
3628+ Examples: ubuntu release
3629+ | release |
3630+ | focal |
3631diff --git a/features/environment.py b/features/environment.py
3632index 07b5cdd..d486bf0 100644
3633--- a/features/environment.py
3634+++ b/features/environment.py
3635@@ -1,25 +1,20 @@
3636 import datetime
3637-import os
3638 import itertools
3639+import logging
3640+import os
3641+import random
3642 import re
3643+import string
3644 import tempfile
3645 import textwrap
3646-import logging
3647-import pycloudlib # type: ignore
3648-
3649-try:
3650- from typing import Dict, Optional, Union, List, Tuple, Any # noqa: F401
3651-except ImportError:
3652- # typing isn't available on trusty, so ignore its absence
3653- pass
3654+from typing import Any, Dict, List, Optional, Tuple, Union # noqa: F401
3655
3656+import pycloudlib # type: ignore
3657 from behave.model import Feature, Scenario
3658-
3659 from behave.runner import Context
3660
3661 import features.cloud as cloud
3662-
3663-from features.util import emit_spinner_on_travis, lxc_get_property, build_debs
3664+from features.util import build_debs, emit_spinner_on_travis, lxc_get_property
3665
3666 ALL_SUPPORTED_SERIES = ["bionic", "focal", "xenial"]
3667
3668@@ -44,8 +39,9 @@ runcmd:
3669
3670 USERDATA_RUNCMD_ENABLE_PROPOSED = """
3671 runcmd:
3672- - printf \"deb http://archive.ubuntu.com/ubuntu/ {series}-proposed restricted main multiverse universe\" > /etc/apt/sources.list.d/uaclient-proposed.list
3673- - apt-get update
3674+ - printf \"deb http://archive.ubuntu.com/ubuntu/ {series}-proposed main\" > /etc/apt/sources.list.d/uaclient-proposed.list
3675+ - "printf \\"Package: *\\nPin: release a={series}-proposed\\nPin-Priority: 400\\n\\" > /etc/apt/preferences.d/lower-proposed"
3676+ - "printf \\"Package: ubuntu-advantage-tools\\nPin: release a={series}-proposed\\nPin-Priority: 1001\\n\\" > /etc/apt/preferences.d/uaclient-proposed"
3677 """ # noqa: E501
3678
3679 USERDATA_APT_SOURCE_PPA = """\
3680@@ -121,6 +117,8 @@ class UAClientBehaveConfig:
3681 "destroy_instances",
3682 "cache_source",
3683 "enable_proposed",
3684+ "ephemeral_instance",
3685+ "snapshot_strategy",
3686 ]
3687 str_options = [
3688 "aws_access_key_id",
3689@@ -179,6 +177,8 @@ class UAClientBehaveConfig:
3690 destroy_instances: bool = True,
3691 cache_source: bool = True,
3692 enable_proposed: bool = False,
3693+ ephemeral_instance: bool = False,
3694+ snapshot_strategy: bool = False,
3695 machine_type: str = "lxd.container",
3696 private_key_file: str = None,
3697 private_key_name: str = "uaclient-integration",
3698@@ -192,7 +192,7 @@ class UAClientBehaveConfig:
3699 ppa_keyid: str = DAILY_PPA_KEYID,
3700 userdata_file: str = None,
3701 check_version: str = None,
3702- cmdline_tags: "List" = []
3703+ cmdline_tags: List = []
3704 ) -> None:
3705 # First, store the values we've detected
3706 self.aws_access_key_id = aws_access_key_id
3707@@ -206,6 +206,8 @@ class UAClientBehaveConfig:
3708 self.build_pr = build_pr
3709 self.cache_source = cache_source
3710 self.enable_proposed = enable_proposed
3711+ self.ephemeral_instance = ephemeral_instance
3712+ self.snapshot_strategy = snapshot_strategy
3713 self.contract_token = contract_token
3714 self.contract_token_staging = contract_token_staging
3715 self.contract_token_staging_expired = contract_token_staging_expired
3716@@ -268,6 +270,14 @@ class UAClientBehaveConfig:
3717 job_suffix = job_suffix.split("PR-")[-1]
3718 timed_job_tag += str(job_suffix)
3719 timed_job_tag = timed_job_tag.replace(".", "-")
3720+
3721+ # Add 8-digit random suffix to the tag, so it does not conflict when
3722+ # spinning many jobs at the same time
3723+ random_suffix = "".join(
3724+ random.choices(string.ascii_lowercase + string.digits, k=8)
3725+ )
3726+ timed_job_tag += "-" + random_suffix
3727+
3728 if "aws" in self.machine_type:
3729 self.cloud_manager = cloud.EC2(
3730 aws_access_key_id,
3731@@ -404,7 +414,7 @@ def before_all(context: Context) -> None:
3732 )
3733
3734
3735-def _should_skip_tags(context: Context, tags: "List") -> str:
3736+def _should_skip_tags(context: Context, tags: List) -> str:
3737 """Return a reason if a feature or scenario should be skipped"""
3738 machine_type = getattr(context.config, "machine_type", "")
3739 machine_types = []
3740@@ -554,7 +564,9 @@ def after_step(context, step):
3741 artifact_file = os.path.join(
3742 artifacts_dir, os.path.basename(log_file)
3743 )
3744- print("-- pull instance:{} {}".format(log_file, artifact_file))
3745+ logging.info(
3746+ "-- pull instance:{} {}".format(log_file, artifact_file)
3747+ )
3748 try:
3749 result = context.instances["uaclient"].execute(
3750 ["cat", log_file], use_sudo=True
3751@@ -575,11 +587,13 @@ def after_step(context, step):
3752
3753 def after_all(context):
3754 if context.config.ppa == "":
3755- print(" No custom images to delete. UACLIENT_BEHAVE_PPA is unset.")
3756+ logging.info(
3757+ " No custom images to delete. UACLIENT_BEHAVE_PPA is unset."
3758+ )
3759 elif context.config.image_clean:
3760 for key, image in context.series_image_name.items():
3761 if key == context.series_reuse_image:
3762- print(
3763+ logging.info(
3764 " Not deleting this image: ",
3765 context.series_image_name[key],
3766 )
3767@@ -587,41 +601,38 @@ def after_all(context):
3768 context.config.cloud_api.delete_image(image)
3769
3770
3771-def _capture_container_as_image(
3772- container_name: str,
3773- image_name: str,
3774- cloud_api: "pycloudlib.cloud.BaseCloud",
3775+def capture_container_as_image(
3776+ container_id: str, image_name: str, cloud_api: pycloudlib.cloud.BaseCloud
3777 ) -> str:
3778 """Capture a container as an image.
3779
3780- :param container_name:
3781- The name of the container to be captured. Note that this container
3782+ :param container_id:
3783+ The id of the container to be captured. Note that this container
3784 will be stopped.
3785 :param image_name:
3786 The name under which the image should be published.
3787 :param cloud_api: Optional pycloud BaseCloud api for applicable
3788 machine_types.
3789 """
3790- print(
3791- "--- Creating base image snapshot from vm {}".format(container_name)
3792+ logging.info(
3793+ "--- Creating base image snapshot from vm {}".format(container_id)
3794 )
3795- inst = cloud_api.get_instance(container_name)
3796+ inst = cloud_api.get_instance(container_id)
3797 return cloud_api.snapshot(instance=inst)
3798
3799
3800-def build_debs_from_dev_instance(context: Context, series: str) -> "List[str]":
3801- """Create a development instance, instal build dependencies and build debs
3802+def build_debs_from_sbuild(context: Context, series: str) -> List[str]:
3803+ """Create a chroot and build the package using sbuild
3804
3805
3806 Will stop the development instance after deb build succeeds.
3807
3808 :return: A list of paths to applicable deb files published.
3809 """
3810- time_suffix = datetime.datetime.now().strftime("%s%f")
3811 deb_paths = []
3812
3813 if context.config.debs_path:
3814- print(
3815+ logging.info(
3816 "--- Checking if debs can be reused in {}".format(
3817 context.config.debs_path
3818 )
3819@@ -635,36 +646,22 @@ def build_debs_from_dev_instance(context: Context, series: str) -> "List[str]":
3820 ]
3821
3822 if len(deb_paths):
3823- print("--- Reusing debs: {}".format(", ".join(deb_paths)))
3824+ logging.info("--- Reusing debs: {}".format(", ".join(deb_paths)))
3825 else:
3826- print("--- Could not find any debs to reuse. Building it locally")
3827- print(
3828- "--- Launching vm to build ubuntu-advantage*debs from local source"
3829- )
3830- build_container_name = (
3831- "ubuntu-behave-image-pre-build-%s-" % series + time_suffix
3832- )
3833-
3834- cloud_manager = context.config.cloud_manager
3835- if "pro" in context.config.machine_type:
3836- user_data = USERDATA_BLOCK_AUTO_ATTACH_IMG
3837- else:
3838- user_data = ""
3839- inst = cloud_manager.launch(
3840- instance_name=build_container_name,
3841- series=series,
3842- user_data=user_data,
3843+ logging.info(
3844+ "--- Could not find any debs to reuse. Building it locally"
3845 )
3846
3847- build_container_name = cloud_manager.get_instance_id(inst)
3848-
3849 with emit_spinner_on_travis("Building debs from local source... "):
3850+ output_deb_dir = os.path.join(tempfile.gettempdir(), series)
3851 deb_paths = build_debs(
3852- build_container_name,
3853- output_deb_dir=os.path.join(tempfile.gettempdir(), series),
3854- cloud_api=context.config.cloud_api,
3855+ series=series,
3856+ output_deb_dir=output_deb_dir,
3857 cache_source=context.config.cache_source,
3858 )
3859+ context.config.debs_path = output_deb_dir
3860+
3861+ logging.info("--- sbuild has finished building the packages")
3862
3863 if "pro" in context.config.machine_type:
3864 return deb_paths
3865@@ -672,7 +669,9 @@ def build_debs_from_dev_instance(context: Context, series: str) -> "List[str]":
3866 return [deb_path for deb_path in deb_paths if "pro" not in deb_path]
3867
3868
3869-def create_uat_image(context: Context, series: str) -> None:
3870+def create_instance_with_uat_installed(
3871+ context: Context, series: str, name: str
3872+) -> None:
3873 """Create a given series lxd image with ubuntu-advantage-tools installed
3874
3875 This will launch a container, install ubuntu-advantage-tools, and publish
3876@@ -687,7 +686,7 @@ def create_uat_image(context: Context, series: str) -> None:
3877 """
3878
3879 if series in context.reuse_container:
3880- print(
3881+ logging.info(
3882 "\n Reusing the existing container: ",
3883 context.reuse_container[series],
3884 )
3885@@ -695,28 +694,21 @@ def create_uat_image(context: Context, series: str) -> None:
3886 ppa = context.config.ppa
3887 if ppa == "":
3888 image_name = context.config.cloud_manager.locate_image_name(series)
3889- print(
3890+ logging.info(
3891 "--- Unset UACLIENT_BEHAVE_PPA. Using ubuntu-advantage-tools "
3892 + "from image: {}".format(image_name)
3893 )
3894 context.series_image_name[series] = image_name
3895 return
3896
3897- time_suffix = datetime.datetime.now().strftime("%s%f")
3898 deb_paths = []
3899 if context.config.build_pr:
3900- deb_paths = build_debs_from_dev_instance(context, series)
3901+ deb_paths = build_debs_from_sbuild(context, series)
3902
3903- print(
3904+ logging.info(
3905 "--- Launching VM to create a base image with updated ubuntu-advantage"
3906 )
3907
3908- is_vm = bool(context.config.machine_type == "lxd.vm")
3909- build_container_name = "ubuntu-behave-image-build-%s-%s" % (
3910- "-vm" if is_vm else "",
3911- series + time_suffix,
3912- )
3913-
3914 user_data = ""
3915 ud_file = context.config.userdata_file
3916 if ud_file and os.path.exists(ud_file):
3917@@ -747,44 +739,38 @@ def create_uat_image(context: Context, series: str) -> None:
3918 ppa_url=ppa, ppa_keyid=ppa_keyid
3919 )
3920 inst = context.config.cloud_manager.launch(
3921- instance_name=build_container_name, series=series, user_data=user_data
3922+ instance_name=name, series=series, user_data=user_data
3923 )
3924- build_container_name = context.config.cloud_manager.get_instance_id(inst)
3925+ instance_id = context.config.cloud_manager.get_instance_id(inst)
3926
3927 _install_uat_in_container(
3928- build_container_name,
3929+ instance_id,
3930 series=series,
3931 config=context.config,
3932 machine_type=context.config.machine_type,
3933 deb_paths=deb_paths,
3934 )
3935
3936- image_name = _capture_container_as_image(
3937- build_container_name,
3938- image_name="ubuntu-behave-image-%s-" % series + time_suffix,
3939- cloud_api=context.config.cloud_api,
3940- )
3941- context.series_image_name[series] = image_name
3942- inst.delete(wait=False)
3943+ return inst
3944
3945
3946 def _install_uat_in_container(
3947- container_name: str,
3948+ container_id: str,
3949 series: str,
3950 config: UAClientBehaveConfig,
3951 machine_type: str,
3952- deb_paths: "Optional[List[str]]" = None,
3953+ deb_paths: Optional[List[str]] = None,
3954 ) -> None:
3955 """Install ubuntu-advantage-tools into the specified container
3956
3957- :param container_name:
3958- The name of the container into which ubuntu-advantage-tools should be
3959+ :param container_id:
3960+ The id of the container into which ubuntu-advantage-tools should be
3961 installed.
3962 :param series: The name of the series that is being used
3963 :param config: UAClientBehaveConfig
3964 :param deb_paths: Optional paths to local deb files we need to install
3965 """
3966- cmds: "List[Any]" = [["systemctl", "is-system-running", "--wait"]]
3967+ cmds: List[Any] = [["systemctl", "is-system-running", "--wait"]]
3968
3969 if deb_paths is None:
3970 deb_paths = []
3971@@ -793,7 +779,7 @@ def _install_uat_in_container(
3972 cmds.append(["sudo", "apt-get", "update", "-qqy"])
3973
3974 deb_files = []
3975- inst = config.cloud_api.get_instance(container_name)
3976+ inst = config.cloud_api.get_instance(container_id)
3977
3978 for deb_file in deb_paths:
3979 if "pro" in deb_file and "pro" not in config.machine_type:
3980@@ -823,6 +809,7 @@ def _install_uat_in_container(
3981 if "pro" in machine_type:
3982 ua_pkg.append("ubuntu-advantage-pro")
3983
3984+ cmds.append(["sudo", "apt-get", "update"])
3985 cmds.append(
3986 " ".join(
3987 [
3988@@ -853,14 +840,14 @@ def _install_uat_in_container(
3989 cmds.append("sudo ua detach --assume-yes")
3990
3991 cmds.append(["ua", "version"])
3992- instance = config.cloud_api.get_instance(container_name)
3993+ instance = config.cloud_api.get_instance(container_id)
3994 for cmd in cmds: # type: ignore
3995 result = instance.execute(cmd)
3996 if result.failed:
3997- print(
3998+ logging.info(
3999 "--- Failed {}: out {} err {}".format(
4000 cmd, result.stdout, result.stderr
4001 )
4002 )
4003 elif "version" in cmd:
4004- print("--- " + result)
4005+ logging.info("--- " + result)
4006diff --git a/features/install_uninstall.feature b/features/install_uninstall.feature
4007new file mode 100644
4008index 0000000..6f9fd66
4009--- /dev/null
4010+++ b/features/install_uninstall.feature
4011@@ -0,0 +1,46 @@
4012+Feature: UA Install and Uninstall related tests
4013+
4014+ @series.all
4015+ @uses.config.machine_type.lxd.container
4016+ Scenario Outline: Do not fail on postinst when cloud-id returns error
4017+ Given a `<release>` machine with ubuntu-advantage-tools installed
4018+ When I delete the file `/run/cloud-init/instance-data.json`
4019+ Then I verify that running `dpkg-reconfigure ubuntu-advantage-tools` `with sudo` exits `0`
4020+
4021+ Examples: ubuntu release
4022+ | release |
4023+ | xenial |
4024+ | bionic |
4025+ | focal |
4026+ | hirsute |
4027+
4028+ @series.lts
4029+ @uses.config.contract_token
4030+ @uses.config.machine_type.lxd.container
4031+ Scenario Outline: Purge package after attaching it to a machine
4032+ Given a `<release>` machine with ubuntu-advantage-tools installed
4033+ When I attach `contract_token` with sudo
4034+ And I run `touch /etc/apt/preferences.d/ubuntu-esm-infra` with sudo
4035+ Then I verify that files exist matching `/var/log/ubuntu-advantage.log`
4036+ And I verify that running `test -d /var/lib/ubuntu-advantage` `with sudo` exits `0`
4037+ And I verify that files exist matching `/etc/apt/auth.conf.d/90ubuntu-advantage`
4038+ And I verify that files exist matching `/etc/apt/trusted.gpg.d/ubuntu-advantage-esm-infra-trusty.gpg`
4039+ And I verify that files exist matching `/etc/apt/sources.list.d/ubuntu-esm-infra.list`
4040+ And I verify that files exist matching `/etc/apt/preferences.d/ubuntu-esm-infra`
4041+ When I run `apt-get purge ubuntu-advantage-tools -y` with sudo, retrying exit [100]
4042+ Then stdout matches regexp:
4043+ """
4044+ Purging configuration files for ubuntu-advantage-tools
4045+ """
4046+ And I verify that no files exist matching `/var/log/ubuntu-advantage.log`
4047+ And I verify that no files exist matching `/var/lib/ubuntu-advantage`
4048+ And I verify that no files exist matching `/etc/apt/auth.conf.d/90ubuntu-advantage`
4049+ And I verify that no files exist matching `/etc/apt/sources.list.d/ubuntu-*`
4050+ And I verify that no files exist matching `/etc/apt/trusted.gpg.d/ubuntu-advantage-*`
4051+ And I verify that no files exist matching `/etc/apt/preferences.d/ubuntu-*`
4052+
4053+ Examples: ubuntu release
4054+ | release |
4055+ | bionic |
4056+ | focal |
4057+ | xenial |
4058diff --git a/features/license_check.feature b/features/license_check.feature
4059new file mode 100644
4060index 0000000..54479e2
4061--- /dev/null
4062+++ b/features/license_check.feature
4063@@ -0,0 +1,120 @@
4064+Feature: License check timer only runs in environments where necessary
4065+
4066+ @series.lts
4067+ @uses.config.contract_token
4068+ @uses.config.machine_type.gcp.generic
4069+ Scenario Outline: license_check job should run periodically on gcp generic lts
4070+ Given a `<release>` machine with ubuntu-advantage-tools installed
4071+ # verify its enabled
4072+ Then I verify the `ua-license-check` systemd timer is scheduled to run within `10` minutes
4073+ # run it and verify that it didn't disable itself
4074+ When I run `systemctl start ua-license-check.service` with sudo
4075+ When I wait `5` seconds
4076+ Then I verify the `ua-license-check` systemd timer is scheduled to run within `10` minutes
4077+ # verify attach disables it
4078+ When I wait `5` seconds
4079+ When I attach `contract_token` with sudo
4080+ Then I verify the `ua-license-check` systemd timer is disabled
4081+ # verify detach enables it
4082+ When I run `ua detach --assume-yes` with sudo
4083+ Then I verify the `ua-license-check` systemd timer is scheduled to run within `10` minutes
4084+ # verify stopping and deleting marker file and stopping disables it
4085+ # We need to call stop both before and after rm-ing the marker file
4086+ # because at least one version of systemd requires it before (245.4-4ubuntu3.11
4087+ # on focal gcp), and every other tested version of systemd requires it after
4088+ # But this is only necessary when manually running the steps or in this test.
4089+ # `disable_license_checks_if_applicable` works fine with only calling stop after,
4090+ # as evidenced by the "verify attach disables it" steps above passing on focal gcp.
4091+ When I run `systemctl stop ua-license-check.timer` with sudo
4092+ When I run `rm /var/lib/ubuntu-advantage/marker-license-check` with sudo
4093+ When I run `systemctl stop ua-license-check.timer` with sudo
4094+ Then I verify the `ua-license-check` systemd timer is disabled
4095+ # verify creating marker file enables it
4096+ When I run `touch /var/lib/ubuntu-advantage/marker-license-check` with sudo
4097+ Then I verify the `ua-license-check` systemd timer is scheduled to run within `10` minutes
4098+ Examples: version
4099+ | release |
4100+ | xenial |
4101+ | bionic |
4102+ | focal |
4103+
4104+ @series.hirsute
4105+ @uses.config.contract_token
4106+ @uses.config.machine_type.gcp.generic
4107+ Scenario Outline: license_check is disabled gcp generic non lts
4108+ Given a `<release>` machine with ubuntu-advantage-tools installed
4109+ Then I verify the `ua-license-check` systemd timer is disabled
4110+ # verify creating marker file enables it, but it disables itself
4111+ When I run `touch /var/lib/ubuntu-advantage/marker-license-check` with sudo
4112+ Then I verify the `ua-license-check` systemd timer either ran within the past `5` seconds OR is scheduled to run within `10` minutes
4113+ When I run `systemctl start ua-license-check.service` with sudo
4114+ When I wait `5` seconds
4115+ Then I verify the `ua-license-check` systemd timer is disabled
4116+ # verify attach and detach does not enable it
4117+ When I wait `5` seconds
4118+ When I attach `contract_token` with sudo
4119+ When I run `ua detach --assume-yes` with sudo
4120+ When I wait `5` seconds
4121+ Then I verify the `ua-license-check` systemd timer is disabled
4122+ Examples: version
4123+ | release |
4124+ | hirsute |
4125+
4126+ @series.all
4127+ @uses.config.contract_token
4128+ @uses.config.machine_type.lxd.container
4129+ @uses.config.machine_type.lxd.vm
4130+ @uses.config.machine_type.aws.generic
4131+ @uses.config.machine_type.azure.generic
4132+ Scenario Outline: license_check is disabled everywhere but gcp generic
4133+ Given a `<release>` machine with ubuntu-advantage-tools installed
4134+ Then I verify the `ua-license-check` systemd timer is disabled
4135+ When I reboot the `<release>` machine
4136+ Then I verify the `ua-license-check` systemd timer is disabled
4137+ # verify creating marker file enables it, but it disables itself
4138+ When I run `touch /var/lib/ubuntu-advantage/marker-license-check` with sudo
4139+ Then I verify the `ua-license-check` systemd timer either ran within the past `5` seconds OR is scheduled to run within `10` minutes
4140+ When I run `systemctl start ua-license-check.service` with sudo
4141+ When I wait `5` seconds
4142+ And I verify that running `grep "Disabling gcp_auto_attach job" /var/log/ubuntu-advantage-license-check.log` `with sudo` exits `0`
4143+ And I verify that running `grep "Disabling gcp_auto_attach job" /var/log/ubuntu-advantage.log` `with sudo` exits `1`
4144+ Then I verify the `ua-license-check` systemd timer is disabled
4145+ # verify attach and detach does not enable it
4146+ When I wait `5` seconds
4147+ When I attach `contract_token` with sudo
4148+ When I run `ua detach --assume-yes` with sudo
4149+ When I wait `5` seconds
4150+ Then I verify the `ua-license-check` systemd timer is disabled
4151+ Examples: version
4152+ | release |
4153+ | xenial |
4154+ | bionic |
4155+ | focal |
4156+ | hirsute |
4157+
4158+ @series.lts
4159+ @uses.config.machine_type.aws.pro
4160+ @uses.config.machine_type.azure.pro
4161+ @uses.config.machine_type.gcp.pro
4162+ Scenario Outline: license_check is disabled everywhere but gcp generic
4163+ Given a `<release>` machine with ubuntu-advantage-tools installed
4164+ When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
4165+ """
4166+ contract_url: 'https://contracts.canonical.com'
4167+ data_dir: /var/lib/ubuntu-advantage
4168+ log_level: debug
4169+ log_file: /var/log/ubuntu-advantage.log
4170+ """
4171+ When I run `ua auto-attach` with sudo
4172+ Then I verify the `ua-license-check` systemd timer is disabled
4173+ # verify creating marker file enables it, but it disables itself
4174+ When I run `touch /var/lib/ubuntu-advantage/marker-license-check` with sudo
4175+ Then I verify the `ua-license-check` systemd timer either ran within the past `5` seconds OR is scheduled to run within `10` minutes
4176+ When I run `systemctl start ua-license-check.service` with sudo
4177+ When I wait `5` seconds
4178+ Then I verify the `ua-license-check` systemd timer is disabled
4179+ Examples: version
4180+ | release |
4181+ | xenial |
4182+ | bionic |
4183+ | focal |
4184diff --git a/features/proxy_config.feature b/features/proxy_config.feature
4185index 1bdcfa0..46b549a 100644
4186--- a/features/proxy_config.feature
4187+++ b/features/proxy_config.feature
4188@@ -2,6 +2,7 @@
4189 Feature: Proxy configuration
4190
4191 @series.lts
4192+ @uses.config.machine_type.lxd.container
4193 Scenario Outline: Attach command when proxy is configured
4194 Given a `<release>` machine with ubuntu-advantage-tools installed
4195 When I launch a `focal` `proxy` machine
4196@@ -83,6 +84,11 @@ Feature: Proxy configuration
4197 """
4198 "invalidurl" is not a valid url. Not setting as proxy.
4199 """
4200+ When I verify that running `ua config set http_proxy=http://host:port` `with sudo` exits `1`
4201+ Then stderr matches regexp:
4202+ """
4203+ "http://host:port" is not a valid url. Not setting as proxy
4204+ """
4205 When I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
4206 """
4207 ua_config:
4208@@ -208,6 +214,7 @@ Feature: Proxy configuration
4209 | bionic |
4210
4211 @series.lts
4212+ @uses.config.machine_type.lxd.container
4213 Scenario Outline: Attach command when authenticated proxy is configured
4214 Given a `<release>` machine with ubuntu-advantage-tools installed
4215 When I launch a `focal` `proxy` machine
4216diff --git a/features/staging_commands.feature b/features/staging_commands.feature
4217index f768851..360b329 100644
4218--- a/features/staging_commands.feature
4219+++ b/features/staging_commands.feature
4220@@ -1,25 +1,8 @@
4221 @uses.config.contract_token_staging
4222 Feature: Enable command behaviour when attached to an UA staging subscription
4223
4224- @series.xenial
4225- Scenario: Attached enable CC EAL service in a xenial lxd container
4226- Given a `xenial` machine with ubuntu-advantage-tools installed
4227- When I attach `contract_token_staging` with sudo
4228- Then I verify that running `ua enable cc-eal` `as non-root` exits `1`
4229- And I will see the following on stderr:
4230- """
4231- This command must be run as root (try using sudo).
4232- """
4233- When I run `ua enable cc-eal --beta` with sudo
4234- Then I will see the following on stdout:
4235- """
4236- One moment, checking your subscription first
4237- GPG key '/usr/share/keyrings/ubuntu-cc-keyring.gpg' not found.
4238- """
4239-
4240- @series.xenial
4241- @series.bionic
4242- @series.focal
4243+ @series.lts
4244+ @uses.config.machine_type.lxd.container
4245 Scenario Outline: Attached enable esm-apps on a machine
4246 Given a `<release>` machine with ubuntu-advantage-tools installed
4247 When I attach `contract_token_staging` with sudo
4248@@ -107,518 +90,3 @@ Feature: Enable command behaviour when attached to an UA staging subscription
4249 | bionic | bundler |
4250 | focal | ant |
4251 | xenial | jq |
4252-
4253- @series.xenial
4254- @series.bionic
4255- @uses.config.machine_type.lxd.vm
4256- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
4257- Given a `<release>` machine with ubuntu-advantage-tools installed
4258- When I attach `contract_token_staging` with sudo
4259- And I run `ua disable livepatch` with sudo
4260- 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]
4261- And I run `apt-mark hold openssh-client openssh-server strongswan` with sudo
4262- And I run `ua enable <fips-service> --assume-yes` with sudo
4263- Then stdout matches regexp:
4264- """
4265- Updating package lists
4266- Installing <fips-name> packages
4267- <fips-name> enabled
4268- A reboot is required to complete install
4269- """
4270- When I run `ua status --all` with sudo
4271- Then stdout matches regexp:
4272- """
4273- <fips-service> +yes enabled
4274- """
4275- And stdout matches regexp:
4276- """
4277- FIPS support requires system reboot to complete configuration
4278- """
4279- And I verify that running `apt update` `with sudo` exits `0`
4280- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
4281- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
4282- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
4283- And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
4284- And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
4285- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
4286- When I reboot the `<release>` machine
4287- And I run `uname -r` as non-root
4288- Then stdout matches regexp:
4289- """
4290- fips
4291- """
4292- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4293- Then I will see the following on stdout:
4294- """
4295- 1
4296- """
4297- When I run `ua status --all` with sudo
4298- Then stdout does not match regexp:
4299- """
4300- FIPS support requires system reboot to complete configuration
4301- """
4302- When I run `ua disable <fips-service> --assume-yes` with sudo
4303- Then stdout matches regexp:
4304- """
4305- Updating package lists
4306- A reboot is required to complete disable operation
4307- """
4308- When I run `ua status --all` with sudo
4309- Then stdout matches regexp:
4310- """
4311- Disabling FIPS requires system reboot to complete operation
4312- """
4313- When I run `apt-cache policy ubuntu-fips` as non-root
4314- Then stdout matches regexp:
4315- """
4316- .*Installed: \(none\)
4317- """
4318- When I reboot the `<release>` machine
4319- Then I verify that `openssh-server` installed version matches regexp `fips`
4320- And I verify that `openssh-client` installed version matches regexp `fips`
4321- And I verify that `strongswan` installed version matches regexp `fips`
4322- And I verify that `openssh-server-hmac` installed version matches regexp `fips`
4323- And I verify that `openssh-client-hmac` installed version matches regexp `fips`
4324- And I verify that `strongswan-hmac` installed version matches regexp `fips`
4325- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
4326- Then I will see the following on stdout:
4327- """
4328- openssh-client was already not hold.
4329- openssh-server was already not hold.
4330- strongswan was already not hold.
4331- """
4332- When I run `ua status --all` with sudo
4333- Then stdout matches regexp:
4334- """
4335- <fips-service> +yes disabled
4336- """
4337- Then stdout does not match regexp:
4338- """
4339- Disabling FIPS requires system reboot to complete operation
4340- """
4341-
4342- Examples: ubuntu release
4343- | release | fips-name | fips-service |fips-apt-source |
4344- | xenial | FIPS | fips |https://esm.staging.ubuntu.com/fips/ubuntu xenial/main |
4345- | bionic | FIPS | fips |https://esm.staging.ubuntu.com/fips/ubuntu bionic/main |
4346-
4347- @series.xenial
4348- @series.bionic
4349- @uses.config.machine_type.lxd.vm
4350- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
4351- Given a `<release>` machine with ubuntu-advantage-tools installed
4352- When I attach `contract_token_staging` with sudo
4353- And I run `ua disable livepatch` with sudo
4354- 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]
4355- When I run `ua enable <fips-service> --assume-yes` with sudo
4356- Then stdout matches regexp:
4357- """
4358- Updating package lists
4359- Installing <fips-name> packages
4360- <fips-name> enabled
4361- A reboot is required to complete install
4362- """
4363- When I run `ua status --all` with sudo
4364- Then stdout matches regexp:
4365- """
4366- <fips-service> +yes enabled
4367- """
4368- And I verify that running `apt update` `with sudo` exits `0`
4369- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
4370- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
4371- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
4372- And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
4373- And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
4374- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
4375- When I reboot the `<release>` machine
4376- And I run `uname -r` as non-root
4377- Then stdout matches regexp:
4378- """
4379- fips
4380- """
4381- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4382- Then I will see the following on stdout:
4383- """
4384- 1
4385- """
4386- When I run `ua disable <fips-service> --assume-yes` with sudo
4387- Then stdout matches regexp:
4388- """
4389- Updating package lists
4390- A reboot is required to complete disable operation
4391- """
4392- When I reboot the `<release>` machine
4393- Then I verify that `openssh-server` installed version matches regexp `fips`
4394- And I verify that `openssh-client` installed version matches regexp `fips`
4395- And I verify that `strongswan` installed version matches regexp `fips`
4396- And I verify that `openssh-server-hmac` installed version matches regexp `fips`
4397- And I verify that `openssh-client-hmac` installed version matches regexp `fips`
4398- And I verify that `strongswan-hmac` installed version matches regexp `fips`
4399- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
4400- Then I will see the following on stdout:
4401- """
4402- openssh-client was already not hold.
4403- openssh-server was already not hold.
4404- strongswan was already not hold.
4405- """
4406- When I run `ua status --all` with sudo
4407- Then stdout matches regexp:
4408- """
4409- <fips-service> +yes disabled
4410- """
4411- When I verify that running `ua enable fips --assume-yes` `with sudo` exits `1`
4412- Then stdout matches regexp:
4413- """
4414- Cannot enable FIPS because FIPS Updates was once enabled.
4415- """
4416- And I verify that files exist matching `/var/lib/ubuntu-advantage/services-once-enabled`
4417-
4418- Examples: ubuntu release
4419- | release | fips-name | fips-service |fips-apt-source |
4420- | xenial | FIPS Updates | fips-updates |https://esm.staging.ubuntu.com/fips-updates/ubuntu xenial-updates/main |
4421- | bionic | FIPS Updates | fips-updates |https://esm.staging.ubuntu.com/fips-updates/ubuntu bionic-updates/main |
4422-
4423- @series.focal
4424- @uses.config.machine_type.lxd.vm
4425- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
4426- Given a `<release>` machine with ubuntu-advantage-tools installed
4427- When I attach `contract_token_staging` with sudo
4428- 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]
4429- And I create the file `/home/ubuntu/machine-token-overlay.json` with the following:
4430- """
4431- {
4432- "availableResources": [
4433- {
4434- "available": true,
4435- "name": "fips"
4436- }
4437- ],
4438- "machineTokenInfo": {
4439- "contractInfo": {
4440- "resourceEntitlements": [
4441- {
4442- "type": "fips",
4443- "entitled": true,
4444- "affordances": {
4445- "series": [
4446- "xenial",
4447- "bionic",
4448- "focal"
4449- ]
4450- },
4451- "directives": {
4452- "suites": [
4453- "xenial",
4454- "bionic",
4455- "focal"
4456- ]
4457- }
4458- }
4459- ]
4460- }
4461- }
4462- }
4463- """
4464- And I append the following on uaclient config:
4465- """
4466- features:
4467- machine_token_overlay: "/home/ubuntu/machine-token-overlay.json"
4468- """
4469- When I run `ua enable <fips-service> --assume-yes` with sudo
4470- Then stdout matches regexp:
4471- """
4472- Updating package lists
4473- Installing <fips-name> packages
4474- FIPS strongswan-hmac package could not be installed
4475- <fips-name> enabled
4476- A reboot is required to complete install
4477- """
4478- When I run `ua status --all` with sudo
4479- Then stdout matches regexp:
4480- """
4481- <fips-service> +yes enabled
4482- """
4483- And I verify that running `apt update` `with sudo` exits `0`
4484- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
4485- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
4486- When I reboot the `<release>` machine
4487- And I run `uname -r` as non-root
4488- Then stdout matches regexp:
4489- """
4490- fips
4491- """
4492- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4493- Then I will see the following on stdout:
4494- """
4495- 1
4496- """
4497- When I run `ua disable <fips-service> --assume-yes` with sudo
4498- Then stdout matches regexp:
4499- """
4500- Updating package lists
4501- A reboot is required to complete disable operation
4502- """
4503- When I reboot the `<release>` machine
4504- Then I verify that `openssh-server` installed version matches regexp `fips`
4505- And I verify that `openssh-client` installed version matches regexp `fips`
4506- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
4507- Then I will see the following on stdout:
4508- """
4509- openssh-client was already not hold.
4510- openssh-server was already not hold.
4511- strongswan was already not hold.
4512- """
4513- When I run `ua status --all` with sudo
4514- Then stdout matches regexp:
4515- """
4516- <fips-service> +yes disabled
4517- """
4518-
4519- Examples: ubuntu release
4520- | release | fips-name | fips-service |fips-apt-source |
4521- | focal | FIPS | fips |https://esm.staging.ubuntu.com/fips/ubuntu focal/main |
4522-
4523- @series.focal
4524- @uses.config.machine_type.lxd.vm
4525- Scenario Outline: Attached enable of vm-based services in an ubuntu lxd vm
4526- Given a `<release>` machine with ubuntu-advantage-tools installed
4527- When I attach `contract_token_staging` with sudo
4528- 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]
4529- And I create the file `/home/ubuntu/machine-token-overlay.json` with the following:
4530- """
4531- {
4532- "availableResources": [
4533- {
4534- "available": true,
4535- "name": "fips-updates"
4536- }
4537- ],
4538- "machineTokenInfo": {
4539- "contractInfo": {
4540- "resourceEntitlements": [
4541- {
4542- "type": "fips-updates",
4543- "entitled": true,
4544- "affordances": {
4545- "series": [
4546- "xenial",
4547- "bionic",
4548- "focal"
4549- ]
4550- },
4551- "directives": {
4552- "suites": [
4553- "xenial-updates",
4554- "bionic-updates",
4555- "focal-updates"
4556- ]
4557- }
4558- }
4559- ]
4560- }
4561- }
4562- }
4563- """
4564- And I append the following on uaclient config:
4565- """
4566- features:
4567- machine_token_overlay: "/home/ubuntu/machine-token-overlay.json"
4568- """
4569- When I run `ua enable <fips-service> --assume-yes` with sudo
4570- Then stdout matches regexp:
4571- """
4572- Updating package lists
4573- Installing <fips-name> packages
4574- <fips-name> enabled
4575- A reboot is required to complete install
4576- """
4577- When I run `ua status --all` with sudo
4578- Then stdout matches regexp:
4579- """
4580- <fips-service> +yes enabled
4581- """
4582- And I verify that running `apt update` `with sudo` exits `0`
4583- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
4584- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
4585- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
4586- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
4587- When I reboot the `<release>` machine
4588- And I run `uname -r` as non-root
4589- Then stdout matches regexp:
4590- """
4591- fips
4592- """
4593- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4594- Then I will see the following on stdout:
4595- """
4596- 1
4597- """
4598- When I run `ua disable <fips-service> --assume-yes` with sudo
4599- Then stdout matches regexp:
4600- """
4601- Updating package lists
4602- A reboot is required to complete disable operation
4603- """
4604- When I reboot the `<release>` machine
4605- Then I verify that `openssh-server` installed version matches regexp `fips`
4606- And I verify that `openssh-client` installed version matches regexp `fips`
4607- And I verify that `strongswan` installed version matches regexp `fips`
4608- And I verify that `strongswan-hmac` installed version matches regexp `fips`
4609- When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
4610- Then I will see the following on stdout:
4611- """
4612- openssh-client was already not hold.
4613- openssh-server was already not hold.
4614- strongswan was already not hold.
4615- """
4616- When I run `ua status --all` with sudo
4617- Then stdout matches regexp:
4618- """
4619- <fips-service> +yes disabled
4620- """
4621- When I verify that running `ua enable fips --assume-yes` `with sudo` exits `1`
4622- Then stdout matches regexp:
4623- """
4624- Cannot enable FIPS because FIPS Updates was once enabled.
4625- """
4626- And I verify that files exist matching `/var/lib/ubuntu-advantage/services-once-enabled`
4627-
4628- Examples: ubuntu release
4629- | release | fips-name | fips-service |fips-apt-source |
4630- | focal | FIPS Updates | fips-updates |https://esm.staging.ubuntu.com/fips-updates/ubuntu focal-updates/main |
4631-
4632- @series.xenial
4633- @uses.config.machine_type.lxd.vm
4634- Scenario Outline: Attached FIPS upgrade across LTS releases
4635- Given a `<release>` machine with ubuntu-advantage-tools installed
4636- When I attach `contract_token_staging` with sudo
4637- And I run `apt-get install lsof` with sudo, retrying exit [100]
4638- And I run `ua disable livepatch` with sudo
4639- And I run `ua enable <fips-service> --assume-yes` with sudo
4640- Then stdout matches regexp:
4641- """
4642- Updating package lists
4643- Installing <fips-name> packages
4644- <fips-name> enabled
4645- A reboot is required to complete install
4646- """
4647- When I run `ua status --all` with sudo
4648- Then stdout matches regexp:
4649- """
4650- <fips-service> +yes enabled
4651- """
4652- And I verify that running `apt update` `with sudo` exits `0`
4653- When I reboot the `<release>` machine
4654- And I run `uname -r` as non-root
4655- Then stdout matches regexp:
4656- """
4657- fips
4658- """
4659- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4660- Then I will see the following on stdout:
4661- """
4662- 1
4663- """
4664- When I run `apt-get dist-upgrade -y --allow-downgrades` with sudo
4665- # A package may need a reboot after running dist-upgrade
4666- And I reboot the `<release>` machine
4667- And I create the file `/etc/update-manager/release-upgrades.d/ua-test.cfg` with the following
4668- """
4669- [Sources]
4670- AllowThirdParty=yes
4671- """
4672- Then I verify that running `do-release-upgrade --frontend DistUpgradeViewNonInteractive` `with sudo` exits `0`
4673- When I reboot the `<release>` machine
4674- And I run `lsb_release -cs` as non-root
4675- Then I will see the following on stdout:
4676- """
4677- <next_release>
4678- """
4679- When I verify that running `egrep "disabled" /etc/apt/sources.list.d/<source-file>.list` `as non-root` exits `1`
4680- Then I will see the following on stdout:
4681- """
4682- """
4683- When I run `ua status --all` with sudo
4684- Then stdout matches regexp:
4685- """
4686- <fips-service> +yes enabled
4687- """
4688- When I run `uname -r` as non-root
4689- Then stdout matches regexp:
4690- """
4691- fips
4692- """
4693- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4694- Then I will see the following on stdout:
4695- """
4696- 1
4697- """
4698-
4699- Examples: ubuntu release
4700- | release | next_release | fips-service | fips-name | source-file |
4701- | xenial | bionic | fips | FIPS | ubuntu-fips |
4702- | xenial | bionic | fips-updates | FIPS Updates | ubuntu-fips-updates |
4703-
4704- @series.xenial
4705- @series.bionic
4706- @uses.config.machine_type.lxd.vm
4707- Scenario Outline: Attached enable fips-updates on fips enabled vm
4708- Given a `<release>` machine with ubuntu-advantage-tools installed
4709- When I attach `contract_token_staging` with sudo
4710- And I run `ua disable livepatch` with sudo
4711- 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]
4712- And I run `ua enable fips --assume-yes` with sudo
4713- Then stdout matches regexp:
4714- """
4715- Updating package lists
4716- Installing FIPS packages
4717- FIPS enabled
4718- A reboot is required to complete install
4719- """
4720- When I run `ua status --all` with sudo
4721- Then stdout matches regexp:
4722- """
4723- fips +yes enabled
4724- """
4725- When I reboot the `<release>` machine
4726- And I run `ua enable fips-updates --assume-yes` with sudo
4727- Then stdout matches regexp:
4728- """
4729- Updating package lists
4730- Installing FIPS Updates packages
4731- FIPS Updates enabled
4732- A reboot is required to complete install
4733- """
4734- When I run `ua status --all` with sudo
4735- Then stdout matches regexp:
4736- """
4737- fips +yes n/a
4738- """
4739- And stdout matches regexp:
4740- """
4741- fips-updates +yes enabled
4742- """
4743- When I reboot the `<release>` machine
4744- Then I verify that running `apt update` `with sudo` exits `0`
4745- And I verify that `ubuntu-fips` is installed from apt source `<fips-apt-source>`
4746- And I verify that `openssh-server` is installed from apt source `<fips-apt-source>`
4747- And I verify that `openssh-client` is installed from apt source `<fips-apt-source>`
4748- And I verify that `strongswan` is installed from apt source `<fips-apt-source>`
4749- And I verify that `openssh-server-hmac` is installed from apt source `<fips-apt-source>`
4750- And I verify that `openssh-client-hmac` is installed from apt source `<fips-apt-source>`
4751- And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
4752- When I run `uname -r` as non-root
4753- Then stdout matches regexp:
4754- """
4755- fips
4756- """
4757- When I run `cat /proc/sys/crypto/fips_enabled` with sudo
4758- Then I will see the following on stdout:
4759- """
4760- 1
4761- """
4762-
4763- Examples: ubuntu release
4764- | release | fips-apt-source |
4765- | xenial | https://esm.staging.ubuntu.com/fips-updates/ubuntu xenial-updates/main |
4766- | bionic | https://esm.staging.ubuntu.com/fips-updates/ubuntu bionic-updates/main |
4767diff --git a/features/steps/steps.py b/features/steps/steps.py
4768index 390a829..4b662b1 100644
4769--- a/features/steps/steps.py
4770+++ b/features/steps/steps.py
4771@@ -1,27 +1,48 @@
4772 import datetime
4773 import logging
4774 import os
4775-import subprocess
4776 import re
4777 import shlex
4778+import subprocess
4779 import time
4780
4781+import yaml
4782 from behave import given, then, when
4783 from hamcrest import (
4784 assert_that,
4785+ contains_string,
4786 equal_to,
4787 matches_regexp,
4788 not_,
4789- contains_string,
4790 )
4791
4792-from features.environment import create_uat_image
4793+from features.environment import (
4794+ capture_container_as_image,
4795+ create_instance_with_uat_installed,
4796+)
4797 from features.util import SLOW_CMDS, emit_spinner_on_travis, nullcontext
4798-
4799 from uaclient.defaults import DEFAULT_CONFIG_FILE, DEFAULT_MACHINE_TOKEN_PATH
4800+from uaclient.util import DatetimeAwareJSONDecoder
4801
4802+CONTAINER_PREFIX = "ubuntu-behave-test"
4803+IMAGE_BUILD_PREFIX = "ubuntu-behave-image-build"
4804+IMAGE_PREFIX = "ubuntu-behave-image"
4805
4806-CONTAINER_PREFIX = "ubuntu-behave-test-"
4807+
4808+def add_test_name_suffix(context, series, prefix):
4809+ pr_number = os.environ.get("UACLIENT_BEHAVE_JENKINS_CHANGE_ID")
4810+ pr_suffix = "-" + str(pr_number) if pr_number else ""
4811+ is_vm = bool(context.config.machine_type == "lxd.vm")
4812+ vm_suffix = "-vm" if is_vm else ""
4813+ time_suffix = datetime.datetime.now().strftime("-%s%f")
4814+
4815+ return "{prefix}{pr_suffix}{vm_suffix}-{series}{time_suffix}".format(
4816+ prefix=prefix,
4817+ pr_suffix=pr_suffix,
4818+ vm_suffix=vm_suffix,
4819+ series=series,
4820+ time_suffix=time_suffix,
4821+ )
4822
4823
4824 @given("a `{series}` machine with ubuntu-advantage-tools installed")
4825@@ -38,29 +59,44 @@ def given_a_machine(context, series):
4826 ] = context.config.cloud_api.get_instance(context.container_name)
4827 return
4828
4829- if series not in context.series_image_name:
4830- with emit_spinner_on_travis():
4831- create_uat_image(context, series)
4832+ instance_name = add_test_name_suffix(context, series, CONTAINER_PREFIX)
4833
4834- is_vm = bool(context.config.machine_type == "lxd.vm")
4835- pr_number = os.environ.get("UACLIENT_BEHAVE_JENKINS_CHANGE_ID")
4836- now = datetime.datetime.now()
4837-
4838- vm_prefix = "vm-" if is_vm else ""
4839- pr_prefix = str(pr_number) + "-" if pr_number else ""
4840- date_prefix = now.strftime("-%s%f")
4841+ if context.config.snapshot_strategy:
4842+ if series not in context.series_image_name:
4843+ with emit_spinner_on_travis():
4844+ build_container_name = add_test_name_suffix(
4845+ context, series, IMAGE_BUILD_PREFIX
4846+ )
4847+ image_inst = create_instance_with_uat_installed(
4848+ context, series, build_container_name
4849+ )
4850
4851- instance_name = (
4852- CONTAINER_PREFIX + pr_prefix + vm_prefix + series + date_prefix
4853- )
4854+ image_name = add_test_name_suffix(
4855+ context, series, IMAGE_PREFIX
4856+ )
4857+ image_inst_id = context.config.cloud_manager.get_instance_id(
4858+ image_inst
4859+ )
4860+ image_id = capture_container_as_image(
4861+ image_inst_id,
4862+ image_name=image_name,
4863+ cloud_api=context.config.cloud_api,
4864+ )
4865+ context.series_image_name[series] = image_id
4866+ image_inst.delete(wait=False)
4867
4868- context.instances = {
4869- "uaclient": context.config.cloud_manager.launch(
4870+ inst = context.config.cloud_manager.launch(
4871 series=series,
4872 instance_name=instance_name,
4873 image_name=context.series_image_name[series],
4874+ ephemeral=context.config.ephemeral_instance,
4875 )
4876- }
4877+ else:
4878+ inst = create_instance_with_uat_installed(
4879+ context, series, instance_name
4880+ )
4881+
4882+ context.instances = {"uaclient": inst}
4883
4884 context.container_name = context.config.cloud_manager.get_instance_id(
4885 context.instances["uaclient"]
4886@@ -68,7 +104,7 @@ def given_a_machine(context, series):
4887
4888 def cleanup_instance() -> None:
4889 if not context.config.destroy_instances:
4890- print(
4891+ logging.info(
4892 "--- Leaving instance running: {}".format(
4893 context.instances["uaclient"].name
4894 )
4895@@ -77,17 +113,16 @@ def given_a_machine(context, series):
4896 try:
4897 context.instances["uaclient"].delete(wait=False)
4898 except RuntimeError as e:
4899- print(
4900+ logging.error(
4901 "Failed to delete instance: {}\n{}".format(
4902 context.instances["uaclient"].name, str(e)
4903 )
4904 )
4905
4906 context.add_cleanup(cleanup_instance)
4907- logging.warning(
4908+ logging.info(
4909 "--- instance ip: {}".format(context.instances["uaclient"].ip)
4910 )
4911- print("--- instance ip: {}".format(context.instances["uaclient"].ip))
4912
4913
4914 @when("I launch a `{series}` `{instance_name}` machine")
4915@@ -104,7 +139,7 @@ def launch_machine(context, series, instance_name):
4916 try:
4917 context.instances[instance_name].delete(wait=False)
4918 except RuntimeError as e:
4919- print(
4920+ logging.error(
4921 "Failed to delete instance: {}\n{}".format(
4922 context.instances[instance_name].name, str(e)
4923 )
4924@@ -154,7 +189,7 @@ def when_i_retry_run_command(context, command, user_spec, exit_codes):
4925 "Exhausted retries waiting for exit codes: %s", exit_codes
4926 )
4927 break
4928- print(
4929+ logging.info(
4930 "--- Retrying on exit {exit_code}: {command}".format(
4931 exit_code=context.process.returncode, command=command
4932 )
4933@@ -163,6 +198,15 @@ def when_i_retry_run_command(context, command, user_spec, exit_codes):
4934 assert_that(context.process.returncode, equal_to(0))
4935
4936
4937+@when("I run `{command}` `{user_spec}` and stdin `{stdin}`")
4938+def when_i_run_command_with_stdin(
4939+ context, command, user_spec, stdin, instance_name="uaclient"
4940+):
4941+ when_i_run_command(
4942+ context=context, command=command, user_spec=user_spec, stdin=stdin
4943+ )
4944+
4945+
4946 @when("I run `{command}` {user_spec}")
4947 def when_i_run_command(
4948 context,
4949@@ -197,9 +241,9 @@ def when_i_run_command(
4950 )
4951
4952 if verify_return and result.return_code != 0:
4953- print("Error executing command: {}".format(command))
4954- print("stdout: {}".format(result.stdout))
4955- print("stderr: {}".format(result.stderr))
4956+ logging.error("Error executing command: {}".format(command))
4957+ logging.error("stdout: {}".format(result.stdout))
4958+ logging.error("stderr: {}".format(result.stderr))
4959
4960 if verify_return:
4961 assert_that(process.returncode, equal_to(0))
4962@@ -287,7 +331,7 @@ def when_i_attach_staging_token(
4963 except IndexError: # no more timeouts
4964 logging.warning("Exhausted retries waiting for exit code: 0")
4965 break
4966- print(
4967+ logging.info(
4968 "--- Retrying on exit {exit_code}: {cmd}".format(
4969 exit_code=context.process.returncode, cmd=cmd
4970 )
4971@@ -323,11 +367,23 @@ def when_i_create_file_with_content(context, file_path):
4972 when_i_run_command(context, cmd, "with sudo")
4973
4974
4975+@when("I delete the file `{file_path}`")
4976+def when_i_delete_file(context, file_path):
4977+ cmd = "rm -rf {}".format(file_path)
4978+ cmd = 'sh -c "{}"'.format(cmd)
4979+ when_i_run_command(context, cmd, "with sudo")
4980+
4981+
4982 @when("I reboot the `{series}` machine")
4983 def when_i_reboot_the_machine(context, series):
4984 context.instances["uaclient"].restart(wait=True)
4985
4986
4987+@when("I wait `{seconds}` seconds")
4988+def when_i_wait(context, seconds):
4989+ time.sleep(int(seconds))
4990+
4991+
4992 @then("I will see the following on stdout")
4993 def then_i_will_see_on_stdout(context):
4994 assert_that(context.process.stdout.strip(), equal_to(context.text))
4995@@ -337,31 +393,47 @@ def then_i_will_see_on_stdout(context):
4996 def then_conditional_stdout_matches_regexp(context, value1, value2):
4997 """Only apply regex assertion if value1 in value2."""
4998 if value1 in value2.split(" or "):
4999- then_stdout_matches_regexp(context)
5000+ then_stream_matches_regexp(context, "stdout")
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: