Merge ~orndorffgrant/ubuntu/+source/ubuntu-advantage-tools:upload-27.15-mantic into ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel

Proposed by Grant Orndorff
Status: Merged
Merged at revision: 42eb665f4babf121e08122bcb5443ec1ba64a102
Proposed branch: ~orndorffgrant/ubuntu/+source/ubuntu-advantage-tools:upload-27.15-mantic
Merge into: ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel
Diff against target: 16157 lines (+6580/-2282)
161 files modified
.github/PULL_REQUEST_TEMPLATE.md (+21/-2)
.github/actions/bug-refs/action.yml (+9/-0)
.github/actions/bug-refs/index.js (+61/-0)
.github/actions/bug-refs/package-lock.json (+430/-0)
.github/actions/bug-refs/package.json (+10/-0)
.github/workflows/ci-base.yaml (+2/-0)
.github/workflows/ci-integration.yaml (+3/-0)
.github/workflows/custom_pr_checks.yaml (+27/-0)
apport/source_ubuntu-advantage-tools.py (+6/-2)
apt-hook/json-hook.cc (+35/-19)
debian/changelog (+38/-0)
debian/ubuntu-advantage-tools.postinst (+1/-1)
dev-docs/howtoguides/building.md (+0/-13)
dev-docs/howtoguides/release_a_new_version.md (+27/-10)
dev-docs/howtoguides/testing.md (+0/-11)
dev-docs/references/directory_layout.md (+0/-1)
dev-docs/references/version_string_formatting.md (+10/-10)
dev/null (+0/-91)
docs/_static/js/github_issue_links.js (+1/-1)
docs/conf.py (+6/-1)
docs/explanations.rst (+2/-0)
docs/explanations/apt_messages.md (+1/-1)
docs/explanations/cves_and_usns_explained.md (+44/-0)
docs/explanations/how_to_interpret_output_of_unattended_upgrades.md (+82/-0)
docs/explanations/motd_messages.md (+121/-20)
docs/explanations/status_columns.md (+102/-0)
docs/googleaf254801a5285c31.html (+1/-0)
docs/howtoguides.rst (+1/-0)
docs/howtoguides/enable_fips.md (+1/-1)
docs/howtoguides/get_rid_of_corrupt_lock.md (+1/-1)
docs/howtoguides/get_token_and_attach.md (+37/-3)
docs/howtoguides/how_to_not_fix_related_usns.md (+65/-0)
docs/index.rst (+3/-2)
docs/references/api.md (+125/-0)
docs/references/network_requirements.md (+1/-1)
docs/sitemap-index.xml (+8/-0)
docs/tutorials/create_a_fips_updates_pro_cloud_image.md (+9/-9)
docs/tutorials/fix_scenarios.md (+54/-15)
features/api_full_auto_attach.feature (+1/-1)
features/apt_messages.feature (+22/-16)
features/attach_validtoken.feature (+29/-15)
features/attached_commands.feature (+1/-1)
features/attached_status.feature (+5/-1)
features/cloud.py (+25/-5)
features/daemon.feature (+4/-4)
features/docker.feature (+0/-1)
features/enable_fips_cloud.feature (+1/-1)
features/enable_fips_vm.feature (+32/-32)
features/environment.py (+58/-92)
features/fix.feature (+281/-63)
features/i8n.feature (+128/-0)
features/livepatch.feature (+7/-2)
features/logs.feature (+59/-0)
features/proxy_config.feature (+4/-3)
features/realtime_kernel.feature (+274/-41)
features/reboot_cmds.feature (+48/-0)
features/retry_auto_attach.feature (+4/-2)
features/security_status.feature (+225/-61)
features/steps/airgap.py (+2/-2)
features/steps/attach.py (+5/-3)
features/steps/files.py (+5/-2)
features/steps/fix.py (+2/-2)
features/steps/machines.py (+8/-8)
features/steps/output.py (+7/-0)
features/steps/packages.py (+17/-18)
features/steps/shell.py (+4/-2)
features/steps/status.py (+1/-1)
features/steps/ubuntu_advantage_tools.py (+24/-23)
features/timer.feature (+20/-0)
features/ubuntu_pro.feature (+12/-12)
features/unattached_status.feature (+18/-2)
features/util.py (+9/-4)
integration-requirements.txt (+1/-4)
lib/apt_news.py (+7/-1)
lib/auto_attach.py (+7/-1)
lib/daemon.py (+7/-0)
lib/esm_cache.py (+7/-0)
lib/reboot_cmds.py (+73/-106)
lib/timer.py (+10/-3)
lib/upgrade_lts_contract.py (+6/-114)
pyproject.toml (+20/-0)
sru/release-27.14/test-migrate-user-config.sh (+46/-28)
systemd/ua-reboot-cmds.service (+2/-2)
systemd/ua-timer.timer (+3/-1)
tools/README.md (+14/-2)
tools/create-lp-release-branches.sh (+5/-5)
tools/run-integration-tests.py (+21/-13)
tox.ini (+16/-9)
uaclient/actions.py (+30/-5)
uaclient/apt.py (+6/-2)
uaclient/apt_news.py (+2/-2)
uaclient/cli.py (+63/-18)
uaclient/clouds/gcp.py (+2/-2)
uaclient/clouds/tests/test_gcp.py (+106/-20)
uaclient/clouds/tests/test_identity.py (+4/-3)
uaclient/config.py (+9/-30)
uaclient/conftest.py (+15/-1)
uaclient/contract.py (+42/-18)
uaclient/data_types.py (+10/-10)
uaclient/defaults.py (+1/-1)
uaclient/entitlements/__init__.py (+9/-3)
uaclient/entitlements/base.py (+144/-22)
uaclient/entitlements/esm.py (+4/-4)
uaclient/entitlements/fips.py (+2/-2)
uaclient/entitlements/livepatch.py (+4/-10)
uaclient/entitlements/realtime.py (+64/-2)
uaclient/entitlements/repo.py (+25/-12)
uaclient/entitlements/tests/test_base.py (+170/-4)
uaclient/entitlements/tests/test_cc.py (+24/-31)
uaclient/entitlements/tests/test_cis.py (+18/-4)
uaclient/entitlements/tests/test_entitlements.py (+17/-1)
uaclient/entitlements/tests/test_esm.py (+8/-8)
uaclient/entitlements/tests/test_fips.py (+52/-35)
uaclient/entitlements/tests/test_livepatch.py (+67/-63)
uaclient/entitlements/tests/test_realtime.py (+61/-0)
uaclient/entitlements/tests/test_repo.py (+28/-40)
uaclient/event_logger.py (+7/-0)
uaclient/exceptions.py (+11/-1)
uaclient/files/files.py (+7/-0)
uaclient/files/state_files.py (+5/-6)
uaclient/livepatch.py (+8/-3)
uaclient/log.py (+28/-2)
uaclient/messages.py (+111/-12)
uaclient/security.py (+389/-145)
uaclient/security_status.py (+139/-58)
uaclient/status.py (+124/-54)
uaclient/system.py (+109/-38)
uaclient/tests/constraints/constraints-jammy.txt (+8/-0)
uaclient/tests/test_actions.py (+19/-6)
uaclient/tests/test_apt.py (+78/-13)
uaclient/tests/test_apt_news.py (+3/-3)
uaclient/tests/test_cli.py (+117/-43)
uaclient/tests/test_cli_api.py (+2/-1)
uaclient/tests/test_cli_attach.py (+8/-5)
uaclient/tests/test_cli_auto_attach.py (+4/-1)
uaclient/tests/test_cli_collect_logs.py (+34/-4)
uaclient/tests/test_cli_detach.py (+1/-0)
uaclient/tests/test_cli_disable.py (+8/-1)
uaclient/tests/test_cli_enable.py (+41/-3)
uaclient/tests/test_cli_fix.py (+12/-3)
uaclient/tests/test_cli_reboot_required.py (+2/-1)
uaclient/tests/test_cli_refresh.py (+5/-2)
uaclient/tests/test_cli_security_status.py (+4/-0)
uaclient/tests/test_cli_status.py (+8/-0)
uaclient/tests/test_config.py (+7/-53)
uaclient/tests/test_contract.py (+109/-82)
uaclient/tests/test_data_types.py (+8/-1)
uaclient/tests/test_livepatch.py (+18/-13)
uaclient/tests/test_reboot_cmds.py (+166/-154)
uaclient/tests/test_security.py (+542/-113)
uaclient/tests/test_security_status.py (+26/-8)
uaclient/tests/test_status.py (+74/-7)
uaclient/tests/test_system.py (+232/-101)
uaclient/tests/test_upgrade_lts_contract.py (+28/-53)
uaclient/tests/test_util.py (+31/-9)
uaclient/timer/__init__.py (+20/-0)
uaclient/timer/tests/test_update_contract_info.py (+2/-2)
uaclient/timer/tests/test_update_messaging.py (+2/-2)
uaclient/upgrade_lts_contract.py (+103/-0)
uaclient/util.py (+0/-1)
uaclient/version.py (+1/-1)
Reviewer Review Type Date Requested Status
Canonical Server Core Reviewers Pending
Canonical Server Reporter Pending
Review via email: mp+442895@code.launchpad.net

Description of the change

This is release 27.15 of ubuntu-advantage-tools.
This is the final 27.x release before we move to scheduled releases, which will each bump the main version.

SRU Bug: https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bug/2017949

To post a comment you must log in.
Revision history for this message
Grant Orndorff (orndorffgrant) wrote :
Download full text (8.1 KiB)

* Staging PPA Test Triggers:
  - Source ubuntu-advantage-tools/27.15~rc1: Published
    + amd64: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=amd64&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
    + arm64: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=arm64&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
    + armhf: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=armhf&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
    + ppc64el: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=ppc64el&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
    + s390x: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=s390x&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
    + riscv64: https://autopkgtest.ubuntu.com/request.cgi?release=mantic&package=ubuntu-advantage-tools&arch=riscv64&trigger=ubuntu-advantage-tools%2F27.15~rc1&ppa=ua-client%2Fstaging
  - Source ubuntu-advantage-tools/27.15~23.04~rc1: Published
    + amd64: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=amd64&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
    + arm64: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=arm64&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
    + armhf: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=armhf&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
    + ppc64el: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=ppc64el&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
    + s390x: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=s390x&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
    + riscv64: https://autopkgtest.ubuntu.com/request.cgi?release=lunar&package=ubuntu-advantage-tools&arch=riscv64&trigger=ubuntu-advantage-tools%2F27.15~23.04~rc1&ppa=ua-client%2Fstaging
  - Source ubuntu-advantage-tools/27.15~22.10~rc1: Published
    + amd64: https://autopkgtest.ubuntu.com/request.cgi?release=kinetic&package=ubuntu-advantage-tools&arch=amd64&trigger=ubuntu-advantage-tools%2F27.15~22.10~rc1&ppa=ua-client%2Fstaging
    + arm64: https://autopkgtest.ubuntu.com/request.cgi?release=kinetic&package=ubuntu-advantage-tools&arch=arm64&trigger=ubuntu-advantage-tools%2F27.15~22.10~rc1&ppa=ua-client%2Fstaging
    + armhf: https://autopkgtest.ubuntu.com/request.cgi?release=kinetic&package=ubuntu-advantage-tools&arch=armhf&trigger=ubuntu-advantage-tools%2F27.15~22.10~rc1&ppa=ua-client%2Fstaging
    + ppc64el: https://autopkgtest.ubuntu.com/request.cgi?release=kinetic&package=ubuntu-advantage-tools&arch=ppc64el&trigger=ubuntu-advantage-tools%2F27.15~22.10~rc1&ppa=ua-client%2Fstaging
    ...

Read more...

Revision history for this message
Grant Orndorff (orndorffgrant) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
2index abf1338..7faa407 100644
3--- a/.github/PULL_REQUEST_TEMPLATE.md
4+++ b/.github/PULL_REQUEST_TEMPLATE.md
5@@ -1,5 +1,13 @@
6-## Proposed Commit Message
7-<!-- Include a proposed commit message because all PRs can be merged in a variety of ways by the reviewer -->
8+## Why is this needed?
9+<!-- This information should be captured in your commit messages, so any description here can be very brief -->
10+This PR solves all of our problems because...
11+
12+<!--
13+By default, we rebase PRs and will ask for a clean well-organized commit history in the PR before rebasing.
14+If your PR is small enough and you prefer, uncomment the following section and fill it out to request a squashed PR.
15+-->
16+<!--
17+## Please Squash this PR with this commit message
18
19 ```
20 summary: no more than 70 characters
21@@ -14,6 +22,7 @@ If you need to write multiple paragraphs, feel free.
22 LP: #NNNNNNN (replace with the appropriate Launchpad bug reference if applicable)
23 Fixes: #NNNNNNN (replace with the appropriate github issue if applicable)
24 ```
25+-->
26
27 ## Test Steps
28 <!-- Please include any steps necessary to verify (and reproduce if
29@@ -21,6 +30,16 @@ this is a bug fix) this change on a live deployed system,
30 including any necessary configuration files, user-data,
31 setup, and teardown. Scripts used may be attached directly to this PR. -->
32
33+<!-- Example:
34+```
35+env SHELL_BEFORE=1 ./tools/test-in-lxd.sh xenial
36+# Set up test scenario before upgrade
37+exit # new version gets installed after exit and lxc shell is re-started
38+sudo pro new-sub-command --new-flag
39+# Assert something
40+```
41+-->
42+
43 ## Checklist
44 <!-- Go over all the following points, and put an `x` in all the boxes
45 that apply. -->
46diff --git a/.github/actions/bug-refs/action.yml b/.github/actions/bug-refs/action.yml
47new file mode 100644
48index 0000000..458d152
49--- /dev/null
50+++ b/.github/actions/bug-refs/action.yml
51@@ -0,0 +1,9 @@
52+name: 'Require Bug References'
53+description: 'Block PRs on missing bug references'
54+inputs:
55+ repo-token:
56+ description: 'Token for the repository. Can be passed in using {{ secrets.GITHUB_TOKEN }}'
57+ required: true
58+runs:
59+ using: 'node16'
60+ main: 'index.js'
61diff --git a/.github/actions/bug-refs/index.js b/.github/actions/bug-refs/index.js
62new file mode 100644
63index 0000000..7804e06
64--- /dev/null
65+++ b/.github/actions/bug-refs/index.js
66@@ -0,0 +1,61 @@
67+const core = require('@actions/core');
68+const github = require('@actions/github');
69+
70+async function run() {
71+ const context = github.context;
72+ if (context.eventName !== "pull_request") {
73+ console.log(
74+ 'The event that triggered this action was not a pull request, skipping.'
75+ );
76+ return;
77+ }
78+
79+ const body = context.payload.pull_request.body.toLocaleUpperCase();
80+ const ignoreJira = body.includes("NO-JIRA");
81+ const ignoreLaunchpad = body.includes("NO-LP");
82+ const ignoreGithub = body.includes("NO-GH");
83+
84+ const errorMessages = [];
85+
86+ const title = context.payload.pull_request.title;
87+ if (!ignoreJira && !title.toLocaleUpperCase().includes("SC-")) {
88+ errorMessages.push("The PR title does not include a Jira SC-#### reference.\nEither add one or add 'no-jira' to the PR description.");
89+ }
90+
91+ const client = github.getOctokit(
92+ core.getInput('repo-token', {required: true})
93+ );
94+ const commits = await client.rest.pulls.listCommits({
95+ owner: context.issue.owner,
96+ repo: context.issue.repo,
97+ pull_number: context.issue.number,
98+ });
99+
100+ let launchpadPresent = false;
101+ let githubPresent = false;
102+ commits.data.forEach(commit => {
103+ const message = commit.commit.message.toLocaleUpperCase();
104+ if (message.includes("LP: #")) {
105+ launchpadPresent = true;
106+ }
107+ if (message.includes("FIXES: #") || message.includes("CLOSES: #")) {
108+ githubPresent = true;
109+ }
110+ });
111+
112+ if (!ignoreLaunchpad && !launchpadPresent) {
113+ errorMessages.push("None of the commits include a Launchpad bug reference.\nEither add one or add 'no-lp' to the PR description.");
114+ }
115+ if (!ignoreGithub && !githubPresent) {
116+ errorMessages.push("None of the commits include a Github bug reference.\nEither add one or add 'no-gh' to the PR description.");
117+ }
118+
119+ if (errorMessages.length > 0) {
120+ core.setFailed(errorMessages.join("\n\n"));
121+ }
122+}
123+
124+run().catch(error => {
125+ console.error(error);
126+ core.setFailed(error.message);
127+})
128diff --git a/.github/actions/bug-refs/package-lock.json b/.github/actions/bug-refs/package-lock.json
129new file mode 100644
130index 0000000..f9ad26b
131--- /dev/null
132+++ b/.github/actions/bug-refs/package-lock.json
133@@ -0,0 +1,430 @@
134+{
135+ "name": "bug-refs",
136+ "version": "1.0.0",
137+ "lockfileVersion": 2,
138+ "requires": true,
139+ "packages": {
140+ "": {
141+ "name": "bug-refs",
142+ "version": "1.0.0",
143+ "dependencies": {
144+ "@actions/core": "^1.10.0",
145+ "@actions/github": "^5.1.1"
146+ }
147+ },
148+ "node_modules/@actions/core": {
149+ "version": "1.10.0",
150+ "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
151+ "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
152+ "dependencies": {
153+ "@actions/http-client": "^2.0.1",
154+ "uuid": "^8.3.2"
155+ }
156+ },
157+ "node_modules/@actions/github": {
158+ "version": "5.1.1",
159+ "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
160+ "integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
161+ "dependencies": {
162+ "@actions/http-client": "^2.0.1",
163+ "@octokit/core": "^3.6.0",
164+ "@octokit/plugin-paginate-rest": "^2.17.0",
165+ "@octokit/plugin-rest-endpoint-methods": "^5.13.0"
166+ }
167+ },
168+ "node_modules/@actions/http-client": {
169+ "version": "2.1.0",
170+ "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
171+ "integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
172+ "dependencies": {
173+ "tunnel": "^0.0.6"
174+ }
175+ },
176+ "node_modules/@octokit/auth-token": {
177+ "version": "2.5.0",
178+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
179+ "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
180+ "dependencies": {
181+ "@octokit/types": "^6.0.3"
182+ }
183+ },
184+ "node_modules/@octokit/core": {
185+ "version": "3.6.0",
186+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
187+ "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
188+ "dependencies": {
189+ "@octokit/auth-token": "^2.4.4",
190+ "@octokit/graphql": "^4.5.8",
191+ "@octokit/request": "^5.6.3",
192+ "@octokit/request-error": "^2.0.5",
193+ "@octokit/types": "^6.0.3",
194+ "before-after-hook": "^2.2.0",
195+ "universal-user-agent": "^6.0.0"
196+ }
197+ },
198+ "node_modules/@octokit/endpoint": {
199+ "version": "6.0.12",
200+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
201+ "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
202+ "dependencies": {
203+ "@octokit/types": "^6.0.3",
204+ "is-plain-object": "^5.0.0",
205+ "universal-user-agent": "^6.0.0"
206+ }
207+ },
208+ "node_modules/@octokit/graphql": {
209+ "version": "4.8.0",
210+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
211+ "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
212+ "dependencies": {
213+ "@octokit/request": "^5.6.0",
214+ "@octokit/types": "^6.0.3",
215+ "universal-user-agent": "^6.0.0"
216+ }
217+ },
218+ "node_modules/@octokit/openapi-types": {
219+ "version": "12.11.0",
220+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
221+ "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
222+ },
223+ "node_modules/@octokit/plugin-paginate-rest": {
224+ "version": "2.21.3",
225+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
226+ "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
227+ "dependencies": {
228+ "@octokit/types": "^6.40.0"
229+ },
230+ "peerDependencies": {
231+ "@octokit/core": ">=2"
232+ }
233+ },
234+ "node_modules/@octokit/plugin-rest-endpoint-methods": {
235+ "version": "5.16.2",
236+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
237+ "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
238+ "dependencies": {
239+ "@octokit/types": "^6.39.0",
240+ "deprecation": "^2.3.1"
241+ },
242+ "peerDependencies": {
243+ "@octokit/core": ">=3"
244+ }
245+ },
246+ "node_modules/@octokit/request": {
247+ "version": "5.6.3",
248+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
249+ "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
250+ "dependencies": {
251+ "@octokit/endpoint": "^6.0.1",
252+ "@octokit/request-error": "^2.1.0",
253+ "@octokit/types": "^6.16.1",
254+ "is-plain-object": "^5.0.0",
255+ "node-fetch": "^2.6.7",
256+ "universal-user-agent": "^6.0.0"
257+ }
258+ },
259+ "node_modules/@octokit/request-error": {
260+ "version": "2.1.0",
261+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
262+ "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
263+ "dependencies": {
264+ "@octokit/types": "^6.0.3",
265+ "deprecation": "^2.0.0",
266+ "once": "^1.4.0"
267+ }
268+ },
269+ "node_modules/@octokit/types": {
270+ "version": "6.41.0",
271+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
272+ "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
273+ "dependencies": {
274+ "@octokit/openapi-types": "^12.11.0"
275+ }
276+ },
277+ "node_modules/before-after-hook": {
278+ "version": "2.2.3",
279+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
280+ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
281+ },
282+ "node_modules/deprecation": {
283+ "version": "2.3.1",
284+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
285+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
286+ },
287+ "node_modules/is-plain-object": {
288+ "version": "5.0.0",
289+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
290+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
291+ "engines": {
292+ "node": ">=0.10.0"
293+ }
294+ },
295+ "node_modules/node-fetch": {
296+ "version": "2.6.9",
297+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
298+ "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
299+ "dependencies": {
300+ "whatwg-url": "^5.0.0"
301+ },
302+ "engines": {
303+ "node": "4.x || >=6.0.0"
304+ },
305+ "peerDependencies": {
306+ "encoding": "^0.1.0"
307+ },
308+ "peerDependenciesMeta": {
309+ "encoding": {
310+ "optional": true
311+ }
312+ }
313+ },
314+ "node_modules/once": {
315+ "version": "1.4.0",
316+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
317+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
318+ "dependencies": {
319+ "wrappy": "1"
320+ }
321+ },
322+ "node_modules/tr46": {
323+ "version": "0.0.3",
324+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
325+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
326+ },
327+ "node_modules/tunnel": {
328+ "version": "0.0.6",
329+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
330+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
331+ "engines": {
332+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
333+ }
334+ },
335+ "node_modules/universal-user-agent": {
336+ "version": "6.0.0",
337+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
338+ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
339+ },
340+ "node_modules/uuid": {
341+ "version": "8.3.2",
342+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
343+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
344+ "bin": {
345+ "uuid": "dist/bin/uuid"
346+ }
347+ },
348+ "node_modules/webidl-conversions": {
349+ "version": "3.0.1",
350+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
351+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
352+ },
353+ "node_modules/whatwg-url": {
354+ "version": "5.0.0",
355+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
356+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
357+ "dependencies": {
358+ "tr46": "~0.0.3",
359+ "webidl-conversions": "^3.0.0"
360+ }
361+ },
362+ "node_modules/wrappy": {
363+ "version": "1.0.2",
364+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
365+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
366+ }
367+ },
368+ "dependencies": {
369+ "@actions/core": {
370+ "version": "1.10.0",
371+ "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
372+ "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
373+ "requires": {
374+ "@actions/http-client": "^2.0.1",
375+ "uuid": "^8.3.2"
376+ }
377+ },
378+ "@actions/github": {
379+ "version": "5.1.1",
380+ "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
381+ "integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
382+ "requires": {
383+ "@actions/http-client": "^2.0.1",
384+ "@octokit/core": "^3.6.0",
385+ "@octokit/plugin-paginate-rest": "^2.17.0",
386+ "@octokit/plugin-rest-endpoint-methods": "^5.13.0"
387+ }
388+ },
389+ "@actions/http-client": {
390+ "version": "2.1.0",
391+ "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
392+ "integrity": "sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw==",
393+ "requires": {
394+ "tunnel": "^0.0.6"
395+ }
396+ },
397+ "@octokit/auth-token": {
398+ "version": "2.5.0",
399+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
400+ "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
401+ "requires": {
402+ "@octokit/types": "^6.0.3"
403+ }
404+ },
405+ "@octokit/core": {
406+ "version": "3.6.0",
407+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
408+ "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
409+ "requires": {
410+ "@octokit/auth-token": "^2.4.4",
411+ "@octokit/graphql": "^4.5.8",
412+ "@octokit/request": "^5.6.3",
413+ "@octokit/request-error": "^2.0.5",
414+ "@octokit/types": "^6.0.3",
415+ "before-after-hook": "^2.2.0",
416+ "universal-user-agent": "^6.0.0"
417+ }
418+ },
419+ "@octokit/endpoint": {
420+ "version": "6.0.12",
421+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
422+ "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
423+ "requires": {
424+ "@octokit/types": "^6.0.3",
425+ "is-plain-object": "^5.0.0",
426+ "universal-user-agent": "^6.0.0"
427+ }
428+ },
429+ "@octokit/graphql": {
430+ "version": "4.8.0",
431+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
432+ "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
433+ "requires": {
434+ "@octokit/request": "^5.6.0",
435+ "@octokit/types": "^6.0.3",
436+ "universal-user-agent": "^6.0.0"
437+ }
438+ },
439+ "@octokit/openapi-types": {
440+ "version": "12.11.0",
441+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz",
442+ "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ=="
443+ },
444+ "@octokit/plugin-paginate-rest": {
445+ "version": "2.21.3",
446+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
447+ "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
448+ "requires": {
449+ "@octokit/types": "^6.40.0"
450+ }
451+ },
452+ "@octokit/plugin-rest-endpoint-methods": {
453+ "version": "5.16.2",
454+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
455+ "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
456+ "requires": {
457+ "@octokit/types": "^6.39.0",
458+ "deprecation": "^2.3.1"
459+ }
460+ },
461+ "@octokit/request": {
462+ "version": "5.6.3",
463+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
464+ "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
465+ "requires": {
466+ "@octokit/endpoint": "^6.0.1",
467+ "@octokit/request-error": "^2.1.0",
468+ "@octokit/types": "^6.16.1",
469+ "is-plain-object": "^5.0.0",
470+ "node-fetch": "^2.6.7",
471+ "universal-user-agent": "^6.0.0"
472+ }
473+ },
474+ "@octokit/request-error": {
475+ "version": "2.1.0",
476+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
477+ "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
478+ "requires": {
479+ "@octokit/types": "^6.0.3",
480+ "deprecation": "^2.0.0",
481+ "once": "^1.4.0"
482+ }
483+ },
484+ "@octokit/types": {
485+ "version": "6.41.0",
486+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz",
487+ "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==",
488+ "requires": {
489+ "@octokit/openapi-types": "^12.11.0"
490+ }
491+ },
492+ "before-after-hook": {
493+ "version": "2.2.3",
494+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
495+ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ=="
496+ },
497+ "deprecation": {
498+ "version": "2.3.1",
499+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
500+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
501+ },
502+ "is-plain-object": {
503+ "version": "5.0.0",
504+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
505+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
506+ },
507+ "node-fetch": {
508+ "version": "2.6.9",
509+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
510+ "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
511+ "requires": {
512+ "whatwg-url": "^5.0.0"
513+ }
514+ },
515+ "once": {
516+ "version": "1.4.0",
517+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
518+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
519+ "requires": {
520+ "wrappy": "1"
521+ }
522+ },
523+ "tr46": {
524+ "version": "0.0.3",
525+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
526+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
527+ },
528+ "tunnel": {
529+ "version": "0.0.6",
530+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
531+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
532+ },
533+ "universal-user-agent": {
534+ "version": "6.0.0",
535+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
536+ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
537+ },
538+ "uuid": {
539+ "version": "8.3.2",
540+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
541+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
542+ },
543+ "webidl-conversions": {
544+ "version": "3.0.1",
545+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
546+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
547+ },
548+ "whatwg-url": {
549+ "version": "5.0.0",
550+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
551+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
552+ "requires": {
553+ "tr46": "~0.0.3",
554+ "webidl-conversions": "^3.0.0"
555+ }
556+ },
557+ "wrappy": {
558+ "version": "1.0.2",
559+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
560+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
561+ }
562+ }
563+}
564diff --git a/.github/actions/bug-refs/package.json b/.github/actions/bug-refs/package.json
565new file mode 100644
566index 0000000..14ceb07
567--- /dev/null
568+++ b/.github/actions/bug-refs/package.json
569@@ -0,0 +1,10 @@
570+{
571+ "name": "bug-refs",
572+ "version": "1.0.0",
573+ "description": "Block PRs on missing bug references",
574+ "main": "index.js",
575+ "dependencies": {
576+ "@actions/core": "^1.10.0",
577+ "@actions/github": "^5.1.1"
578+ }
579+}
580diff --git a/.github/workflows/ci-base.yaml b/.github/workflows/ci-base.yaml
581index 59174bf..dab17d3 100644
582--- a/.github/workflows/ci-base.yaml
583+++ b/.github/workflows/ci-base.yaml
584@@ -29,6 +29,8 @@ jobs:
585 run: tox -e mypy
586 - name: Version Consistency
587 run: python3 ./tools/check-versions-are-consistent.py
588+ - name: Docs
589+ run: tox -e docs
590 unit-tests:
591 name: Unit Tests
592 runs-on: ubuntu-22.04
593diff --git a/.github/workflows/ci-integration.yaml b/.github/workflows/ci-integration.yaml
594index 62df9e3..937de39 100644
595--- a/.github/workflows/ci-integration.yaml
596+++ b/.github/workflows/ci-integration.yaml
597@@ -92,6 +92,9 @@ jobs:
598 # in a way that is incompatible with lxd.
599 # https://linuxcontainers.org/lxd/docs/master/howto/network_bridge_firewalld/#prevent-issues-with-lxd-and-docker
600 sudo iptables -I DOCKER-USER -j ACCEPT
601+ - name: Refresh LXD
602+ if: matrix.platform == 'lxd' || matrix.platform == 'vm'
603+ run: sudo snap refresh --channel latest/stable lxd
604 - name: Initialize LXD
605 if: matrix.platform == 'lxd' || matrix.platform == 'vm'
606 run: sudo lxd init --auto
607diff --git a/.github/workflows/custom_pr_checks.yaml b/.github/workflows/custom_pr_checks.yaml
608new file mode 100644
609index 0000000..b3be667
610--- /dev/null
611+++ b/.github/workflows/custom_pr_checks.yaml
612@@ -0,0 +1,27 @@
613+---
614+
615+name: Custom PR Checks
616+
617+on:
618+ pull_request:
619+ types:
620+ - opened
621+ - synchronize
622+ - reopened
623+ - edited
624+ branches:
625+ - main
626+
627+jobs:
628+ bug-refs:
629+ runs-on: ubuntu-latest
630+ steps:
631+ - name: Git checkout
632+ uses: actions/checkout@v3
633+ - name: Install dependencies
634+ run: cd ./.github/actions/bug-refs && npm install
635+ - name: Check for bug references
636+ uses: ./.github/actions/bug-refs
637+ id: bug-refs
638+ with:
639+ repo-token: ${{ secrets.GITHUB_TOKEN }}
640diff --git a/apport/source_ubuntu-advantage-tools.py b/apport/source_ubuntu-advantage-tools.py
641index 193d557..f2c4f1a 100644
642--- a/apport/source_ubuntu-advantage-tools.py
643+++ b/apport/source_ubuntu-advantage-tools.py
644@@ -2,6 +2,7 @@ import os
645 import tempfile
646
647 from apport.hookutils import attach_file_if_exists
648+from uaclient import defaults
649 from uaclient.actions import collect_logs
650 from uaclient.config import UAConfig
651
652@@ -12,7 +13,7 @@ def add_info(report, ui=None):
653 cfg = UAConfig()
654 with tempfile.TemporaryDirectory() as output_dir:
655 collect_logs(cfg, output_dir)
656- auto_include_log_files = [
657+ auto_include_log_files = {
658 "cloud-id.txt",
659 "cloud-id.txt-error",
660 "ua-status.json",
661@@ -24,6 +25,9 @@ def add_info(report, ui=None):
662 os.path.basename(cfg.timer_log_file),
663 os.path.basename(cfg.daemon_log_file),
664 os.path.basename(cfg.data_path("jobs-status")),
665- ]
666+ os.path.basename(defaults.CONFIG_DEFAULTS["log_file"]),
667+ os.path.basename(defaults.CONFIG_DEFAULTS["timer_log_file"]),
668+ os.path.basename(defaults.CONFIG_DEFAULTS["daemon_log_file"]),
669+ }
670 for f in auto_include_log_files:
671 attach_file_if_exists(report, os.path.join(output_dir, f), key=f)
672diff --git a/apt-hook/json-hook.cc b/apt-hook/json-hook.cc
673index 1d36bd2..61548b7 100644
674--- a/apt-hook/json-hook.cc
675+++ b/apt-hook/json-hook.cc
676@@ -218,13 +218,17 @@ CloudID get_cloud_id() {
677 return ret;
678 }
679
680-bool is_xenial() {
681+enum ESMInfraSeries {NOT_ESM_INFRA, XENIAL, BIONIC};
682+
683+ESMInfraSeries get_esm_infra_series() {
684 std::ifstream os_release_file("/etc/os-release");
685- bool ret = false;
686+ ESMInfraSeries ret = NOT_ESM_INFRA;
687 if (os_release_file.is_open()) {
688 std::string os_release_str((std::istreambuf_iterator<char>(os_release_file)), (std::istreambuf_iterator<char>()));
689 if (os_release_str.find("xenial") != os_release_str.npos) {
690- ret = true;
691+ ret = XENIAL;
692+ } else if (os_release_str.find("bionic") != os_release_str.npos) {
693+ ret = BIONIC;
694 }
695 os_release_file.close();
696 }
697@@ -238,27 +242,39 @@ struct ESMContext {
698
699 ESMContext get_esm_context() {
700 CloudID cloud_id = get_cloud_id();
701- bool is_x = is_xenial();
702+ ESMInfraSeries esm_infra_series = get_esm_infra_series();
703
704 ESMContext ret;
705 ret.context = "";
706 ret.url = "https://ubuntu.com/pro";
707
708- if (cloud_id != AZURE && is_x) {
709- ret.context = " for 16.04";
710- ret.url = "https://ubuntu.com/16-04";
711- } else if (cloud_id == AZURE && !is_x) {
712- ret.context = " on Azure";
713- ret.url = "https://ubuntu.com/azure/pro";
714- } else if (cloud_id == AZURE && is_x) {
715- ret.context = " for 16.04 on Azure";
716- ret.url = "https://ubuntu.com/16-04/azure";
717- } else if (cloud_id == AWS && !is_x) {
718- ret.context = " on AWS";
719- ret.url = "https://ubuntu.com/aws/pro";
720- } else if (cloud_id == GCE && !is_x) {
721- ret.context = " on GCP";
722- ret.url = "https://ubuntu.com/gcp/pro";
723+ if (esm_infra_series == XENIAL) {
724+ if (cloud_id == AZURE) {
725+ ret.context = " for 16.04 on Azure";
726+ ret.url = "https://ubuntu.com/16-04/azure";
727+ } else {
728+ ret.context = " for 16.04";
729+ ret.url = "https://ubuntu.com/16-04";
730+ }
731+ } else if (esm_infra_series == BIONIC) {
732+ if (cloud_id == AZURE) {
733+ ret.context = " for 18.04 on Azure";
734+ ret.url = "https://ubuntu.com/18-04/azure";
735+ } else {
736+ ret.context = " for 18.04";
737+ ret.url = "https://ubuntu.com/18-04";
738+ }
739+ } else {
740+ if (cloud_id == AZURE) {
741+ ret.context = " on Azure";
742+ ret.url = "https://ubuntu.com/azure/pro";
743+ } else if (cloud_id == AWS) {
744+ ret.context = " on AWS";
745+ ret.url = "https://ubuntu.com/aws/pro";
746+ } else if (cloud_id == GCE) {
747+ ret.context = " on GCP";
748+ ret.url = "https://ubuntu.com/gcp/pro";
749+ }
750 }
751
752 return ret;
753diff --git a/apt.conf.d/51ubuntu-advantage-esm b/apt.conf.d/51ubuntu-advantage-esm
754deleted file mode 100644
755index e9b1c3a..0000000
756--- a/apt.conf.d/51ubuntu-advantage-esm
757+++ /dev/null
758@@ -1,6 +0,0 @@
759-Unattended-Upgrade::Allowed-Origins {
760- "${distro_id}ESM:${distro_codename}-infra-security";
761-};
762-Unattended-Upgrade::Allowed-Origins {
763- "${distro_id}ESMApps:${distro_codename}-apps-security";
764-};
765diff --git a/debian/changelog b/debian/changelog
766index 69290bb..e9979e2 100644
767--- a/debian/changelog
768+++ b/debian/changelog
769@@ -1,3 +1,41 @@
770+ubuntu-advantage-tools (27.15) mantic; urgency=medium
771+
772+ * d/ubuntu-advantage-tools.postinst:
773+ - more specific regex for ua_config warning
774+ * New upstream release 27.15 (LP: #2017949)
775+ - apport: collect default log files if present for bug reports
776+ - apt messaging: add bionic-specific urls
777+ - config: no longer load uaclient.conf from current working directory
778+ - fix:
779+ + add support for --no-related flag
780+ + separate target USN from related USNs
781+ - general:
782+ + logs to user cache directory when run as non-root
783+ + fix bug where non-root commands failed with file permission error
784+ accessing /tmp/ubuntu-advantage (GH: #2567)
785+ + use system environment vars by default in sub processes (GH: #2527)
786+ + fall back to /usr/lib/os-release for release info
787+ + start logging to default log file until config is loaded
788+ + remove small timeout from contract checking request
789+ - livepatch: use uname.machine for kernel arch when checking support
790+ (GH: #2517)
791+ - realtime-kernel: add support for intel-iotg variant
792+ - reboot-required: new criteria for "yes-kernel-livepatches-applied"
793+ livepatch status must be either "applied" or "nothing-to-apply" and
794+ livepatch support status must say "supported"
795+ - security-status:
796+ + always show available/installed counts for esm packages
797+ + include hint to run apt-get update for up-to-date info (GH: #2443)
798+ + improve visibility of installed and available updates (GH: #2442)
799+ + change package info message hint to recommend apt-cache show
800+ - systemd: update service unit for reboot_cmds to not run if not attached
801+ - status:
802+ + add hint for pro status --all
803+ + better message if no services are available (LP: #1994923)
804+ - timer: only run timer when attached
805+
806+ -- Grant Orndorff <grant.orndorff@canonical.com> Thu, 27 Apr 2023 16:34:55 -0400
807+
808 ubuntu-advantage-tools (27.14.4) lunar; urgency=medium
809
810 * timer: disable update_contract_info job (LP: #2015302)
811diff --git a/debian/ubuntu-advantage-tools.postinst b/debian/ubuntu-advantage-tools.postinst
812index 7d9d03e..31d93ae 100644
813--- a/debian/ubuntu-advantage-tools.postinst
814+++ b/debian/ubuntu-advantage-tools.postinst
815@@ -452,7 +452,7 @@ case "$1" in
816 migrate_user_config_post
817 fi
818
819- if grep -q "ua_config:" /etc/ubuntu-advantage/uaclient.conf; then
820+ if grep -q "^ua_config:" /etc/ubuntu-advantage/uaclient.conf; then
821 echo "Warning: uaclient.conf contains old ua_config field." >&2
822 echo " Please do the following:" >&2
823 echo " 1. Run 'pro config set field=value' for each field/value pair" >&2
824diff --git a/docs/README.md b/dev-docs/howtoguides/build-docs.md
825similarity index 100%
826rename from docs/README.md
827rename to dev-docs/howtoguides/build-docs.md
828diff --git a/dev-docs/howtoguides/building.md b/dev-docs/howtoguides/building.md
829index 17be892..40b4d70 100644
830--- a/dev-docs/howtoguides/building.md
831+++ b/dev-docs/howtoguides/building.md
832@@ -41,16 +41,3 @@ sbuild-launchpad-chroot create --architecture="riscv64" "--name=focal-riscv64" "
833 > # this script can be used to update all chroots
834 > sudo PATTERN=\* sh /usr/share/doc/sbuild/examples/sbuild-debian-developer-setup-update-all
835 > ```
836-
837-## Setting up an lxc development container
838-```shell
839-lxc launch ubuntu-daily:xenial dev-x -c user.user-data="$(cat tools/ua-dev-cloud-config.yaml)"
840-lxc exec dev-x bash
841-```
842-
843-## Setting up a kvm development environment with multipass
844-**Note:** There is a sample procedure documented in tools/multipass.md as well.
845-```shell
846-multipass launch daily:focal -n dev-f --cloud-init tools/ua-dev-cloud-config.yaml
847-multipass connect dev-f
848-```
849diff --git a/dev-docs/howtoguides/how_to_release_a_new_version_of_ua.md b/dev-docs/howtoguides/release_a_new_version.md
850similarity index 75%
851rename from dev-docs/howtoguides/how_to_release_a_new_version_of_ua.md
852rename to dev-docs/howtoguides/release_a_new_version.md
853index 7a067dc..9d9109c 100644
854--- a/dev-docs/howtoguides/how_to_release_a_new_version_of_ua.md
855+++ b/dev-docs/howtoguides/release_a_new_version.md
856@@ -31,6 +31,14 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
857 ```
858 * 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.
859
860+* In order to run the `ppa` command, install `ppa-dev-tools` from `bryce`'s PPA:
861+ ```bash
862+ sudo add-apt-repository ppa:bryce/ppa-dev-tools
863+ sudo apt update
864+ sudo apt install ppa-dev-tools
865+ ```
866+ When running `ppa` for the first time, there will be another round of launchpad authorization to be performed.
867+
868 ## I. Preliminary/staging release to team infrastructure
869 1. Create a release PR:
870
871@@ -41,7 +49,7 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
872 b Create a new entry in the `debian/changelog` file:
873
874 * You can do that by running `dch --newversion <version-name>`.
875- * 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 pro-client and ubuntu/devel version numbers.
876+ * Remember to update the release from `UNRELEASED` to the ubuntu/devel release. Edit the version to look like: `27.2`, with the appropriate pro-client version number.
877 * Populate `debian/changelog` with the commits you have cherry-picked.
878 * You can do that by running `git log <first-cherry-pick-commit>..<last-cherry-pick-commit> | log2dch`
879 * This will generate a list of commits that could be included in the changelog.
880@@ -84,7 +92,7 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
881
882 b. Edit the changelog
883 * List yourself as the author of this release.
884- * Edit the version number to look like: `27.2~20.04.1~rc1` (`<version>~<ubuntu-release-number>.<revno>~rc<release-candidate-number>`)
885+ * Edit the version number to look like: `27.2~rc1` (`<version>~rc<release-candidate-number>`)
886 * Edit the Ubuntu release name. Start with the ubuntu/devel release.
887 * `git add debian/changelog && git commit -m "throwaway"` - Do **not** push this commit!
888
889@@ -95,9 +103,10 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
890 * If this succeeds move on. If this fails, debug and fix before continuing.
891
892 e. Repeat 3.b through 3.d for all supported Ubuntu Releases
893- * PS: remember to also change the version number on the changelog. For example, suppose
894- the new version is `1.1~20.04.1~rc1`. If you want to test Bionic now, change it to
895- `1.1~18.04.1~rc1`.
896+ * The version for series other than devel should be in the form `<version>~<ubuntu-release-number>~rc<release-candidate-number>`
897+ This means you must add the release number in the changelog. For example, suppose
898+ the devel version is `1.1~rc1`. If you want to build for jammy now, change it to
899+ `1.1~22.04~rc1`.
900
901 f. For each release, dput to the staging PPA:
902 * `dput ppa:ua-client/staging ../out/<package_name>_source.changes`
903@@ -136,14 +145,17 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
904 e. `git checkout -B upload-<this-version>-kinetic`
905 * This creates a new local branch name based on your detached branch.
906
907- f. Make sure the changelog version contains the release version in the name (e.g., `27.1~22.10.1`)
908+ f. `git push <your_launchpad_user> upload-<this-version>-kinetic`
909
910- g. `git push <your_launchpad_user> upload-<this-version>-kinetic`
911-
912- h. On Launchpad, create a merge proposal for this version which targets `ubuntu/devel`
913- * For an example, see the [27.9 merge proposal](https://code.launchpad.net/~orndorffgrant/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/+merge/422906).
914+ g. On Launchpad, create a merge proposal for this version which targets `ubuntu/devel`
915+ * For an example, see the [27.14.1 merge proposal](https://code.launchpad.net/~renanrodrigo/ubuntu/+source/ubuntu-advantage-tools/+git/ubuntu-advantage-tools/+merge/439507).
916 * Add 2 review slots for `canonical-server-reporter` and `canonical-server-core-reviewers`.
917
918+ h. With the packages published to `ppa:ua-client/staging`, add links to the autopkgtest triggers to the Merge Proposal. The reviewer will have permission to trigger those tests. The links can be obtained by running `ppa tests -r <release> -a <arch1,arch2> ua-client/staging -L`
919+ * Make sure to post links to all the architectures built for a given release.
920+ * The riscv64 autopkgtests are not avaialble and don't need to be included.
921+ * The `ppa test` command will have two variations of tests: the regular one, and one with `all-proposed=1`; only the regular test need to be there.
922+
923 4. Server Team Review and Pre-SRU Review
924
925 a. Ask the assigned ubuntu-advantage-tools reviewer/sponsor from Server team for a review of your MPs. If you don't know who that is, ask in ~Server. Include a link to the ubuntu/devel MP and to the SRU bug.
926@@ -160,7 +172,12 @@ If this is your first time releasing ubuntu-advantage-tools, you'll need to do t
927 * Follow instructions in `II.4.b` if they request any changes.
928
929 e. Once the SRU team member gives a pre-SRU approval, create the branches for each stable release. They should be named `upload-<this-version>-<codename>`.
930+ * The versions for the stable releases must include `~<release-number>`
931 * If you've followed the instructions precisely so far, you can just run `bash tools/create-lp-release-branches.sh`.
932+ - When using the `create-lp-release-branches.sh` script, an important parameter is `SRU_BUG`:
933+ - In the vast majority of cases, this should be set to the overall SRU bug written in step II.1.b.
934+ - In the case where an existing SRU never got released, and a new patch version was uploaded on top of it to fix a new bug discovered during review, then the bug should still be the overall SRU bug.
935+ - If the release is exclusively a bugfix release and the previous version has already been successfully released all the way through the SRU process, then the bug should instead be the specific bugfix number.
936
937 f. Ask Server team member sponsor to upload to devel, and then the SRU proposed queue using the stable release branches you just created.
938 * Ask them to tag the PR with the appropriate `upload/<version>` tag so git-ubuntu will import rich commit history.
939diff --git a/dev-docs/howtoguides/testing.md b/dev-docs/howtoguides/testing.md
940index fb0519a..37d6cb2 100644
941--- a/dev-docs/howtoguides/testing.md
942+++ b/dev-docs/howtoguides/testing.md
943@@ -175,17 +175,6 @@ To specifically run non-ubuntu pro tests using canonical cloud-images an
944 additional token obtained from https://ubuntu.com/pro needs to be set:
945 - UACLIENT_BEHAVE_CONTRACT_TOKEN=<your_token>
946
947-By default, the public AMIs for Ubuntu Pro testing used for each Ubuntu
948-release are defined in features/aws-ids.yaml. These ami-ids are determined by
949-running `./tools/refresh-aws-pro-ids`.
950-
951-Integration tests will read features/aws-ids.yaml to determine which default
952-AMI id to use for each supported Ubuntu release.
953-
954-To update `features/aws-ids.yaml`, run `./tools/refresh-aws-pro-ids` and put up
955-a pull request against this repo to updated that content from the ua-contracts
956-marketplace definitions.
957-
958 * To manually run EC2 integration tests with a specific AMI Id provide the
959 following environment variable to launch your specific AMI instead of building
960 a daily ubuntu-advantage-tools image.
961diff --git a/dev-docs/references/directory_layout.md b/dev-docs/references/directory_layout.md
962index 241fa36..ccee76b 100644
963--- a/dev-docs/references/directory_layout.md
964+++ b/dev-docs/references/directory_layout.md
965@@ -14,7 +14,6 @@ The following describes the intent of Ubuntu Pro Client related directories:
966 | uaclient.messages | Module that contains the messages delivered by `pro` to the user |
967 | uaclient.security | Module that hold the logic used to run `pro fix` commands |
968 | ./apt-hook/ | the C++ apt-hook delivering MOTD and apt command notifications about Ubuntu Pro support services |
969-| ./apt-conf.d/ | apt config files delivered to /etc/apt/apt-conf.d to automatically allow unattended upgrades of ESM security-related components. If apt proxy settings are configured, an additional apt config file will be placed here to configure the apt proxy. |
970 | /etc/ubuntu-advantage/uaclient.conf | Configuration file for the Ubuntu Pro Client.|
971 | /var/lib/ubuntu-advantage/private | `root` read-only directory containing Contract API responses, machine-tokens and service credentials |
972 | /var/lib/ubuntu-advantage/machine-token.json | `world` readable file containing redacted Contract API responses, machine-tokens and service credentials |
973diff --git a/dev-docs/references/version_string_formatting.md b/dev-docs/references/version_string_formatting.md
974index 98c150e..59f163c 100644
975--- a/dev-docs/references/version_string_formatting.md
976+++ b/dev-docs/references/version_string_formatting.md
977@@ -5,10 +5,10 @@ Below are the versioning schemes used for publishing debs:
978 | Build target | Version Format |
979 | --------------------------------------------------------------------------------- | ------------------------------------------ |
980 | [Daily PPA](https://code.launchpad.net/~canonical-server/+recipe/ua-client-daily) | `XX.YY-<revno>~g<commitish>~ubuntu22.04.1` |
981-| Staging PPA | `XX.YY~22.04.1~rc1` |
982-| Stable PPA | `XX.YY~22.04.1~stableppa1` |
983-| Archive release | `XX.YY~22.04.1` |
984-| Archive bugfix release | `XX.YY.Z~22.04.1` |
985+| Staging PPA | `XX.YY~22.04~rc1` |
986+| Stable PPA | `XX.YY~22.04~stableppa1` |
987+| Archive release | `XX.YY~22.04` |
988+| Archive bugfix release | `XX.YY.Z~22.04` |
989
990 ## Supported upgrade paths on same upstream version
991
992@@ -18,10 +18,10 @@ This table demonstrates upgrade paths between sources for one particular upstrea
993
994 | Upgrade path | Version diff example |
995 | ------------------------------- | ----------------------------------------------------------------------- |
996-| Staging to Next Staging rev | `31.4~22.04.1~rc1` ➜ `31.4~22.04.1~rc2` |
997-| Staging to Stable | `31.4~22.04.1~rc2` ➜ `31.4~22.04.1~stableppa1` |
998-| Stable to Next Stable rev | `31.4~22.04.1~stableppa1` ➜ `31.4~22.04.1~stableppa2` |
999-| Stable to Archive | `31.4~22.04.1~stableppa2` ➜ `31.4~22.04.1` |
1000-| LTS Archive to Next LTS Archive | `31.4~22.04.1` ➜ `31.4~24.04.1` |
1001-| Archive to Daily | `31.4~24.04.1` ➜ `31.4-1500~g75fa134~ubuntu24.04.1` |
1002+| Staging to Next Staging rev | `31.4~22.04~rc1` ➜ `31.4~22.04~rc2` |
1003+| Staging to Stable | `31.4~22.04~rc2` ➜ `31.4~22.04~stableppa1` |
1004+| Stable to Next Stable rev | `31.4~22.04~stableppa1` ➜ `31.4~22.04~stableppa2` |
1005+| Stable to Archive | `31.4~22.04~stableppa2` ➜ `31.4~22.04` |
1006+| LTS Archive to Next LTS Archive | `31.4~22.04` ➜ `31.4~24.04` |
1007+| Archive to Daily | `31.4~24.04` ➜ `31.4-1500~g75fa134~ubuntu24.04.1` |
1008 | Daily to Next Daily | `31.4-1500~g75fa134~ubuntu24.04.1` ➜ `31.4-1501~g3836375~ubuntu24.04.1` |
1009diff --git a/docs/_static/js/github_issue_links.js b/docs/_static/js/github_issue_links.js
1010index e449b4e..d339060 100644
1011--- a/docs/_static/js/github_issue_links.js
1012+++ b/docs/_static/js/github_issue_links.js
1013@@ -2,7 +2,7 @@ window.onload = function() {
1014 const link = document.createElement("a");
1015 link.classList.add("muted-link");
1016 link.classList.add("github-issue-link");
1017- link.text = "Have a question?";
1018+ link.text = "Give feedback";
1019 link.href = (
1020 "https://github.com/canonical/ubuntu-pro-client/issues/new?"
1021 + "title=docs%3A+TYPE+YOUR+QUESTION+HERE"
1022diff --git a/docs/conf.py b/docs/conf.py
1023index 8dd4d59..f1f82b0 100644
1024--- a/docs/conf.py
1025+++ b/docs/conf.py
1026@@ -38,6 +38,11 @@ extensions = [
1027
1028 templates_path = ["_templates"]
1029
1030+html_extra_path = [
1031+ "googleaf254801a5285c31.html",
1032+ "sitemap-index.xml"
1033+]
1034+
1035 # List of patterns, relative to source directory, that match files and
1036 # directories to ignore when looking for source files.
1037 # This pattern also affects html_static_path and html_extra_path.
1038@@ -100,7 +105,7 @@ html_static_path = ["_static"]
1039 html_css_files = [
1040 "css/logo.css",
1041 "css/github_issue_links.css",
1042- "css/custom.css"
1043+ "css/custom.css",
1044 ]
1045 html_js_files = [
1046 "js/github_issue_links.js",
1047diff --git a/docs/explanations.rst b/docs/explanations.rst
1048index a424451..78adb85 100644
1049--- a/docs/explanations.rst
1050+++ b/docs/explanations.rst
1051@@ -27,6 +27,7 @@ selection of some of the commands -- what they do, and how they work.
1052 :maxdepth: 1
1053
1054 explanations/how_to_interpret_the_security_status_command.md
1055+ explanations/how_to_interpret_output_of_unattended_upgrades.md
1056 explanations/status_columns.md
1057 explanations/what_refresh_does.md
1058
1059@@ -48,6 +49,7 @@ Other Pro features explained
1060 .. toctree::
1061 :maxdepth: 1
1062
1063+ explanations/cves_and_usns_explained.md
1064 explanations/what_are_the_timer_jobs.md
1065 explanations/what_is_the_daemon.md
1066 explanations/why_trusty_is_no_longer_supported.md
1067diff --git a/docs/explanations/apt_messages.md b/docs/explanations/apt_messages.md
1068index d4e62ef..edd50d2 100644
1069--- a/docs/explanations/apt_messages.md
1070+++ b/docs/explanations/apt_messages.md
1071@@ -25,7 +25,7 @@ Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04
1072
1073 ## LTS series with esm-apps service disabled
1074
1075-When you are running `apt upgraded` on a LTS release, like Focal, we advertise
1076+When you are running `apt upgrade` on a LTS release, like Focal, we advertise
1077 the `esm-apps` service if packages could be upgraded by enabling the service:
1078
1079 ```
1080diff --git a/docs/explanations/cves_and_usns_explained.md b/docs/explanations/cves_and_usns_explained.md
1081new file mode 100644
1082index 0000000..272c1d8
1083--- /dev/null
1084+++ b/docs/explanations/cves_and_usns_explained.md
1085@@ -0,0 +1,44 @@
1086+# CVEs and USNs explained
1087+
1088+## What is a CVE
1089+
1090+Common Vulnerabilities and Exposures (CVEs) are a way to catalogue and track public security
1091+vulnerabilities for a given software. Every CVE is identified through a unique identifier,
1092+for example [CVE-2023-0465](https://www.cve.org/CVERecord?id=CVE-2023-0465).
1093+
1094+CVEs are maintained by the [MITRE Corporation](https://cve.mitre.org/) and the goal of the project
1095+is to provide naming conventions for the public known security issues while also maintaining a
1096+centralised repository for all of the security issues. This makes it easier for an organization to
1097+submit a new security flaw though the CVE convention while also analysing any other existing CVEs
1098+in the database.
1099+
1100+You can search for any existing CVE related to Ubuntu using
1101+[the Ubuntu CVE page](https://ubuntu.com/security/cves).
1102+
1103+## What is a USN?
1104+
1105+An Ubuntu Security Notice (USN) is the way that Canonical publicly catalogues and displays security
1106+vulneratibilities for Ubuntu packages. Usually, a USN is composed of one or more
1107+[CVEs](#what-is-a-cve) and it also contains update instructions to fix the issue, if a fix is
1108+already available.
1109+
1110+USNs follow a naming convention of the format: [USN-5963-1](https://ubuntu.com/security/notices/USN-5963-1)
1111+
1112+You can search for any existing USN using
1113+[the Ubuntu Security Notices page](https://ubuntu.com/security/notices).
1114+
1115+## What are related USNs?
1116+
1117+A USN is composed of different CVEs. If the same CVE appears on multiple USNs, we say that those USNs are related.
1118+In the following image, we can see a visual representation of that concept, where USN-789 and USN-321
1119+are related USNs because both are affected by CVE-2:
1120+
1121+![Related USN example](../images/usn-related.png)
1122+
1123+
1124+A real example can be seen in [USN-5573-1](https://ubuntu.com/security/notices/USN-5573-1).
1125+In the section **Related notices**, it shows that both **USN-5570-1**
1126+and **USN-5570-2** are related to **USN-5573-1**.
1127+
1128+This information is useful for users that want to tackle
1129+all related USNs at once, making sure that a CVE is fully fixed on their Ubuntu machine.
1130diff --git a/docs/explanations/how_to_interpret_output_of_unattended_upgrades.md b/docs/explanations/how_to_interpret_output_of_unattended_upgrades.md
1131new file mode 100644
1132index 0000000..714c14a
1133--- /dev/null
1134+++ b/docs/explanations/how_to_interpret_output_of_unattended_upgrades.md
1135@@ -0,0 +1,82 @@
1136+# How to interpret the output of unattended-upgrades
1137+
1138+On Pro Client version 27.14~, we introduced the `u.pro.unattended_upgrades.status.v1` endpoint.
1139+This endpoint is designed to provide users with an overview of the configuration and setup for
1140+unattended-upgrades on the machine. The expected output follows this JSON example:
1141+
1142+```json
1143+{
1144+ "_schema_version": "v1",
1145+ "data": {
1146+ "attributes": {
1147+ "apt_periodic_job_enabled": true,
1148+ "package_lists_refresh_frequency_days": 1,
1149+ "systemd_apt_timer_enabled": true,
1150+ "unattended_upgrades_allowed_origins": [
1151+ "${distro_id}:${distro_codename}",
1152+ "${distro_id}:${distro_codename}-security",
1153+ "${distro_id}ESMApps:${distro_codename}-apps-security",
1154+ "${distro_id}ESM:${distro_codename}-infra-security"
1155+ ],
1156+ "unattended_upgrades_disabled_reason": null,
1157+ "unattended_upgrades_frequency_days": 1,
1158+ "unattended_upgrades_last_run": null,
1159+ "unattended_upgrades_running": true
1160+ },
1161+ "meta": {
1162+ "environment_vars": [],
1163+ "raw_config": {
1164+ "APT::Periodic::Enable": "1",
1165+ "APT::Periodic::Unattended-Upgrade": "1",
1166+ "APT::Periodic::Update-Package-Lists": "1",
1167+ "Unattended-Upgrade::Allowed-Origins": [
1168+ "${distro_id}:${distro_codename}",
1169+ "${distro_id}:${distro_codename}-security",
1170+ "${distro_id}ESMApps:${distro_codename}-apps-security",
1171+ "${distro_id}ESM:${distro_codename}-infra-security"
1172+ ]
1173+ }
1174+ },
1175+ "type": "UnattendedUpgradesStatus"
1176+ },
1177+ "errors": [],
1178+ "result": "success",
1179+ "version": "27.14~16.04.1",
1180+ "warnings": []
1181+}
1182+```
1183+
1184+As we can see from this output, we have a variable named `unattended_upgrades_running`. That variable
1185+indicates if unattended-upgrades is properly configured and running on the machine.
1186+The value of this field will only be `true` if *ALL* of the following prerequisites are also true:
1187+
1188+* *`apt_periodic_job_enable` is true*: That variable indicates if the APT::Periodic::Enable configuration variable
1189+ is turned on. If it is turned off, unattended-upgrades will not automatically run on the machine.
1190+* *`package_lists_refresh_frequency_days` is non-zero*: That variable shows the value of APT::Periodic::Package-List-Frequency.
1191+ This configuration defines the daily frequency for updating package sources in the background. If it has a zero value, this step will never
1192+ happen and unattended-upgrades might not be able to install new versions of the packages.
1193+* *`systemd_apt_timer_enabled` is true*: This variable is true if both `apt-daily.timer` and `apt-daily-upgrade.timer` are running
1194+ on the machine. These timers are the ones that control when unattended-upgrades run. The first job, `apt-daily.timer` is responsible
1195+ for triggering the code that downloads the lastest package information on the system. The second job, `apt-daily-upgrade.timer` is
1196+ responsible for running unattended-upgrades to download the latest version of the packages. If one of these jobs is disabled,
1197+ unattended-upgrades might not work as expected.
1198+* *`unattended_upgrades_allowed_origins` is not empty*: This variable defines the origins that
1199+ unattended-upgrades can use to install a package. If that list is empty, no packages can be
1200+ installed and unattended-upgrades will not work as expected.
1201+* *`unattended_upgrades_frequency_days` is non-zero*: That variable shows the value of
1202+ APT::Periodic::Unattended-Upgrade. This configuration defines the daily frequency for running
1203+ unattended-upgrades in the background. Therefore, if it has a zero value, the command will never
1204+ run.
1205+
1206+
1207+If any of those conditions are not met, the variable
1208+*unattended_upgrades_disabled_reason* will contain an object explaining why unattended-upgrades is
1209+not running. For example, if `package_lists_refresh_frequency_days` has a zero value, we will see
1210+the following value for *unattended_upgrades_disabled_reason*:
1211+
1212+```json
1213+{
1214+ "msg": "APT::Periodic::Update-Package-Lists is turned off",
1215+ "code": "unattended-upgrades-cfg-value-turned-off"
1216+}
1217+```
1218diff --git a/docs/explanations/motd_messages.md b/docs/explanations/motd_messages.md
1219index 337a4bd..6a8f22b 100644
1220--- a/docs/explanations/motd_messages.md
1221+++ b/docs/explanations/motd_messages.md
1222@@ -2,21 +2,51 @@
1223
1224 When the Ubuntu Pro Client (`pro`) is installed on the system, it delivers
1225 custom messages on ["Message of the Day" (MOTD)](https://wiki.debian.org/motd).
1226-Those messages are generated directly by two different sources.
1227+Those messages are generated directly by three different sources.
1228
1229-## Python-scripted MOTD
1230+* MOTD about available updates
1231+* MOTD about important subscription conditions
1232+* MOTD about ESM being available
1233+
1234+## MOTD about available updates
1235
1236 The [update-notifier](https://wiki.ubuntu.com/UpdateNotifier) delivers a script
1237-called `apt_check.py`. With regards to Ubuntu Pro, this script is responsible
1238-for:
1239-
1240+via the `update-notifier-common` package called
1241+`/usr/lib/update-notifier/apt_check.py.
1242+With regards to Ubuntu Pro, this script is responsible for:
1243+
1244 * Informing the user about the status of one of the ESM services; `esm-apps` if
1245 the machine is an LTS series, or `esm-infra` if the series is in ESM mode.
1246 * Showing the number of `esm-infra` or `esm-apps` packages that can be upgraded
1247 on the machine.
1248
1249-For example, here is the output of the `apt_check.py` script on a LTS machine
1250-when both of those services are enabled:
1251+`update-notifier` has always added information about potential updates to
1252+MOTD to raise user awareness. With the advent of Ubuntu Pro they are
1253+just more differentiated.
1254+
1255+Note that if you run `apt_check.py` directly it might give you rather
1256+unreadable output as it is meant for program use. You can add `--human-readable`
1257+to see the information as it would be presented in MOTD.
1258+
1259+### Machine is unattached
1260+
1261+On a machine that runs an Ubuntu release for which the `esm-apps` service
1262+is available, but not yet attached to an Ubuntu Pro subscription, there will
1263+be a message notifying the user that there may be more security updates
1264+available through ESM Apps.
1265+
1266+```
1267+Expanded Security Maintenance for Applications is not enabled.
1268+
1269+0 updates can be applied immediately.
1270+
1271+Enable ESM Apps to receive additional future security updates.
1272+See https://ubuntu.com/esm or run: sudo pro status
1273+```
1274+
1275+### Machine is fully attached
1276+
1277+In the opposite situation, if an LTS machine has the `esm-infra` and `esm-apps` services enabled then users will see the following output in MOTD:
1278
1279 ```
1280 Expanded Security Maintenance for Applications is enabled.
1281@@ -28,8 +58,16 @@ Expanded Security Maintenance for Applications is enabled.
1282 To see these additional updates run: apt list --upgradable
1283 ```
1284
1285-However, if we were running this on an ESM series, we would instead see
1286-`esm-infra` being advertised:
1287+### Machine is fully attached, on an older release
1288+
1289+Above you have seen examples of recent (as in "still in their first 5
1290+years of support") Ubuntu releases, where the hint is about ESM Apps
1291+extending the coverage to the universe repositories.
1292+
1293+However, if running on an Ubuntu release that has is already past the initial
1294+5 years of support and has thereby entered Expanded Security Maintenance
1295+(["ESM"](https://ubuntu.com/security/esm)), we would instead see
1296+`esm-infra` (which provides coverage for another 5 years) being shown:
1297
1298 ```
1299 Expanded Security Maintenance Infrastructure is enabled.
1300@@ -41,17 +79,19 @@ Expanded Security Maintenance Infrastructure is enabled.
1301 To see these additional updates run: apt list --upgradable
1302 ```
1303
1304+### Partial service enablement
1305+
1306 Now let's consider a scenario where one of these services is not enabled. For
1307 example, if `esm-apps` was disabled, the output will be:
1308
1309 ```
1310 Expanded Security Maintenance for Applications is not enabled.
1311-
1312+
1313 6 updates can be applied immediately.
1314 1 of these updates is a ESM Infra security update.
1315 5 of these updates are standard security updates.
1316 To see these additional updates run: apt list --upgradable
1317-
1318+
1319 5 additional security updates can be applied with ESM Apps
1320 Learn more about enabling ESM Apps for Ubuntu 16.04 at
1321 https://ubuntu.com/16-04
1322@@ -62,13 +102,13 @@ upgraded if that service was enabled. Note that we would deliver the same
1323 information for `esm-infra` if the service was disabled and the series running
1324 on the machine is in ESM state.
1325
1326-## MOTD through Ubuntu Pro timer jobs
1327+## MOTD about important subscription conditions
1328
1329-One of the timer jobs Ubuntu Pro uses can insert additional messages into MOTD.
1330-These messages will be always delivered before or after the content created by
1331-the Python script delivered by `update-notifier`. These additional messages are
1332-generated when `pro` detects that certain conditions on the machine have been
1333-met. They are:
1334+One of the [timer jobs](https://canonical-ubuntu-pro-client.readthedocs-hosted.com/en/latest/explanations/what_are_the_timer_jobs.html)
1335+Ubuntu Pro uses can insert additional messages into MOTD.
1336+These messages will be always delivered next to the content created by
1337+`update-notifier`. These additional messages are generated when `pro`
1338+detects that certain conditions on the machine have been met. They are:
1339
1340 ### Subscription expired
1341
1342@@ -104,8 +144,69 @@ coverage for your applications.
1343 Your grace period will expire in 9 days.
1344 ```
1345
1346-### How are these messages updated and inserted into MOTD?
1347+## MOTD about ESM being available
1348+
1349+When Ubuntu Pro became generally available, a temporary announcement was made
1350+through MOTD. This was intended to raise awareness of Pro now being available
1351+and free for personal use, and was shown on systems that could be covered
1352+by `esm-apps`.
1353+It looked like:
1354+
1355+```
1356+ * Introducing Expanded Security Maintenance for Applications.
1357+ Receive updates to over 25,000 software packages with your
1358+ Ubuntu Pro subscription. Free for personal use.
1359+
1360+ https://ubuntu.com/pro
1361+```
1362+
1363+Since this message was intended as a limited-time announcement to coincide
1364+with the release of Ubuntu Pro into general availability, it was removed in
1365+27.14.
1366+
1367+## How are these messages inserted into MOTD and how can I disable them?
1368+
1369+Just as there are different purposes to the messages outlined above,
1370+there are different sources producing these MOTD elements that one
1371+sees at login.
1372+
1373+Those messages are considered important to ensure user awareness about
1374+the free additional security coverage provided by Ubuntu Pro and about
1375+not-yet-applied potential updates in general. Therefore it is generally not
1376+recommended to disable them. But still, you can selectively disable them
1377+by removing the config files that add them, as outlined below.
1378+
1379+Removing those files is considered a conffile change to customize a program
1380+and they will stay removed even on future upgrades or re-installations of the
1381+related packages.
1382+
1383+If you realize that you actually need them back you need
1384+to reinstall the related packages and tell apt/dpkg to offer you to restore
1385+those files via:
1386+
1387+```
1388+sudo apt install --reinstall -o Dpkg::Options::="--force-confask" ubuntu-advantage-tools update-notifier-common
1389+```
1390+
1391+## Source: MOTD about available updates
1392+
1393+1. `update-notifier-common` has a hook `/etc/apt/apt.conf.d/99update-notifier` that runs after `apt update`.
1394+2. That hook will update the information in `/var/lib/update-notifier/updates-available` matching the new package information that was just fetched by using `/usr/lib/update-notifier/apt-check --human-readable`.
1395+3. At MOTD generation time, the script located at `/etc/update-motd.d/90-updates-available` checks if `/var/lib/update-notifier/updates-available` exists and if it does, inserts the message into the full MOTD.
1396+
1397+If you want to disable any message of update-notifier (not just related to Ubuntu Pro and ESM) about potentially available updates remove `/etc/update-motd.d/90-updates-available`.
1398
1399-1. The contract status is checked periodically in the background when the machine is attached to an Ubuntu Pro contract.
1400-2. If one of the above messages applies to the contract that the machine is attached to, then the message is stored in `/var/lib/ubuntu-advantage/messages/motd-contract-status`.
1401+## Source: MOTD about important subscription conditions
1402+
1403+1. The subscription status is checked periodically in the background when the machine is attached to an Ubuntu Pro subscription.
1404+2. If one of the above conditions applies to the subscription that the machine is attached to (there are no messages generated by this for unattached machines), then the message is stored in `/var/lib/ubuntu-advantage/messages/motd-contract-status`.
1405 3. At MOTD generation time, the script located at `/etc/update-motd.d/91-contract-ua-esm-status` checks if `/var/lib/ubuntu-advantage/messages/motd-contract-status` exists and if it does, inserts the message into the full MOTD.
1406+
1407+If you want to disable any message about important conditions of your attached subscription remove `/etc/update-motd.d/91-contract-ua-esm-status`.
1408+
1409+## Source: MOTD about ESM being available
1410+
1411+1. `pro` checks regularly if a system would have `esm-apps` available to it and if so places a message in `/var/lib/ubuntu-advantage/messages/motd-esm-announce`.
1412+2. At MOTD generation time, the script located at `/etc/update-motd.d/88-esm-announce` checks if `/var/lib/ubuntu-advantage/messages/motd-esm-announce` exists and if it does, inserts the message into the full MOTD.
1413+
1414+If you want to disable the ESM announcement remove `/etc/update-motd.d/88-esm-announce` (or upgrade to 27.14 or later which will remove it for you).
1415diff --git a/docs/explanations/status_columns.md b/docs/explanations/status_columns.md
1416index 1447b44..6e79449 100644
1417--- a/docs/explanations/status_columns.md
1418+++ b/docs/explanations/status_columns.md
1419@@ -101,3 +101,105 @@ allow_beta: True
1420 It's important to keep in mind that any feature defined like this will be
1421 listed, even if it is invalid or typed the wrong way. Those appear in `status`
1422 output for informational and debugging purposes.
1423+
1424+## Machine-readable output
1425+
1426+The `pro status` command supports a `--format` flag with options including `json` and `yaml`. These result in a machine-readable form of the information presented by the `pro status` command.
1427+
1428+```{note}
1429+`pro status` should return the same results whether using `sudo` or not, but earlier versions did not always do this. We recommend using `sudo` whenever possible.
1430+```
1431+
1432+For example, running `sudo pro status --format=json` on an attached machine may give you something like this:
1433+```javascript
1434+{
1435+ "_doc": "Content provided in json response is currently considered Experimental and may change",
1436+ "_schema_version": "0.1",
1437+ "account": {
1438+ "created_at": "2000-01-02T03:04:05+06:00",
1439+ "id": "account_id",
1440+ "name": "Test"
1441+ },
1442+ "attached": true,
1443+ "config": { ...effectiveConfiguration },
1444+ "config_path": "/etc/ubuntu-advantage/uaclient.conf",
1445+ "contract": {
1446+ "created_at": "2000-01-02T03:04:05+06:00",
1447+ "id": "contract_id",
1448+ "name": "contract_name",
1449+ "products": [ "uaa-essential" ],
1450+ "tech_support_level": "essential"
1451+ },
1452+ "effective": null,
1453+ "environment_vars": [...proClientEnvironmentVariables],
1454+ "errors": [],
1455+ "execution_details": "No Ubuntu Pro operations are running",
1456+ "execution_status": "inactive",
1457+ "expires": "9999-12-31T00:00:00+00:00",
1458+ "features": {},
1459+ "machine_id": "machine_id",
1460+ "notices": [],
1461+ "result": "success",
1462+ "services": [
1463+ {
1464+ "available": "yes",
1465+ "blocked_by": [],
1466+ "description": "Expanded Security Maintenance for Applications",
1467+ "description_override": null,
1468+ "entitled": "yes",
1469+ "name": "esm-apps",
1470+ "status": "enabled",
1471+ "status_details": "Ubuntu Pro: ESM Apps is active",
1472+ "warning": null
1473+ },
1474+ {
1475+ "available": "yes",
1476+ "blocked_by": [],
1477+ "description": "Expanded Security Maintenance for Infrastructure",
1478+ "description_override": null,
1479+ "entitled": "yes",
1480+ "name": "esm-infra",
1481+ "status": "enabled",
1482+ "status_details": "Ubuntu Pro: ESM Infra is active",
1483+ "warning": null
1484+ },
1485+ {
1486+ "available": "yes",
1487+ "blocked_by": [],
1488+ "description": "Canonical Livepatch service",
1489+ "description_override": null,
1490+ "entitled": "yes",
1491+ "name": "livepatch",
1492+ "status": "enabled",
1493+ "status_details": "",
1494+ "warning": null
1495+ },
1496+ ...otherServiceStatusObjects
1497+ ],
1498+ "simulated": false,
1499+ "version": "27.13.6~18.04.1",
1500+ "warnings": []
1501+}
1502+```
1503+
1504+Some particularly important attributes in the output include:
1505+* `attached`: This boolean value indicates whether this machine is attached to an Ubuntu Pro account. This does not tell you if any particular service (e.g. `esm-infra`) is enabled. You must check the individual service item in the `services` list for that status (described below).
1506+* `expires`: This is the date that the Ubuntu Pro subscription is valid until (in RFC3339 format). After this date has passed the machine should be treated as if not attached and no services are enabled. `attached` may still say `true` and services may still say they are `entitled` and `enabled`, but if the `expires` date has passed, you should assume the services are not functioning.
1507+* `services`: This is a list of Ubuntu Pro services. Each item has its own attributes. Widely applicable services include those with `name` equal to `esm-infra`, `esm-apps`, and `livepatch`. Some important fields in each service object are:
1508+ * `name`: The name of the service.
1509+ * `entitled`: A boolean indicating whether the attached Ubuntu Pro account is allowed to enable this service.
1510+ * `status`: A string indicating the service's current status on the machine. Any value other than `enabled` should be treated as if the service is not enabled and not working properly on the machine. Possible values are:
1511+ * `enabled`: The service is enabled and working.
1512+ * `disabled`: The service can be enabled but is not currently.
1513+ * `n/a`: The service cannot be enabled on this machine.
1514+ * `warning`: The service is supposed to be enabled but something is wrong. Check the `warning` field in the service item for additional information.
1515+
1516+For example, if you want to programatically find the status of esm-infra on a particular machine, you can use the following command:
1517+```shell
1518+sudo pro status --format=json | jq '.services[] | select(.name == "esm-infra").status'
1519+```
1520+That command will print one of the `status` values defined above.
1521+
1522+```{attention}
1523+In an future version of Ubuntu Pro Client, there will be an [API](../references/api.md) function to access this information. For now, though, `pro status --format=json` is the recommended machine-readable interface to this data.
1524+```
1525diff --git a/docs/googleaf254801a5285c31.html b/docs/googleaf254801a5285c31.html
1526new file mode 100644
1527index 0000000..b603071
1528--- /dev/null
1529+++ b/docs/googleaf254801a5285c31.html
1530@@ -0,0 +1 @@
1531+google-site-verification: googleaf254801a5285c31.html
1532\ No newline at end of file
1533diff --git a/docs/howtoguides.rst b/docs/howtoguides.rst
1534index 7127394..5b93de6 100644
1535--- a/docs/howtoguides.rst
1536+++ b/docs/howtoguides.rst
1537@@ -59,6 +59,7 @@ How to use ``pro`` commands
1538 :maxdepth: 1
1539
1540 Run `fix` in "dry run" mode <howtoguides/how_to_run_fix_in_dry_run_mode.md>
1541+ Skip fixing related USNs <howtoguides/how_to_not_fix_related_usns.md>
1542
1543 ``refresh``
1544 -----------
1545diff --git a/docs/howtoguides/enable_fips.md b/docs/howtoguides/enable_fips.md
1546index 8f614fb..4fe8b8a 100644
1547--- a/docs/howtoguides/enable_fips.md
1548+++ b/docs/howtoguides/enable_fips.md
1549@@ -36,5 +36,5 @@ been installed:
1550 ```
1551 Installing FIPS packages
1552 FIPS enabled
1553-A reboot is required to complete installl
1554+A reboot is required to complete install.
1555 ```
1556diff --git a/docs/howtoguides/get_rid_of_corrupt_lock.md b/docs/howtoguides/get_rid_of_corrupt_lock.md
1557index 03da4a3..17e8e37 100644
1558--- a/docs/howtoguides/get_rid_of_corrupt_lock.md
1559+++ b/docs/howtoguides/get_rid_of_corrupt_lock.md
1560@@ -2,7 +2,7 @@
1561
1562 Some pro commands (`attach`, `enable`, `detach` and `disable`) will potentially change the
1563 internal state of your system. Since those commands can run in parallel, we have a lock file
1564-mechanism to guarantee that only one of these commands can run at the same time. The lock follow
1565+mechanism to guarantee that only one of these commands can run at the same time. The lock follows
1566 this pattern:
1567
1568 ```
1569diff --git a/docs/howtoguides/get_token_and_attach.md b/docs/howtoguides/get_token_and_attach.md
1570index 41726ef..ff15c15 100644
1571--- a/docs/howtoguides/get_token_and_attach.md
1572+++ b/docs/howtoguides/get_token_and_attach.md
1573@@ -1,10 +1,21 @@
1574 # How to get an Ubuntu Pro token and attach to a subscription
1575
1576+## Get an Ubuntu Pro token
1577+
1578 Retrieve your Ubuntu Pro token from the
1579-[Ubuntu Pro portal](https://ubuntu.com/pro/). You will log in with your "Single
1580+[Ubuntu Pro portal](https://ubuntu.com/pro/). Log in with your "Single
1581 Sign On" credentials, the same credentials you use for https://login.ubuntu.com.
1582-Note that you can obtain a free personal token, which provides you with access
1583-to several of the Ubuntu Pro services.
1584+
1585+Being logged in you can then go to the
1586+[Ubuntu Pro Dashboard](https://ubuntu.com/pro/dashboard) that is associated to
1587+your user. It will show you all subscriptions currently available to you and
1588+for each the associated token.
1589+
1590+Note that even without buying anything you can always obtain a free personal
1591+token that way, which provides you with access to several of the Ubuntu Pro
1592+services.
1593+
1594+## Attach to a subscription
1595
1596 Once that token is obtained, to attach your machine to a subscription, just run:
1597
1598@@ -35,3 +46,26 @@ Enable services with: pro enable <service>
1599 Once the Ubuntu Pro Client is attached to your Ubuntu Pro account, you can use
1600 it to activate various services, including: access to ESM packages, Livepatch,
1601 FIPS, and CIS. Some features are specific to certain LTS releases.
1602+
1603+## Control of auto-enabled services
1604+
1605+Your subscription controls which services are available to you and which ones
1606+you can manage via the [Ubuntu Pro Dashboard](https://ubuntu.com/pro/dashboard).
1607+
1608+Recommended services are auto-enabled by default when attaching a system.
1609+You can choose which of the available services will be automatically
1610+enabled or disabled when you attach by toggling them in the
1611+[Ubuntu Pro Dashboard](https://ubuntu.com/pro/dashboard).
1612+Available services can always be enabled or disabled on the command line
1613+with `pro enable` and `pro disable` after attaching.
1614+
1615+![Toggling recommended services in the Pro Dashboard](pro-dashboard-service-toggles.png)
1616+
1617+If your subscription does not permit you to change the default
1618+enabled services via the Dashboard, or if you want to keep the
1619+defaults but do not want to auto-enable any services while attaching a particular
1620+machine, you can pass the `--no-auto-enable` flag to `attach` using the following command:
1621+
1622+```
1623+$ sudo pro attach YOUR_TOKEN --no-auto-enable
1624+```
1625diff --git a/docs/howtoguides/how_to_not_fix_related_usns.md b/docs/howtoguides/how_to_not_fix_related_usns.md
1626new file mode 100644
1627index 0000000..c9fabf0
1628--- /dev/null
1629+++ b/docs/howtoguides/how_to_not_fix_related_usns.md
1630@@ -0,0 +1,65 @@
1631+# How to not fix related USNs
1632+
1633+When running the `pro fix` command for a USN, by default we also try to fix
1634+any related USNs as well. To better understand the concept of related USNs,
1635+you can refer to our [related USNs guide](../explanations/cves_and_usns_explained.md).
1636+To make this clear, let's take a look into the following example:
1637+
1638+```
1639+USN-5573-1: rsync vulnerability
1640+Found CVEs:
1641+ - https://ubuntu.com/security/CVE-2022-37434
1642+
1643+Fixing requested USN-5573-1
1644+1 affected source package is installed: rsync
1645+(1/1) rsync:
1646+A fix is available in Ubuntu standard updates.
1647+{ apt update && apt install --only-upgrade -y rsync }
1648+
1649+✔ USN-5573-1 is resolved.
1650+
1651+Found related USNs:
1652+- USN-5570-1
1653+- USN-5570-2
1654+
1655+Fixing related USNs:
1656+- USN-5570-1
1657+No affected source packages are installed.
1658+
1659+✔ USN-5570-1 does not affect your system.
1660+
1661+- USN-5570-2
1662+1 affected source package is installed: zlib
1663+(1/1) zlib:
1664+A fix is available in Ubuntu standard updates.
1665+{ apt update && apt install --only-upgrade -y zlib1g }
1666+
1667+✔ USN-5570-2 is resolved.
1668+
1669+Summary:
1670+✔ USN-5573-1 [requested] is resolved.
1671+✔ USN-5570-1 [related] does not affect your system.
1672+✔ USN-5570-2 [related] is resolved.
1673+```
1674+
1675+We can see here that the `pro fix` command fixed the requested **USN-5573-1** while also
1676+handling both **USN-5570-1** and **USN-5570-2**, which are related to the requested USN.
1677+If you don't want to fix any related USNs during the `fix` operation, just use the
1678+`--no-related` flag. By running the command `pro fix USN-5573-1 --no-related` we would get
1679+the following output instead:
1680+
1681+```
1682+USN-5573-1: rsync vulnerability
1683+Found CVEs:
1684+ - https://ubuntu.com/security/CVE-2022-37434
1685+
1686+Fixing requested USN-5573-1
1687+1 affected source package is installed: rsync
1688+(1/1) rsync:
1689+A fix is available in Ubuntu standard updates.
1690+{ apt update && apt install --only-upgrade -y rsync }
1691+
1692+✔ USN-5573-1 is resolved.
1693+```
1694+
1695+Note that we have not analysed or tried to fix any related USNs
1696diff --git a/docs/howtoguides/pro-dashboard-service-toggles.png b/docs/howtoguides/pro-dashboard-service-toggles.png
1697new file mode 100644
1698index 0000000..90095f5
1699Binary files /dev/null and b/docs/howtoguides/pro-dashboard-service-toggles.png differ
1700diff --git a/docs/images/usn-related.png b/docs/images/usn-related.png
1701new file mode 100644
1702index 0000000..9db73c0
1703Binary files /dev/null and b/docs/images/usn-related.png differ
1704diff --git a/docs/index.rst b/docs/index.rst
1705index b63cce0..d07dd4d 100644
1706--- a/docs/index.rst
1707+++ b/docs/index.rst
1708@@ -63,9 +63,10 @@ using it!
1709
1710 - **Having trouble?**
1711 We would like to help! To get help on a specific page in this documentation,
1712- simply click on the "Have a question?" link at the top of that page. This
1713+ simply click on the "Give feedback" link at the top of that page. This
1714 will open up an issue in GitHub where you can tell us more about the problem
1715- you're having and we will do our best to resolve it for you.
1716+ you're having or suggestion you'd like to make, and we will do our best to
1717+ resolve it for you.
1718
1719 - **Found a bug?**
1720 You can `Report bugs on Launchpad`_!
1721diff --git a/docs/references/api.md b/docs/references/api.md
1722index 4708d9b..9c40f60 100644
1723--- a/docs/references/api.md
1724+++ b/docs/references/api.md
1725@@ -75,6 +75,28 @@ except ImportError:
1726
1727 You could do something similar by catching certain errors when using the `pro api` subcommand, but there are more cases that could indicate an old version, and it generally isn't recommended.
1728
1729+
1730+### Errors and Warnings fields
1731+
1732+When using the API through the CLI, we use two distinct fields to list issues to the users; *errors*
1733+and *warnings*. Both of those fields will contain a list of JSON objects explaining unexpected
1734+behavior during the execution of a command. For example, the *errors* field will be populated like
1735+this if we have a connectivity issue when running a `pro api` command:
1736+
1737+```json
1738+[
1739+ {
1740+ "msg": "Failed to connect to authentication server",
1741+ "code": "connectivity-error",
1742+ "meta": {}
1743+ }
1744+]
1745+```
1746+
1747+Finally, *warnings* follow the exact same structure as *errors*. The only difference is that
1748+*warnings* means that the command was able to complete although unexpected scenarios happened
1749+when executing the command.
1750+
1751 ## Available endpoints
1752 The currently available endpoints are:
1753 - [u.pro.version.v1](#uproversionv1)
1754@@ -89,6 +111,7 @@ The currently available endpoints are:
1755 - [u.pro.packages.summary.v1](#upropackagessummaryv1)
1756 - [u.pro.packages.updates.v1](#upropackagesupdatesv1)
1757 - [u.security.package_manifest.v1](#usecuritypackage_manifestv1)
1758+- [u.unattended_upgrades.status.v1](#uunattended_upgradesstatusv1)
1759
1760 ## u.pro.version.v1
1761
1762@@ -801,3 +824,105 @@ pro api u.security.package_manifest.v1
1763 "package_manifest":"package1\t1.0\npackage2\t2.3\n"
1764 }
1765 ```
1766+
1767+## u.unattended_upgrades.status.v1
1768+
1769+Introduced in Ubuntu Pro Client Version: `27.14~`
1770+
1771+Returns the status around unattended-upgrades. The focus of the endpoint
1772+is to verify if the application is running and how it is configured on
1773+the machine.
1774+
1775+```{important}
1776+For this endpoint, we deliver a unique key under `meta` called `raw_config`. This field contains
1777+all related unattended-upgrades configurations unparsed. This means that this field will maintain
1778+both original name and values for those configurations.
1779+```
1780+
1781+### Args
1782+
1783+This endpoint takes no arguments.
1784+
1785+### Python API interaction
1786+
1787+#### Calling from Python code
1788+
1789+```python
1790+from uaclient.api.u.unattended_upgrades.status.v1 import status
1791+
1792+result = status()
1793+```
1794+
1795+#### Expected return object:
1796+`uaclient.api.u.unattended_upgrades.status.v1.UnattendedUpgradesStatusResult
1797+
1798+|Field Name|Type|Description|
1799+|-|-|-|
1800+|`systemd_apt_timer_enabled`|*bool*|Indicate if the apt-daily.timer jobs are enabled|
1801+|`apt_periodic_job_enabled`|*bool*|Indicate if the APT::Periodic::Enabled configuration is turned off|
1802+|`package_lists_refresh_frequency_days`|*int*|The value of the APT::Periodic::Update-Package-Lists configuration|
1803+|`unattended_upgrades_frequency_days`|*int*|The value of the APT::Periodic::Unattended-Upgrade configuration|
1804+|`unattended_upgrades_allowed_origins`|*List[str]*|The value of the Unattended-Upgrade::Allowed-Origins configuration|
1805+|`unattended_upgrades_running`|*bool*|Indicate if the unattended-upgrade service is correctly configured and running|
1806+|`unattended_upgrades_disabled_reason`|*object*|Object that explains why unattended-upgrades is not running. In case the application is running, the object will be null|
1807+|`unatteded_upgrades_last_run`|`datetime.datetime`|The last time unattended-upgrades has run|
1808+
1809+`uaclient.api.u.unattended_upgrades.status.v1.UnattendedUpgradesStatusDisabledReason`
1810+
1811+|Field Name|Type|Description|
1812+|-|-|-|
1813+|`msg`|*str*|The reason why unattended-upgrades is not running in the system|
1814+|`code`|*str*|The message code associated with the message|
1815+
1816+### Raised exceptions
1817+
1818+- `UnattendedUpgradesError`: Raised in case we cannot run a necessary command to show the status
1819+ of unattended-upgrades
1820+
1821+### CLI interaction
1822+
1823+#### Calling from the CLI:
1824+
1825+```bash
1826+pro api u.unattended_upgrades.status.v1
1827+```
1828+
1829+#### Expected attributes in JSON structure
1830+
1831+```json
1832+{
1833+ "apt_periodic_job_enabled": true,
1834+ "package_lists_refresh_frequency_days": 1,
1835+ "systemd_apt_timer_enabled": true,
1836+ "unattended_upgrades_allowed_origins": [
1837+ "${distro_id}:${distro_codename}",
1838+ "${distro_id}:${distro_codename}-security",
1839+ "${distro_id}ESMApps:${distro_codename}-apps-security",
1840+ "${distro_id}ESM:${distro_codename}-infra-security"
1841+ ],
1842+ "unattended_upgrades_disabled_reason": null,
1843+ "unattended_upgrades_frequency_days": 1,
1844+ "unattended_upgrades_last_run": null,
1845+ "unattended_upgrades_running": true
1846+}
1847+```
1848+
1849+#### Possible attributes in JSON meta field
1850+```json
1851+{
1852+ "meta": {
1853+ "environment_vars": [],
1854+ "raw_config": {
1855+ "APT::Periodic::Enable": "1",
1856+ "APT::Periodic::Unattended-Upgrade": "1",
1857+ "APT::Periodic::Update-Package-Lists": "1",
1858+ "Unattended-Upgrade::Allowed-Origins": [
1859+ "${distro_id}:${distro_codename}",
1860+ "${distro_id}:${distro_codename}-security",
1861+ "${distro_id}ESMApps:${distro_codename}-apps-security",
1862+ "${distro_id}ESM:${distro_codename}-infra-security"
1863+ ]
1864+ }
1865+ }
1866+}
1867+```
1868diff --git a/docs/references/network_requirements.md b/docs/references/network_requirements.md
1869index cb25256..ffbeffd 100644
1870--- a/docs/references/network_requirements.md
1871+++ b/docs/references/network_requirements.md
1872@@ -10,7 +10,7 @@ access to:
1873
1874 ```{seealso}
1875
1876-You can also refer to our [Proxy Configuration guide](/../howtoguides/configure_proxies.md)
1877+You can also refer to our [Proxy Configuration guide](../howtoguides/configure_proxies.md)
1878 to learn how to inform Ubuntu Pro Client of HTTP(S)/APT proxies.
1879 ```
1880
1881diff --git a/docs/sitemap-index.xml b/docs/sitemap-index.xml
1882new file mode 100644
1883index 0000000..efce50f
1884--- /dev/null
1885+++ b/docs/sitemap-index.xml
1886@@ -0,0 +1,8 @@
1887+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
1888+ <url>
1889+ <loc>https://canonical-ubuntu-pro-client.readthedocs-hosted.com/en/latest/</loc>
1890+ <changefreq>weekly</changefreq>
1891+ <priority>1.0</priority>
1892+ </url>
1893+</urlset>
1894+
1895diff --git a/docs/tutorials/create_a_fips_updates_pro_cloud_image.md b/docs/tutorials/create_a_fips_updates_pro_cloud_image.md
1896index e4427bc..10b87b3 100644
1897--- a/docs/tutorials/create_a_fips_updates_pro_cloud_image.md
1898+++ b/docs/tutorials/create_a_fips_updates_pro_cloud_image.md
1899@@ -1,8 +1,8 @@
1900-# Customised Cloud Ubuntu Pro images with FIPS updates
1901+# How to customise a cloud Ubuntu Pro image with FIPS updates
1902
1903 ## Launch an Ubuntu Pro instance on your cloud
1904
1905-See the following links for up to date information for each supported Cloud:
1906+See the following links for up to date information for each supported cloud:
1907
1908 * https://ubuntu.com/aws/pro
1909 * https://ubuntu.com/azure/pro
1910@@ -10,20 +10,20 @@ See the following links for up to date information for each supported Cloud:
1911
1912 ## Enable FIPS updates
1913
1914-First, we need to wait for the standard Ubuntu Pro services to be set up:
1915+Wait for the standard Ubuntu Pro services to be set up:
1916
1917 ```bash
1918 sudo pro status --wait
1919 ```
1920
1921-We can then use [the `enable` command](../howtoguides/enable_fips.md) to set up
1922+Use [the `enable` command](../howtoguides/enable_fips.md) to set up
1923 FIPS updates.
1924
1925 ```bash
1926 sudo pro enable fips-updates --assume-yes
1927 ```
1928
1929-Now, we need to reboot the instance:
1930+Now, reboot the instance:
1931
1932 ```bash
1933 sudo reboot
1934@@ -49,12 +49,12 @@ Cloud-specific instructions are here:
1935 * [Azure](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/capture-image-resource)
1936 * [GCP](https://cloud.google.com/compute/docs/machine-images/create-machine-images)
1937
1938-## Launch your custom image!
1939+## Launch your custom image
1940
1941-Use your specific Cloud to launch a new instance from your custom image.
1942+Use your specific cloud to launch a new instance from the custom image.
1943
1944 ````{note}
1945-For versions prior to 27.11, you will need to re-enable `fips-updates` on each
1946+For versions of the Ubuntu Pro Client prior to 27.11, you will need to re-enable `fips-updates` on each
1947 instance launched from the custom image.
1948
1949 This won't require a reboot and is only necessary to ensure the instance gets
1950@@ -64,7 +64,7 @@ updates to FIPS packages when they become available.
1951 sudo pro enable fips-updates --assume-yes
1952 ```
1953
1954-You can easily script this using [cloud-init user data](https://cloudinit.readthedocs.io/en/latest/topics/modules.html#runcmd) at launch time:
1955+This can be scripted using [cloud-init user data](https://cloudinit.readthedocs.io/en/latest/topics/modules.html#runcmd) at launch time:
1956 ```yaml
1957 #cloud-config
1958 # Enable fips-updates after pro auto-attach and reboot after cloud-init completes
1959diff --git a/docs/tutorials/fix_scenarios.md b/docs/tutorials/fix_scenarios.md
1960index fe6f8e2..1c96800 100644
1961--- a/docs/tutorials/fix_scenarios.md
1962+++ b/docs/tutorials/fix_scenarios.md
1963@@ -81,7 +81,9 @@ You should see an output like this:
1964 ```
1965 CVE-2020-15180: MariaDB vulnerabilities
1966 https://ubuntu.com/security/CVE-2020-15180
1967+
1968 No affected source packages are installed.
1969+
1970 ✔ CVE-2020-15180 does not affect your system.
1971 ```
1972
1973@@ -110,10 +112,12 @@ You will then see the following output:
1974 ```
1975 CVE-2020-25686: Dnsmasq vulnerabilities
1976 https://ubuntu.com/security/CVE-2020-25686
1977+
1978 1 affected package is installed: dnsmasq
1979 (1/1) dnsmasq:
1980 A fix is available in Ubuntu standard updates.
1981 { apt update && apt install --only-upgrade -y dnsmasq }
1982+
1983 ✔ CVE-2020-25686 is resolved.
1984 ```
1985
1986@@ -137,10 +141,12 @@ run the `pro fix` command again, and we should now see the following:
1987 ```
1988 CVE-2020-25686: Dnsmasq vulnerabilities
1989 https://ubuntu.com/security/CVE-2020-25686
1990+
1991 1 affected package is installed: dnsmasq
1992 (1/1) dnsmasq:
1993 A fix is available in Ubuntu standard updates.
1994 The update is already installed.
1995+
1996 ✔ CVE-2020-25686 is resolved.
1997 ```
1998
1999@@ -151,30 +157,34 @@ let you know! Before we reproduce this scenario, let us first install a package
2000 that we know has no fix available by running:
2001
2002 ```console
2003-$ sudo apt install -y libawl-php
2004+$ sudo apt-get install -y expat=2.1.0-7 swish-e matanza ghostscript
2005 ```
2006
2007 Now, we can confirm that there is no fix by running the following command:
2008
2009 ```console
2010-$ pro fix USN-4539-1
2011+$ pro fix CVE-2017-9233
2012 ```
2013
2014 You will see the following output:
2015
2016 ```
2017-USN-4539-1: AWL vulnerability
2018-Found CVEs:
2019-https://ubuntu.com/security/CVE-2020-11728
2020-1 affected source package is installed: awl
2021-(1/1) awl:
2022-Sorry, no fix is available.
2023-1 package is still affected: awl
2024-✘ USN-4539-1 is not resolved.
2025+CVE-2017-9233: Coin3D vulnerability
2026+ - https://ubuntu.com/security/CVE-2017-9233
2027+
2028+3 affected source packages are installed: expat, matanza, swish-e
2029+(1/3, 2/3) matanza, swish-e:
2030+Ubuntu security engineers are investigating this issue.
2031+(3/3) expat:
2032+A fix is available in Ubuntu standard updates.
2033+{ apt update && apt install --only-upgrade -y expat }
2034+
2035+2 packages are still affected: matanza, swish-e
2036+✘ CVE-2017-9233 is not resolved.
2037 ```
2038
2039-As you can see, we are informed by `pro fix` that there is no fix available. In
2040-the last line, we can also see that the USN is not resolved.
2041+As you can see, we are informed by `pro fix` that some packages do not have a fix available. In
2042+the last line, we can also see that the CVE is not resolved.
2043
2044 ## CVE/USN that require an Ubuntu Pro subscription
2045
2046@@ -193,6 +203,8 @@ USN-5079-2: curl vulnerabilities
2047 Found CVEs:
2048 https://ubuntu.com/security/CVE-2021-22946
2049 https://ubuntu.com/security/CVE-2021-22947
2050+
2051+Fixing requested USN-5079-2
2052 1 affected package is installed: curl
2053 (1/1) curl:
2054 A fix is available in Ubuntu Pro: ESM Infra.
2055@@ -222,6 +234,7 @@ USN-5079-2: curl vulnerabilities
2056 Found CVEs:
2057 https://ubuntu.com/security/CVE-2021-22946
2058 https://ubuntu.com/security/CVE-2021-22947
2059+
2060 1 affected package is installed: curl
2061 (1/1) curl:
2062 A fix is available in Ubuntu Pro: ESM Infra.
2063@@ -258,22 +271,40 @@ Enable services with: pro enable <service>
2064 Technical support level: essential
2065 { apt update && apt install --only-upgrade -y curl libcurl3-gnutls }
2066 ✔ USN-5079-2 is resolved.
2067+
2068+Found related USNs:
2069+- USN-5079-1
2070+
2071+Fixing related USNs:
2072+- USN-5079-1
2073+No affected source packages are installed.
2074+
2075+✔ USN-5079-1 does not affect your system.
2076+
2077+Summary:
2078+✔ USN-5079-2 [requested] is resolved.
2079+✔ USN-5079-1 [related] does not affect your system.
2080 ```
2081
2082-We can see that that the attach command was successful, which can be verified
2083+We can see that this command also fixed related USN **USN-5079-1**.
2084+If you want to learn more about related USNs, refer to [our explanation guide](../explanations/cves_and_usns_explained.md#what-are-related-usns)
2085+
2086+Finally, we can see that that the attach command was successful, which can be verified
2087 by the status output we see when executing the command. Additionally, we can
2088 observe that the USN is indeed fixed, which you can confirm by running the
2089 `pro fix` command again:
2090
2091 ```
2092-N-5079-2: curl vulnerabilities
2093+USN-5079-2: curl vulnerabilities
2094 Found CVEs:
2095 https://ubuntu.com/security/CVE-2021-22946
2096 https://ubuntu.com/security/CVE-2021-22947
2097+
2098 1 affected package is installed: curl
2099 (1/1) curl:
2100 A fix is available in Ubuntu Pro: ESM Infra.
2101 The update is already installed.
2102+
2103 ✔ USN-5079-2 is resolved.
2104 ```
2105
2106@@ -308,6 +339,7 @@ prompted):
2107 ```
2108 CVE-2021-44731: snapd vulnerabilities
2109 https://ubuntu.com/security/CVE-2021-44731
2110+
2111 1 affected package is installed: snapd
2112 (1/1) snapd:
2113 A fix is available in Ubuntu Pro: ESM Infra.
2114@@ -321,6 +353,7 @@ One moment, checking your subscription first
2115 Updating package lists
2116 Ubuntu Pro: ESM Infra enabled
2117 { apt update && apt install --only-upgrade -y ubuntu-core-launcher snapd }
2118+
2119 ✔ CVE-2021-44731 is resolved.
2120 ```
2121
2122@@ -342,13 +375,15 @@ $ sudo pro fix CVE-2022-0778
2123 Then you will see the following output:
2124
2125 ```
2126-VE-2022-0778: OpenSSL vulnerability
2127+CVE-2022-0778: OpenSSL vulnerability
2128 https://ubuntu.com/security/CVE-2022-0778
2129+
2130 1 affected package is installed: openssl
2131 (1/1) openssl:
2132 A fix is available in Ubuntu Pro: ESM Infra.
2133 { apt update && apt install --only-upgrade -y libssl1.0.0 openssl }
2134 A reboot is required to complete fix operation.
2135+
2136 ✘ CVE-2022-0778 is not resolved.
2137 ```
2138
2139@@ -358,10 +393,12 @@ indeed fixed:
2140 ```
2141 CVE-2022-0778: OpenSSL vulnerability
2142 https://ubuntu.com/security/CVE-2022-0778
2143+
2144 1 affected package is installed: openssl
2145 (1/1) openssl:
2146 A fix is available in Ubuntu Pro: ESM Infra.
2147 The update is already installed.
2148+
2149 ✔ CVE-2022-0778 is resolved.
2150 ```
2151
2152@@ -390,6 +427,7 @@ And you will see the following output:
2153 ```
2154 CVE-2017-9233: Expat vulnerability
2155 https://ubuntu.com/security/CVE-2017-9233
2156+
2157 3 affected packages are installed: expat, matanza, swish-e
2158 (1/3, 2/3) matanza, swish-e:
2159 Sorry, no fix is available.
2160@@ -397,6 +435,7 @@ Sorry, no fix is available.
2161 A fix is available in Ubuntu standard updates.
2162 { apt update && apt install --only-upgrade -y expat }
2163 2 packages are still affected: matanza, swish-e
2164+
2165 ✘ CVE-2017-9233 is not resolved.
2166 ```
2167
2168diff --git a/features/api_full_auto_attach.feature b/features/api_full_auto_attach.feature
2169index c65fca5..9df2f69 100644
2170--- a/features/api_full_auto_attach.feature
2171+++ b/features/api_full_auto_attach.feature
2172@@ -27,7 +27,7 @@ Feature: Full Auto-Attach Endpoint
2173 """
2174 Then stdout matches regexp:
2175 """
2176- livepatch +yes +(disabled|n/a) +Canonical Livepatch service
2177+ livepatch +yes +(disabled|n/a) +(Canonical Livepatch service|Current kernel is not supported)
2178 """
2179 Examples:
2180 | release |
2181diff --git a/features/apt_messages.feature b/features/apt_messages.feature
2182index 401360d..693ebee 100644
2183--- a/features/apt_messages.feature
2184+++ b/features/apt_messages.feature
2185@@ -175,7 +175,7 @@ Feature: APT Messages
2186 Calculating upgrade...
2187 Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
2188 <package>
2189- Learn more about Ubuntu Pro at https://ubuntu.com/pro
2190+ <learn_more_msg>
2191 0 upgraded, 0 newly installed, 0 to remove and \d+ not upgraded.
2192 """
2193 When I run `apt-get upgrade` with sudo
2194@@ -211,10 +211,10 @@ Feature: APT Messages
2195 0 upgraded, 0 newly installed, 0 to remove and \d+ not upgraded\.
2196 """
2197 Examples: ubuntu release
2198- | release | package |
2199- | bionic | ansible |
2200- | focal | hello |
2201- | jammy | hello |
2202+ | release | package | learn_more_msg |
2203+ | bionic | ansible | Learn more about Ubuntu Pro for 18.04 at https://ubuntu.com/18-04 |
2204+ | focal | hello | Learn more about Ubuntu Pro at https://ubuntu.com/pro |
2205+ | jammy | hello | Learn more about Ubuntu Pro at https://ubuntu.com/pro |
2206
2207 @series.all
2208 @uses.config.machine_type.lxd.container
2209@@ -613,6 +613,7 @@ Feature: APT Messages
2210
2211 @series.xenial
2212 @series.bionic
2213+ @series.focal
2214 @uses.config.machine_type.aws.generic
2215 Scenario Outline: AWS URLs
2216 Given a `<release>` machine with ubuntu-advantage-tools installed
2217@@ -620,17 +621,19 @@ Feature: APT Messages
2218 When I run `apt-get install ansible -y` with sudo
2219 When I run `apt-get update` with sudo
2220 When I run `apt upgrade --dry-run` with sudo
2221- Then stdout matches regexp:
2222+ Then stdout contains substring:
2223 """
2224 <msg>
2225 """
2226 Examples: ubuntu release
2227- | release | msg |
2228- | xenial | Learn more about Ubuntu Pro for 16\.04 at https:\/\/ubuntu\.com\/16-04 |
2229- | bionic | Learn more about Ubuntu Pro on AWS at https:\/\/ubuntu\.com\/aws\/pro |
2230+ | release | msg |
2231+ | xenial | Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04 |
2232+ | bionic | Learn more about Ubuntu Pro for 18.04 at https://ubuntu.com/18-04 |
2233+ | focal | Learn more about Ubuntu Pro on AWS at https://ubuntu.com/aws/pro |
2234
2235 @series.xenial
2236 @series.bionic
2237+ @series.focal
2238 @uses.config.machine_type.azure.generic
2239 Scenario Outline: Azure URLs
2240 Given a `<release>` machine with ubuntu-advantage-tools installed
2241@@ -638,17 +641,19 @@ Feature: APT Messages
2242 When I run `apt-get install ansible -y` with sudo
2243 When I run `apt-get update` with sudo
2244 When I run `apt upgrade --dry-run` with sudo
2245- Then stdout matches regexp:
2246+ Then stdout contains substring:
2247 """
2248 <msg>
2249 """
2250 Examples: ubuntu release
2251- | release | msg |
2252- | xenial | Learn more about Ubuntu Pro for 16\.04 on Azure at https:\/\/ubuntu\.com\/16-04\/azure |
2253- | bionic | Learn more about Ubuntu Pro on Azure at https:\/\/ubuntu\.com\/azure\/pro |
2254+ | release | msg |
2255+ | xenial | Learn more about Ubuntu Pro for 16.04 on Azure at https://ubuntu.com/16-04/azure |
2256+ | bionic | Learn more about Ubuntu Pro for 18.04 on Azure at https://ubuntu.com/18-04/azure |
2257+ | focal | Learn more about Ubuntu Pro on Azure at https://ubuntu.com/azure/pro |
2258
2259 @series.xenial
2260 @series.bionic
2261+ @series.focal
2262 @uses.config.machine_type.gcp.generic
2263 Scenario Outline: GCP URLs
2264 Given a `<release>` machine with ubuntu-advantage-tools installed
2265@@ -656,14 +661,15 @@ Feature: APT Messages
2266 When I run `apt-get install ansible -y` with sudo
2267 When I run `apt-get update` with sudo
2268 When I run `apt upgrade --dry-run` with sudo
2269- Then stdout matches regexp:
2270+ Then stdout contains substring:
2271 """
2272 <msg>
2273 """
2274 Examples: ubuntu release
2275 | release | msg |
2276- | xenial | Learn more about Ubuntu Pro for 16\.04 at https:\/\/ubuntu\.com\/16-04 |
2277- | bionic | Learn more about Ubuntu Pro on GCP at https:\/\/ubuntu\.com\/gcp\/pro |
2278+ | xenial | Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04 |
2279+ | bionic | Learn more about Ubuntu Pro for 18.04 at https://ubuntu.com/18-04 |
2280+ | focal | Learn more about Ubuntu Pro on GCP at https://ubuntu.com/gcp/pro |
2281
2282 @series.kinetic
2283 @uses.config.machine_type.lxd.container
2284diff --git a/features/attach_validtoken.feature b/features/attach_validtoken.feature
2285index da04c06..3ff70d5 100644
2286--- a/features/attach_validtoken.feature
2287+++ b/features/attach_validtoken.feature
2288@@ -8,18 +8,31 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
2289 Scenario Outline: Attached command in a non-lts ubuntu machine
2290 Given a `<release>` machine with ubuntu-advantage-tools installed
2291 When I attach `contract_token` with sudo
2292- And I run `pro status --all` as non-root
2293+ And I run `pro status` as non-root
2294 Then stdout matches regexp:
2295- """
2296- SERVICE +ENTITLED STATUS DESCRIPTION
2297- cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages
2298- cis +yes +n/a +Security compliance and audit tools
2299- esm-apps +yes +n/a +Expanded Security Maintenance for Applications
2300- esm-infra +yes +n/a +Expanded Security Maintenance for Infrastructure
2301- fips +yes +n/a +NIST-certified core packages
2302- fips-updates +yes +n/a +NIST-certified core packages with priority security updates
2303- livepatch +yes +n/a +Canonical Livepatch service
2304- """
2305+ """
2306+ No Ubuntu Pro services are available to this system.
2307+ """
2308+ And stdout matches regexp:
2309+ """
2310+ For a list of all Ubuntu Pro services, run 'pro status --all'
2311+ """
2312+ When I run `pro status --all` as non-root
2313+ Then stdout matches regexp:
2314+ """
2315+ SERVICE +ENTITLED STATUS DESCRIPTION
2316+ cc-eal +yes +n/a +Common Criteria EAL2 Provisioning Packages
2317+ cis +yes +n/a +Security compliance and audit tools
2318+ esm-apps +yes +n/a +Expanded Security Maintenance for Applications
2319+ esm-infra +yes +n/a +Expanded Security Maintenance for Infrastructure
2320+ fips +yes +n/a +NIST-certified core packages
2321+ fips-updates +yes +n/a +NIST-certified core packages with priority security updates
2322+ livepatch +yes +n/a +Canonical Livepatch service
2323+ """
2324+ And stdout does not match regexp:
2325+ """
2326+ For a list of all Ubuntu Pro services, run 'pro status --all'
2327+ """
2328
2329 Examples: ubuntu release
2330 | release |
2331@@ -83,7 +96,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
2332 | xenial | libkrad0=1.13.2+dfsg-5 | disabled | cis | disabled | disabled | Canonical Livepatch service |
2333 | bionic | libkrad0=1.16-2build1 | disabled | cis | disabled | disabled | Canonical Livepatch service |
2334 | focal | hello=2.10-2ubuntu2 | n/a | usg | disabled | disabled | Canonical Livepatch service |
2335- | jammy | hello=2.10-2ubuntu4 | n/a | usg | n/a | n/a | Available with the HWE kernel |
2336+ | jammy | hello=2.10-2ubuntu4 | n/a | usg | n/a | n/a | Canonical Livepatch service |
2337
2338 @series.lts
2339 @uses.config.machine_type.lxd.container
2340@@ -380,6 +393,7 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
2341
2342 Examples: ubuntu release livepatch status
2343 | release |
2344- | xenial |
2345- | bionic |
2346- | focal |
2347+ # removing until we add this feature back in a way that doesn't hammer the server
2348+ #| xenial |
2349+ #| bionic |
2350+ #| focal |
2351diff --git a/features/attached_commands.feature b/features/attached_commands.feature
2352index 524e4e0..ffedcbe 100644
2353--- a/features/attached_commands.feature
2354+++ b/features/attached_commands.feature
2355@@ -294,7 +294,7 @@ Feature: Command behaviour when attached to an Ubuntu Pro subscription
2356 | xenial | yes | yes | yes | yes | yes | yes | cis | no |
2357 | bionic | yes | yes | yes | yes | yes | yes | cis | no |
2358 | focal | yes | no | yes | yes | yes | no | usg | no |
2359- | jammy | yes | no | no | no | no | no | usg | yes |
2360+ | jammy | yes | no | yes | no | no | no | usg | yes |
2361
2362 @series.all
2363 @uses.config.machine_type.lxd.container
2364diff --git a/features/attached_status.feature b/features/attached_status.feature
2365index b01386e..571bba4 100644
2366--- a/features/attached_status.feature
2367+++ b/features/attached_status.feature
2368@@ -101,6 +101,7 @@ Feature: Attached status
2369 ros +yes +disabled +Security Updates for the Robot Operating System
2370 ros-updates +yes +disabled +All Updates for the Robot Operating System
2371
2372+ For a list of all Ubuntu Pro services, run 'pro status --all'
2373 Enable services with: pro enable <service>
2374 """
2375 When I verify root and non-root `pro status --all` calls have the same output
2376@@ -143,6 +144,7 @@ Feature: Attached status
2377 fips-updates +yes +disabled +NIST-certified core packages with priority security updates
2378 usg +yes +disabled +Security compliance and audit tools
2379
2380+ For a list of all Ubuntu Pro services, run 'pro status --all'
2381 Enable services with: pro enable <service>
2382 """
2383 When I verify root and non-root `pro status --all` calls have the same output
2384@@ -180,7 +182,9 @@ Feature: Attached status
2385 SERVICE +ENTITLED +STATUS +DESCRIPTION
2386 esm-apps +yes +enabled +Expanded Security Maintenance for Applications
2387 esm-infra +yes +enabled +Expanded Security Maintenance for Infrastructure
2388+ usg +yes +disabled +Security compliance and audit tools
2389
2390+ For a list of all Ubuntu Pro services, run 'pro status --all'
2391 Enable services with: pro enable <service>
2392 """
2393 When I verify root and non-root `pro status --all` calls have the same output
2394@@ -197,7 +201,7 @@ Feature: Attached status
2395 realtime-kernel +yes +n/a +Ubuntu kernel with PREEMPT_RT patches integrated
2396 ros +yes +n/a +Security Updates for the Robot Operating System
2397 ros-updates +yes +n/a +All Updates for the Robot Operating System
2398- usg +yes +n/a +Security compliance and audit tools
2399+ usg +yes +disabled +Security compliance and audit tools
2400
2401 Enable services with: pro enable <service>
2402 """
2403diff --git a/features/cloud.py b/features/cloud.py
2404index 1a5d11b..d222f84 100644
2405--- a/features/cloud.py
2406+++ b/features/cloud.py
2407@@ -168,7 +168,7 @@ class Cloud:
2408 """
2409 return instance.id
2410
2411- def locate_image_name(self, series: str) -> str:
2412+ def locate_image_name(self, series: str, daily: bool = True) -> str:
2413 """Locate and return the image name to use for vm provision.
2414
2415 :param series:
2416@@ -189,7 +189,14 @@ class Cloud:
2417 elif "pro" in self.machine_type:
2418 image_type = ImageType.PRO
2419
2420- return self.api.daily_image(release=series, image_type=image_type)
2421+ if daily:
2422+ logging.debug("looking up daily image for {}".format(series))
2423+ return self.api.daily_image(release=series, image_type=image_type)
2424+ else:
2425+ logging.debug("looking up released image for {}".format(series))
2426+ return self.api.released_image(
2427+ release=series, image_type=image_type
2428+ )
2429
2430 def manage_ssh_key(
2431 self,
2432@@ -297,7 +304,14 @@ class EC2(Cloud):
2433 An AWS cloud provider instance
2434 """
2435 if not image_name:
2436- image_name = self.locate_image_name(series)
2437+ if series == "xenial" and "pro" not in self.machine_type:
2438+ logging.debug(
2439+ "defaulting to non-daily image for awsgeneric-16.04"
2440+ )
2441+ daily = False
2442+ else:
2443+ daily = True
2444+ image_name = self.locate_image_name(series, daily=daily)
2445
2446 logging.info(
2447 "--- Launching AWS image {}({})".format(image_name, series)
2448@@ -603,7 +617,7 @@ class _LXD(Cloud):
2449 # instead of the instance id
2450 return instance.name
2451
2452- def locate_image_name(self, series: str) -> str:
2453+ def locate_image_name(self, series: str, daily: bool = True) -> str:
2454 """Locate and return the image name to use for vm provision.
2455
2456 :param series:
2457@@ -618,7 +632,13 @@ class _LXD(Cloud):
2458 "Must provide either series or image_name to launch azure"
2459 )
2460
2461- image_name = self.api.daily_image(release=series)
2462+ if daily:
2463+ logging.debug("looking up daily image for {}".format(series))
2464+ image_name = self.api.daily_image(release=series)
2465+ else:
2466+ logging.debug("looking up released image for {}".format(series))
2467+ image_name = self.api.released_image(release=series)
2468+
2469 return image_name
2470
2471
2472diff --git a/features/daemon.feature b/features/daemon.feature
2473index ed74ec5..88fbbf7 100644
2474--- a/features/daemon.feature
2475+++ b/features/daemon.feature
2476@@ -105,10 +105,10 @@ Feature: Pro Upgrade Daemon only runs in environments where necessary
2477 Active: active \(running\)
2478 """
2479 # TODO find out what caused memory to go up, try to lower it again
2480- Then on `xenial`, systemd status output says memory usage is less than `16` MB
2481- Then on `bionic`, systemd status output says memory usage is less than `14` MB
2482- Then on `focal`, systemd status output says memory usage is less than `12` MB
2483- Then on `jammy`, systemd status output says memory usage is less than `13` MB
2484+ Then on `xenial`, systemd status output says memory usage is less than `17` MB
2485+ Then on `bionic`, systemd status output says memory usage is less than `15` MB
2486+ Then on `focal`, systemd status output says memory usage is less than `13` MB
2487+ Then on `jammy`, systemd status output says memory usage is less than `14` MB
2488
2489 When I run `cat /var/log/ubuntu-advantage-daemon.log` with sudo
2490 Then stdout matches regexp:
2491diff --git a/features/docker.feature b/features/docker.feature
2492index 2e82266..bf204d9 100644
2493--- a/features/docker.feature
2494+++ b/features/docker.feature
2495@@ -77,4 +77,3 @@ Feature: Build docker images with pro services
2496 | focal | xenial | [ esm-infra ] | curl | esm |
2497 | focal | bionic | [ fips ] | openssl | fips |
2498 | focal | focal | [ esm-apps ] | hello | esm |
2499-
2500diff --git a/features/enable_fips_cloud.feature b/features/enable_fips_cloud.feature
2501index c14b39b..41edbb0 100644
2502--- a/features/enable_fips_cloud.feature
2503+++ b/features/enable_fips_cloud.feature
2504@@ -217,7 +217,7 @@ Feature: FIPS enablement in cloud based machines
2505 And I verify that `strongswan-hmac` is installed from apt source `<fips-apt-source>`
2506 When I run `apt-cache policy ubuntu-fips` as non-root
2507 Then stdout does not match regexp:
2508- ""
2509+ """
2510 .*Installed: \(none\)
2511 """
2512 When I reboot the machine
2513diff --git a/features/enable_fips_vm.feature b/features/enable_fips_vm.feature
2514index ea6c38e..88a5db8 100644
2515--- a/features/enable_fips_vm.feature
2516+++ b/features/enable_fips_vm.feature
2517@@ -11,7 +11,7 @@ Feature: FIPS enablement in lxd VMs
2518 When I run `pro status --format json` with sudo
2519 Then stdout contains substring
2520 """
2521- {"available": "yes", "blocked_by": [{"name": "livepatch", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "disabled", "status_details": "FIPS is not configured"}
2522+ {"available": "yes", "blocked_by": [{"name": "livepatch", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "disabled", "status_details": "FIPS is not configured", "warning": null}
2523 """
2524 When I run `pro disable livepatch` with sudo
2525 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]
2526@@ -48,15 +48,14 @@ Feature: FIPS enablement in lxd VMs
2527 When I run `pro status --format json --all` with sudo
2528 Then stdout contains substring:
2529 """
2530- {"available": "no", "blocked_by": [{"name": "fips", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}], "description": "Canonical Livepatch service", "description_override": null, "entitled": "yes", "name": "livepatch", "status": "n/a", "status_details": "Cannot enable Livepatch when FIPS is enabled."}
2531+ {"available": "no", "blocked_by": [{"name": "fips", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}], "description": "Canonical Livepatch service", "description_override": null, "entitled": "yes", "name": "livepatch", "status": "n/a", "status_details": "Cannot enable Livepatch when FIPS is enabled.", "warning": null}
2532 """
2533-
2534 When I reboot the machine
2535 And I run `uname -r` as non-root
2536 Then stdout matches regexp:
2537- """
2538- fips
2539- """
2540+ """
2541+ fips
2542+ """
2543 When I run `cat /proc/sys/crypto/fips_enabled` with sudo
2544 Then I will see the following on stdout:
2545 """
2546@@ -64,24 +63,24 @@ Feature: FIPS enablement in lxd VMs
2547 """
2548 When I run `pro status --all` with sudo
2549 Then stdout does not match regexp:
2550- """
2551- FIPS support requires system reboot to complete configuration
2552- """
2553+ """
2554+ FIPS support requires system reboot to complete configuration
2555+ """
2556 When I run `pro disable <fips-service>` `with sudo` and stdin `y`
2557 Then stdout matches regexp:
2558- """
2559- This will disable the FIPS entitlement but the FIPS packages will remain installed.
2560- """
2561+ """
2562+ This will disable the FIPS entitlement but the FIPS packages will remain installed.
2563+ """
2564 And stdout matches regexp:
2565- """
2566- Updating package lists
2567- A reboot is required to complete disable operation
2568- """
2569+ """
2570+ Updating package lists
2571+ A reboot is required to complete disable operation
2572+ """
2573 When I run `pro status --all` with sudo
2574 Then stdout matches regexp:
2575- """
2576- Disabling FIPS requires system reboot to complete operation
2577- """
2578+ """
2579+ Disabling FIPS requires system reboot to complete operation
2580+ """
2581 When I run `apt-cache policy ubuntu-fips` as non-root
2582 Then stdout matches regexp:
2583 """
2584@@ -103,13 +102,13 @@ Feature: FIPS enablement in lxd VMs
2585 """
2586 When I run `pro status --all` with sudo
2587 Then stdout matches regexp:
2588- """
2589- <fips-service> +yes disabled
2590- """
2591+ """
2592+ <fips-service> +yes disabled
2593+ """
2594 Then stdout does not match regexp:
2595- """
2596- Disabling FIPS requires system reboot to complete operation
2597- """
2598+ """
2599+ Disabling FIPS requires system reboot to complete operation
2600+ """
2601 When I run `pro enable <fips-service> --assume-yes --format json --assume-yes` with sudo
2602 Then stdout is a json matching the `ua_operation` schema
2603 And I will see the following on stdout:
2604@@ -125,9 +124,9 @@ Feature: FIPS enablement in lxd VMs
2605 """
2606 When I run `pro status --all` with sudo
2607 Then stdout matches regexp:
2608- """
2609- <fips-service> +yes disabled
2610- """
2611+ """
2612+ <fips-service> +yes disabled
2613+ """
2614
2615 Examples: ubuntu release
2616 | release | fips-name | fips-service |fips-apt-source |
2617@@ -171,7 +170,7 @@ Feature: FIPS enablement in lxd VMs
2618 When I run `pro status --all --format json` with sudo
2619 Then stdout contains substring:
2620 """
2621- {"available": "no", "blocked_by": [{"name": "fips-updates", "reason": "FIPS cannot be enabled if FIPS Updates has ever been enabled because FIPS Updates installs security patches that aren't officially certified.", "reason_code": "fips-updates-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "n/a", "status_details": "Cannot enable FIPS when FIPS Updates is enabled."}
2622+ {"available": "no", "blocked_by": [{"name": "fips-updates", "reason": "FIPS cannot be enabled if FIPS Updates has ever been enabled because FIPS Updates installs security patches that aren't officially certified.", "reason_code": "fips-updates-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "n/a", "status_details": "Cannot enable FIPS when FIPS Updates is enabled.", "warning": null}
2623 """
2624
2625 When I reboot the machine
2626@@ -245,7 +244,7 @@ Feature: FIPS enablement in lxd VMs
2627 When I run `pro status --all --format json` with sudo
2628 Then stdout contains substring:
2629 """
2630- {"available": "no", "blocked_by": [{"name": "livepatch", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}, {"name": "fips-updates", "reason": "FIPS cannot be enabled if FIPS Updates has ever been enabled because FIPS Updates installs security patches that aren't officially certified.", "reason_code": "fips-updates-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "n/a", "status_details": "Cannot enable FIPS when FIPS Updates is enabled."}
2631+ {"available": "no", "blocked_by": [{"name": "livepatch", "reason": "Livepatch cannot be enabled while running the official FIPS certified kernel. If you would like a FIPS compliant kernel with additional bug fixes and security updates, you can use the FIPS Updates service with Livepatch.", "reason_code": "livepatch-invalidates-fips"}, {"name": "fips-updates", "reason": "FIPS cannot be enabled if FIPS Updates has ever been enabled because FIPS Updates installs security patches that aren't officially certified.", "reason_code": "fips-updates-invalidates-fips"}], "description": "NIST-certified core packages", "description_override": null, "entitled": "yes", "name": "fips", "status": "n/a", "status_details": "Cannot enable FIPS when FIPS Updates is enabled.", "warning": null}
2632 """
2633 When I run `pro disable <fips-service> --assume-yes` with sudo
2634 And I run `pro enable <fips-service> --assume-yes --format json --assume-yes` with sudo
2635@@ -342,7 +341,6 @@ Feature: FIPS enablement in lxd VMs
2636 """
2637 Updating package lists
2638 Installing <fips-name> packages
2639- FIPS strongswan-hmac package could not be installed
2640 <fips-name> enabled
2641 A reboot is required to complete install
2642 """
2643@@ -376,6 +374,8 @@ Feature: FIPS enablement in lxd VMs
2644 When I reboot the machine
2645 Then I verify that `openssh-server` installed version matches regexp `fips`
2646 And I verify that `openssh-client` installed version matches regexp `fips`
2647+ And I verify that `strongswan` installed version matches regexp `fips`
2648+ And I verify that `strongswan-hmac` installed version matches regexp `fips`
2649 When I run `apt-mark unhold openssh-client openssh-server strongswan` with sudo
2650 Then I will see the following on stdout:
2651 """
2652@@ -520,7 +520,7 @@ Feature: FIPS enablement in lxd VMs
2653 """
2654 And stdout matches regexp:
2655 """
2656- livepatch +yes enabled
2657+ livepatch +yes (enabled|warning)
2658 """
2659 When I run `uname -r` as non-root
2660 Then stdout matches regexp:
2661diff --git a/features/environment.py b/features/environment.py
2662index 8c3f685..522a02f 100644
2663--- a/features/environment.py
2664+++ b/features/environment.py
2665@@ -6,6 +6,7 @@ import random
2666 import re
2667 import string
2668 import sys
2669+import tarfile
2670 from typing import Dict, List, Optional, Tuple, Union # noqa: F401
2671
2672 import pycloudlib # type: ignore # noqa: F401
2673@@ -123,8 +124,8 @@ class UAClientBehaveConfig:
2674 contract_token: Optional[str] = None,
2675 contract_token_staging: Optional[str] = None,
2676 contract_token_staging_expired: Optional[str] = None,
2677- artifact_dir: Optional[str] = None,
2678- install_from: InstallationSource = InstallationSource.DAILY,
2679+ artifact_dir: str = "artifacts",
2680+ install_from: InstallationSource = InstallationSource.LOCAL,
2681 custom_ppa: Optional[str] = None,
2682 debs_path: Optional[str] = None,
2683 userdata_file: Optional[str] = None,
2684@@ -299,6 +300,9 @@ class UAClientBehaveConfig:
2685 bool_value = False
2686 kwargs[key] = bool_value
2687
2688+ # userdata should override environment variables
2689+ kwargs.update(config.userdata)
2690+
2691 if "install_from" in kwargs:
2692 kwargs["install_from"] = InstallationSource(kwargs["install_from"])
2693
2694@@ -329,17 +333,17 @@ def before_all(context: Context) -> None:
2695 print(" - {} = {}".format(key, value))
2696 context.series_image_name = {}
2697 context.series_reuse_image = ""
2698- context.config = UAClientBehaveConfig.from_environ(context.config)
2699- context.config.cloud_manager.manage_ssh_key()
2700+ context.pro_config = UAClientBehaveConfig.from_environ(context.config)
2701+ context.pro_config.cloud_manager.manage_ssh_key()
2702 context.snapshots = {}
2703 context.machines = {}
2704
2705- if context.config.reuse_image:
2706+ if context.pro_config.reuse_image:
2707 series = lxc_get_property(
2708- context.config.reuse_image, property_name="series", image=True
2709+ context.pro_config.reuse_image, property_name="series", image=True
2710 )
2711 machine_type = lxc_get_property(
2712- context.config.reuse_image,
2713+ context.pro_config.reuse_image,
2714 property_name="machine_type",
2715 image=True,
2716 )
2717@@ -347,26 +351,26 @@ def before_all(context: Context) -> None:
2718 print("Found machine_type: {vm_type}".format(vm_type=machine_type))
2719 if series is not None:
2720 context.series_reuse_image = series
2721- context.series_image_name[series] = context.config.reuse_image
2722+ context.series_image_name[series] = context.pro_config.reuse_image
2723 else:
2724 print(" Could not check image series. It will not be used. ")
2725- context.config.reuse_image = None
2726+ context.pro_config.reuse_image = None
2727
2728
2729 def _should_skip_tags(context: Context, tags: List) -> str:
2730 """Return a reason if a feature or scenario should be skipped"""
2731- machine_type = getattr(context.config, "machine_type", "")
2732+ machine_type = getattr(context.pro_config, "machine_type", "")
2733 machine_types = []
2734
2735 for tag in tags:
2736 parts = tag.split(".")
2737- if parts[0] != "uses":
2738- continue # Only process @uses.* tags for skipping:
2739- val = context
2740- for idx, attr in enumerate(parts[1:], 1):
2741+ if parts[0] != "uses" or parts[1] != "config":
2742+ continue # Only process @uses.config.* tags for skipping:
2743+ val = context.pro_config
2744+ for idx, attr in enumerate(parts[2:], 1):
2745 val = getattr(val, attr, None)
2746 if attr == "machine_type":
2747- curr_machine_type = ".".join(parts[idx + 1 :])
2748+ curr_machine_type = ".".join(parts[idx + 2 :])
2749 machine_types.append(curr_machine_type)
2750 if curr_machine_type == machine_type:
2751 return ""
2752@@ -397,7 +401,7 @@ def before_scenario(context: Context, scenario: Scenario):
2753 scenario.skip(reason=reason)
2754 return
2755
2756- filter_series = context.config.filter_series
2757+ filter_series = context.pro_config.filter_series
2758 given_a_series_match = re.match(
2759 "a `(.*)` machine with ubuntu-advantage-tools installed",
2760 scenario.steps[0].name,
2761@@ -431,61 +435,30 @@ def before_scenario(context: Context, scenario: Scenario):
2762 )
2763
2764
2765-FAILURE_FILES = (
2766- "/etc/ubuntu-advantage/uaclient.log",
2767- "/var/log/cloud-init.log",
2768- "/var/log/ubuntu-advantage.log",
2769- "/var/log/ubuntu-advantage-daemon.log",
2770- "/var/log/ubuntu-advantage-timer.log",
2771- "/var/lib/cloud/instance/user-data.txt",
2772- "/var/lib/cloud/instance/vendor-data.txt",
2773-)
2774-FAILURE_CMDS = {
2775- "ua-version": ["pro", "version"],
2776- "cloud-init-analyze": ["cloud-init", "analyze", "show"],
2777- "cloud-init.status": ["cloud-init", "status", "--long"],
2778- "status.yaml": ["pro", "status", "--all", "--format=yaml"],
2779- "journal.log": ["journalctl", "-b", "0"],
2780- "systemd-analyze-blame": ["systemd-analyze", "blame"],
2781- "systemctl-status": ["systemctl", "status"],
2782- "systemctl-status-ua-auto-attach": [
2783- "systemctl",
2784- "status",
2785- "ua-auto-attach.service",
2786- ],
2787- "systemctl-status-ua-reboot-cmds": [
2788- "systemctl",
2789- "status",
2790- "ua-reboot-cmds.service",
2791- ],
2792- "systemctl-status-ubuntu-advantage": [
2793- "systemctl",
2794- "status",
2795- "ubuntu-advantage.service",
2796- ],
2797- "systemctl-status-apt-news": [
2798- "systemctl",
2799- "status",
2800- "apt-news.service",
2801- ],
2802-}
2803-
2804-
2805 def after_step(context, step):
2806 """Collect test artifacts in the event of failure."""
2807 if step.status == "failed":
2808- if context.config.artifact_dir:
2809- artifacts_dir = context.config.artifact_dir
2810- else:
2811- artifacts_dir = "artifacts"
2812- artifacts_dir = os.path.join(
2813- artifacts_dir,
2814+ logging.warning("STEP FAILED. Collecting logs.")
2815+ inner_dir = os.path.join(
2816+ datetime.datetime.now().strftime("%Y-%m-%dT%H-%M-%S"),
2817 "{}_{}".format(os.path.basename(step.filename), step.line),
2818 )
2819+ new_artifacts_dir = os.path.join(
2820+ context.pro_config.artifact_dir,
2821+ inner_dir,
2822+ )
2823+ if not os.path.exists(new_artifacts_dir):
2824+ os.makedirs(new_artifacts_dir)
2825+
2826+ latest_link_dir = os.path.join(
2827+ context.pro_config.artifact_dir, "latest"
2828+ )
2829+ if os.path.exists(latest_link_dir):
2830+ os.unlink(latest_link_dir)
2831+ os.symlink(inner_dir, latest_link_dir)
2832+
2833 if hasattr(context, "process"):
2834- if not os.path.exists(artifacts_dir):
2835- os.makedirs(artifacts_dir)
2836- artifact_file = os.path.join(artifacts_dir, "process.log")
2837+ artifact_file = os.path.join(new_artifacts_dir, "process.log")
2838 process = context.process
2839 with open(artifact_file, "w") as stream:
2840 stream.write(
2841@@ -497,35 +470,28 @@ def after_step(context, step):
2842 )
2843
2844 if hasattr(context, "machines") and SUT in context.machines:
2845- if not os.path.exists(artifacts_dir):
2846- os.makedirs(artifacts_dir)
2847- for log_file in FAILURE_FILES:
2848- artifact_file = os.path.join(
2849- artifacts_dir, os.path.basename(log_file)
2850+ try:
2851+ context.machines[SUT].instance.execute(
2852+ ["pro", "collect-logs", "-o", "/tmp/logs.tar.gz"],
2853+ use_sudo=True,
2854 )
2855- logging.info(
2856- "-- pull instance:{} {}".format(log_file, artifact_file)
2857+ context.machines[SUT].instance.execute(
2858+ ["chmod", "666", "/tmp/logs.tar.gz"], use_sudo=True
2859 )
2860- try:
2861- result = context.machines[SUT].instance.execute(
2862- ["cat", log_file], use_sudo=True
2863- )
2864- content = result.stdout if result.ok else ""
2865- except RuntimeError:
2866- content = ""
2867- with open(artifact_file, "w") as stream:
2868- stream.write(content)
2869- for artifact_file, cmd in FAILURE_CMDS.items():
2870- result = context.machines[SUT].instance.execute(
2871- cmd, use_sudo=True
2872+ dest = os.path.join(new_artifacts_dir, "logs.tar.gz")
2873+ context.machines[SUT].instance.pull_file(
2874+ "/tmp/logs.tar.gz", dest
2875 )
2876- artifact_file = os.path.join(artifacts_dir, artifact_file)
2877- with open(artifact_file, "w") as stream:
2878- stream.write(result.stdout)
2879+ with tarfile.open(dest) as logs_tarfile:
2880+ logs_tarfile.extractall(new_artifacts_dir)
2881+ logging.warning("Done collecting logs.")
2882+ except Exception as e:
2883+ logging.error(str(e))
2884+ logging.warning("Failed to collect logs")
2885
2886
2887 def after_all(context):
2888- if context.config.image_clean:
2889+ if context.pro_config.image_clean:
2890 for key, image in context.series_image_name.items():
2891 if key == context.series_reuse_image:
2892 logging.info(
2893@@ -533,11 +499,11 @@ def after_all(context):
2894 context.series_image_name[key],
2895 )
2896 else:
2897- context.config.cloud_api.delete_image(image)
2898+ context.pro_config.cloud_api.delete_image(image)
2899
2900- if context.config.destroy_instances:
2901+ if context.pro_config.destroy_instances:
2902 try:
2903- key_pair = context.config.cloud_manager.api.key_pair
2904+ key_pair = context.pro_config.cloud_manager.api.key_pair
2905 os.remove(key_pair.private_key_path)
2906 os.remove(key_pair.public_key_path)
2907 except Exception as e:
2908@@ -547,7 +513,7 @@ def after_all(context):
2909
2910 if "builder" in context.snapshots:
2911 try:
2912- context.config.cloud_manager.api.delete_image(
2913+ context.pro_config.cloud_manager.api.delete_image(
2914 context.snapshots["builder"]
2915 )
2916 except RuntimeError as e:
2917diff --git a/features/fix.feature b/features/fix.feature
2918index f62946f..cc10066 100644
2919--- a/features/fix.feature
2920+++ b/features/fix.feature
2921@@ -39,64 +39,158 @@ Feature: Ua fix command behaviour
2922 When I run `apt-get update` with sudo
2923 When I verify that running `pro fix CVE-1800-123456` `as non-root` exits `1`
2924 Then I will see the following on stderr:
2925- """
2926- Error: CVE-1800-123456 not found.
2927- """
2928+ """
2929+ Error: CVE-1800-123456 not found.
2930+ """
2931 When I verify that running `pro fix USN-12345-12` `as non-root` exits `1`
2932 Then I will see the following on stderr:
2933- """
2934- Error: USN-12345-12 not found.
2935- """
2936+ """
2937+ Error: USN-12345-12 not found.
2938+ """
2939 When I verify that running `pro fix CVE-12345678-12` `as non-root` exits `1`
2940 Then I will see the following on stderr:
2941- """
2942- Error: issue "CVE-12345678-12" is not recognized.
2943- Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn"
2944- """
2945+ """
2946+ Error: issue "CVE-12345678-12" is not recognized.
2947+ Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn"
2948+ """
2949 When I verify that running `pro fix USN-12345678-12` `as non-root` exits `1`
2950 Then I will see the following on stderr:
2951- """
2952- Error: issue "USN-12345678-12" is not recognized.
2953- Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn"
2954- """
2955+ """
2956+ Error: issue "USN-12345678-12" is not recognized.
2957+ Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn"
2958+ """
2959 When I run `apt install -y libawl-php=0.60-1 --allow-downgrades` with sudo
2960 And I run `pro fix USN-4539-1` with sudo
2961 Then stdout matches regexp:
2962- """
2963- USN-4539-1: AWL vulnerability
2964- Found CVEs:
2965- - https://ubuntu.com/security/CVE-2020-11728
2966+ """
2967+ USN-4539-1: AWL vulnerability
2968+ Found CVEs:
2969+ - https://ubuntu.com/security/CVE-2020-11728
2970
2971- 1 affected source package is installed: awl
2972- \(1/1\) awl:
2973- A fix is available in Ubuntu standard updates.
2974- .*\{ apt update && apt install --only-upgrade -y libawl-php \}.*
2975+ Fixing requested USN-4539-1
2976+ 1 affected source package is installed: awl
2977+ \(1/1\) awl:
2978+ A fix is available in Ubuntu standard updates.
2979+ .*\{ apt update && apt install --only-upgrade -y libawl-php \}.*
2980
2981- .*✔.* USN-4539-1 is resolved.
2982- """
2983+ .*✔.* USN-4539-1 is resolved.
2984+ """
2985 When I run `pro fix CVE-2020-28196` as non-root
2986 Then stdout matches regexp:
2987- """
2988- CVE-2020-28196: Kerberos vulnerability
2989- - https://ubuntu.com/security/CVE-2020-28196
2990+ """
2991+ CVE-2020-28196: Kerberos vulnerability
2992+ - https://ubuntu.com/security/CVE-2020-28196
2993
2994- 1 affected source package is installed: krb5
2995- \(1/1\) krb5:
2996- A fix is available in Ubuntu standard updates.
2997- The update is already installed.
2998+ 1 affected source package is installed: krb5
2999+ \(1/1\) krb5:
3000+ A fix is available in Ubuntu standard updates.
3001+ The update is already installed.
3002
3003- .*✔.* CVE-2020-28196 is resolved.
3004- """
3005+ .*✔.* CVE-2020-28196 is resolved.
3006+ """
3007 When I run `pro fix CVE-2022-24959` as non-root
3008 Then stdout matches regexp:
3009- """
3010- CVE-2022-24959: Linux kernel vulnerabilities
3011- - https://ubuntu.com/security/CVE-2022-24959
3012+ """
3013+ CVE-2022-24959: Linux kernel vulnerabilities
3014+ - https://ubuntu.com/security/CVE-2022-24959
3015
3016- No affected source packages are installed.
3017+ No affected source packages are installed.
3018
3019- .*✔.* CVE-2022-24959 does not affect your system.
3020- """
3021+ .*✔.* CVE-2022-24959 does not affect your system.
3022+ """
3023+ When I run `apt install -y rsync=3.1.3-8 --allow-downgrades` with sudo
3024+ And I run `apt install -y zlib1g=1:1.2.11.dfsg-2ubuntu1 --allow-downgrades` with sudo
3025+ And I run `pro fix USN-5573-1` with sudo
3026+ Then stdout matches regexp:
3027+ """
3028+ USN-5573-1: rsync vulnerability
3029+ Found CVEs:
3030+ - https://ubuntu.com/security/CVE-2022-37434
3031+
3032+ Fixing requested USN-5573-1
3033+ 1 affected source package is installed: rsync
3034+ \(1/1\) rsync:
3035+ A fix is available in Ubuntu standard updates.
3036+ .*\{ apt update && apt install --only-upgrade -y rsync \}.*
3037+
3038+ .*✔.* USN-5573-1 is resolved.
3039+
3040+ Found related USNs:
3041+ - USN-5570-1
3042+ - USN-5570-2
3043+
3044+ Fixing related USNs:
3045+ - USN-5570-1
3046+ No affected source packages are installed.
3047+
3048+ .*✔.* USN-5570-1 does not affect your system.
3049+
3050+ - USN-5570-2
3051+ 1 affected source package is installed: zlib
3052+ \(1/1\) zlib:
3053+ A fix is available in Ubuntu standard updates.
3054+ .*\{ apt update && apt install --only-upgrade -y zlib1g \}.*
3055+
3056+ .*✔.* USN-5570-2 is resolved.
3057+
3058+ Summary:
3059+ .*✔.* USN-5573-1 \[requested\] is resolved.
3060+ .*✔.* USN-5570-1 \[related\] does not affect your system.
3061+ .*✔.* USN-5570-2 \[related\] is resolved.
3062+ """
3063+ When I run `pro fix USN-5573-1` with sudo
3064+ Then stdout matches regexp:
3065+ """
3066+ USN-5573-1: rsync vulnerability
3067+ Found CVEs:
3068+ - https://ubuntu.com/security/CVE-2022-37434
3069+
3070+ Fixing requested USN-5573-1
3071+ 1 affected source package is installed: rsync
3072+ \(1/1\) rsync:
3073+ A fix is available in Ubuntu standard updates.
3074+ The update is already installed.
3075+
3076+ .*✔.* USN-5573-1 is resolved.
3077+
3078+ Found related USNs:
3079+ - USN-5570-1
3080+ - USN-5570-2
3081+
3082+ Fixing related USNs:
3083+ - USN-5570-1
3084+ No affected source packages are installed.
3085+
3086+ .*✔.* USN-5570-1 does not affect your system.
3087+
3088+ - USN-5570-2
3089+ 1 affected source package is installed: zlib
3090+ \(1/1\) zlib:
3091+ A fix is available in Ubuntu standard updates.
3092+ The update is already installed.
3093+
3094+ .*✔.* USN-5570-2 is resolved.
3095+
3096+ Summary:
3097+ .*✔.* USN-5573-1 \[requested\] is resolved.
3098+ .*✔.* USN-5570-1 \[related\] does not affect your system.
3099+ .*✔.* USN-5570-2 \[related\] is resolved.
3100+ """
3101+ When I run `pro fix USN-5573-1 --no-related` with sudo
3102+ Then stdout matches regexp:
3103+ """
3104+ USN-5573-1: rsync vulnerability
3105+ Found CVEs:
3106+ - https://ubuntu.com/security/CVE-2022-37434
3107+
3108+ Fixing requested USN-5573-1
3109+ 1 affected source package is installed: rsync
3110+ \(1/1\) rsync:
3111+ A fix is available in Ubuntu standard updates.
3112+ The update is already installed.
3113+
3114+ .*✔.* USN-5573-1 is resolved.
3115+ """
3116
3117 Examples: ubuntu release details
3118 | release |
3119@@ -107,22 +201,30 @@ Feature: Ua fix command behaviour
3120 @uses.config.machine_type.lxd.container
3121 Scenario Outline: Fix command on an unattached machine
3122 Given a `<release>` machine with ubuntu-advantage-tools installed
3123+ When I verify that running `pro fix CVE-1800-123456` `as non-root` exits `1`
3124+ Then I will see the following on stderr:
3125+ """
3126+ Error: CVE-1800-123456 not found.
3127+ """
3128+ When I verify that running `pro fix USN-12345-12` `as non-root` exits `1`
3129+ Then I will see the following on stderr:
3130+ """
3131+ Error: USN-12345-12 not found.
3132+ """
3133 When I run `apt-get update` with sudo
3134 When I run `apt install -y libawl-php` with sudo
3135 And I reboot the machine
3136- And I verify that running `pro fix USN-4539-1` `as non-root` exits `1`
3137+ And I run `pro fix USN-4539-1` as non-root
3138 Then stdout matches regexp:
3139 """
3140 USN-4539-1: AWL vulnerability
3141 Found CVEs:
3142 - https://ubuntu.com/security/CVE-2020-11728
3143
3144- 1 affected source package is installed: awl
3145- \(1/1\) awl:
3146- Ubuntu security engineers are investigating this issue.
3147+ Fixing requested USN-4539-1
3148+ No affected source packages are installed.
3149
3150- 1 package is still affected: awl
3151- .*✘.* USN-4539-1 is not resolved.
3152+ .*✔.* USN-4539-1 does not affect your system.
3153 """
3154 When I run `pro fix CVE-2020-15180` as non-root
3155 Then stdout matches regexp:
3156@@ -192,6 +294,7 @@ Feature: Ua fix command behaviour
3157 - https://ubuntu.com/security/CVE-2021-22946
3158 - https://ubuntu.com/security/CVE-2021-22947
3159
3160+ Fixing requested USN-5079-2
3161 1 affected source package is installed: curl
3162 \(1/1\) curl:
3163 A fix is available in Ubuntu Pro: ESM Infra.
3164@@ -207,6 +310,19 @@ Feature: Ua fix command behaviour
3165 .*\{ apt update && apt install --only-upgrade -y curl libcurl3-gnutls \}.*
3166
3167 .*✔.* USN-5079-2 is resolved.
3168+
3169+ Found related USNs:
3170+ - USN-5079-1
3171+
3172+ Fixing related USNs:
3173+ - USN-5079-1
3174+ No affected source packages are installed.
3175+
3176+ .*✔.* USN-5079-1 does not affect your system.
3177+
3178+ Summary:
3179+ .*✔.* USN-5079-2 \[requested\] is resolved.
3180+ .*✔.* USN-5079-1 \[related\] does not affect your system.
3181 """
3182 When I fix `USN-5079-2` by attaching to a subscription with `contract_token_staging_expired`
3183 Then stdout matches regexp
3184@@ -216,6 +332,7 @@ Feature: Ua fix command behaviour
3185 - https://ubuntu.com/security/CVE-2021-22946
3186 - https://ubuntu.com/security/CVE-2021-22947
3187
3188+ Fixing requested USN-5079-2
3189 1 affected source package is installed: curl
3190 \(1/1\) curl:
3191 A fix is available in Ubuntu Pro: ESM Infra.
3192@@ -240,6 +357,7 @@ Feature: Ua fix command behaviour
3193 - https://ubuntu.com/security/CVE-2021-22946
3194 - https://ubuntu.com/security/CVE-2021-22947
3195
3196+ Fixing requested USN-5079-2
3197 1 affected source package is installed: curl
3198 \(1/1\) curl:
3199 A fix is available in Ubuntu Pro: ESM Infra.
3200@@ -259,6 +377,19 @@ Feature: Ua fix command behaviour
3201 .*\{ apt update && apt install --only-upgrade -y curl libcurl3-gnutls \}.*
3202
3203 .*✔.* USN-5079-2 is resolved.
3204+
3205+ Found related USNs:
3206+ - USN-5079-1
3207+
3208+ Fixing related USNs:
3209+ - USN-5079-1
3210+ No affected source packages are installed.
3211+
3212+ .*✔.* USN-5079-1 does not affect your system.
3213+
3214+ Summary:
3215+ .*✔.* USN-5079-2 \[requested\] is resolved.
3216+ .*✔.* USN-5079-1 \[related\] does not affect your system.
3217 """
3218 When I verify that running `pro fix USN-5051-2` `with sudo` exits `2`
3219 Then stdout matches regexp:
3220@@ -267,6 +398,7 @@ Feature: Ua fix command behaviour
3221 Found CVEs:
3222 - https://ubuntu.com/security/CVE-2021-3712
3223
3224+ Fixing requested USN-5051-2
3225 1 affected source package is installed: openssl
3226 \(1/1\) openssl:
3227 A fix is available in Ubuntu Pro: ESM Infra.
3228@@ -276,6 +408,8 @@ Feature: Ua fix command behaviour
3229 .*✘.* USN-5051-2 is not resolved.
3230 """
3231 When I run `pro disable esm-infra` with sudo
3232+ # Allow esm-cache to be populated
3233+ And I run `sleep 5` as non-root
3234 And I run `apt-get install gzip -y` with sudo
3235 And I run `pro fix USN-5378-4 --dry-run` as non-root
3236 Then stdout matches regexp:
3237@@ -286,17 +420,53 @@ Feature: Ua fix command behaviour
3238 Found CVEs:
3239 - https://ubuntu.com/security/CVE-2022-1271
3240
3241- 2 affected source packages are installed: gzip, xz-utils
3242- \(1/2, 2/2\) gzip, xz-utils:
3243+ Fixing requested USN-5378-4
3244+ 1 affected source package is installed: gzip
3245+ \(1/1\) gzip:
3246 A fix is available in Ubuntu Pro: ESM Infra.
3247
3248 .*Ubuntu Pro service: esm-infra is not enabled.
3249 To proceed with the fix, a prompt would ask permission to automatically enable
3250 this service.
3251 \{ pro enable esm-infra \}.*
3252- .*\{ apt update && apt install --only-upgrade -y gzip liblzma5 xz-utils \}.*
3253+ .*\{ apt update && apt install --only-upgrade -y gzip \}.*
3254
3255 .*✔.* USN-5378-4 is resolved.
3256+
3257+ Found related USNs:
3258+ - USN-5378-1
3259+ - USN-5378-2
3260+ - USN-5378-3
3261+
3262+ Fixing related USNs:
3263+ - USN-5378-1
3264+ No affected source packages are installed.
3265+
3266+ .*✔.* USN-5378-1 does not affect your system.
3267+
3268+ - USN-5378-2
3269+ No affected source packages are installed.
3270+
3271+ .*✔.* USN-5378-2 does not affect your system.
3272+
3273+ - USN-5378-3
3274+ 1 affected source package is installed: xz-utils
3275+ \(1/1\) xz-utils:
3276+ A fix is available in Ubuntu Pro: ESM Infra.
3277+
3278+ .*Ubuntu Pro service: esm-infra is not enabled.
3279+ To proceed with the fix, a prompt would ask permission to automatically enable
3280+ this service.
3281+ \{ pro enable esm-infra \}.*
3282+ .*\{ apt update && apt install --only-upgrade -y liblzma5 xz-utils \}.*
3283+
3284+ .*✔.* USN-5378-3 is resolved.
3285+
3286+ Summary:
3287+ .*✔.* USN-5378-4 \[requested\] is resolved.
3288+ .*✔.* USN-5378-1 \[related\] does not affect your system.
3289+ .*✔.* USN-5378-2 \[related\] does not affect your system.
3290+ .*✔.* USN-5378-3 \[related\] is resolved.
3291 """
3292 When I run `pro fix USN-5378-4` `with sudo` and stdin `E`
3293 Then stdout matches regexp:
3294@@ -305,8 +475,9 @@ Feature: Ua fix command behaviour
3295 Found CVEs:
3296 - https://ubuntu.com/security/CVE-2022-1271
3297
3298- 2 affected source packages are installed: gzip, xz-utils
3299- \(1/2, 2/2\) gzip, xz-utils:
3300+ Fixing requested USN-5378-4
3301+ 1 affected source package is installed: gzip
3302+ \(1/1\) gzip:
3303 A fix is available in Ubuntu Pro: ESM Infra.
3304 The update is not installed because this system does not have
3305 esm-infra enabled.
3306@@ -316,9 +487,59 @@ Feature: Ua fix command behaviour
3307 One moment, checking your subscription first
3308 Updating package lists
3309 Ubuntu Pro: ESM Infra enabled
3310- .*\{ apt update && apt install --only-upgrade -y gzip liblzma5 xz-utils \}.*
3311+ .*\{ apt update && apt install --only-upgrade -y gzip \}.*
3312
3313 .*✔.* USN-5378-4 is resolved.
3314+
3315+ Found related USNs:
3316+ - USN-5378-1
3317+ - USN-5378-2
3318+ - USN-5378-3
3319+
3320+ Fixing related USNs:
3321+ - USN-5378-1
3322+ No affected source packages are installed.
3323+
3324+ .*✔.* USN-5378-1 does not affect your system.
3325+
3326+ - USN-5378-2
3327+ No affected source packages are installed.
3328+
3329+ .*✔.* USN-5378-2 does not affect your system.
3330+
3331+ - USN-5378-3
3332+ 1 affected source package is installed: xz-utils
3333+ \(1/1\) xz-utils:
3334+ A fix is available in Ubuntu Pro: ESM Infra.
3335+ .*\{ apt update && apt install --only-upgrade -y liblzma5 xz-utils \}.*
3336+
3337+ .*✔.* USN-5378-3 is resolved.
3338+
3339+ Summary:
3340+ .*✔.* USN-5378-4 \[requested\] is resolved.
3341+ .*✔.* USN-5378-1 \[related\] does not affect your system.
3342+ .*✔.* USN-5378-2 \[related\] does not affect your system.
3343+ .*✔.* USN-5378-3 \[related\] is resolved.
3344+ """
3345+ When I run `pro detach --assume-yes` with sudo
3346+ And I run `sed -i "/xenial-updates/d" /etc/apt/sources.list` with sudo
3347+ And I run `sed -i "/xenial-security/d" /etc/apt/sources.list` with sudo
3348+ And I run `apt-get update` with sudo
3349+ And I run `apt-get install squid -y` with sudo
3350+ And I verify that running `pro fix CVE-2020-25097` `as non-root` exits `1`
3351+ Then stdout matches regexp:
3352+ """
3353+ CVE-2020-25097: Squid vulnerabilities
3354+ - https://ubuntu.com/security/CVE-2020-25097
3355+
3356+ 1 affected source package is installed: squid3
3357+ \(1/1\) squid3:
3358+ A fix is available in Ubuntu standard updates.
3359+ - Cannot install package squid version 3.5.12-1ubuntu7.16
3360+ - Cannot install package squid-common version 3.5.12-1ubuntu7.16
3361+
3362+ 1 package is still affected: squid3
3363+ .*✘.* CVE-2020-25097 is not resolved
3364 """
3365
3366 Examples: ubuntu release details
3367@@ -353,7 +574,7 @@ Feature: Ua fix command behaviour
3368 Usage: "pro fix CVE-yyyy-nnnn" or "pro fix USN-nnnn"
3369 """
3370 When I run `apt install -y libawl-php` with sudo
3371- And I verify that running `pro fix USN-4539-1 --dry-run` `as non-root` exits `1`
3372+ And I run `pro fix USN-4539-1 --dry-run` as non-root
3373 Then stdout matches regexp:
3374 """
3375 .*WARNING: The option --dry-run is being used.
3376@@ -362,26 +583,22 @@ Feature: Ua fix command behaviour
3377 Found CVEs:
3378 - https://ubuntu.com/security/CVE-2020-11728
3379
3380- 1 affected source package is installed: awl
3381- \(1/1\) awl:
3382- Ubuntu security engineers are investigating this issue.
3383+ Fixing requested USN-4539-1
3384+ No affected source packages are installed.
3385
3386- 1 package is still affected: awl
3387- .*✘.* USN-4539-1 is not resolved.
3388+ .*✔.* USN-4539-1 does not affect your system.
3389 """
3390- When I verify that running `pro fix USN-4539-1` `as non-root` exits `1`
3391+ When I run `pro fix USN-4539-1` as non-root
3392 Then stdout matches regexp:
3393 """
3394 USN-4539-1: AWL vulnerability
3395 Found CVEs:
3396 - https://ubuntu.com/security/CVE-2020-11728
3397
3398- 1 affected source package is installed: awl
3399- \(1/1\) awl:
3400- Ubuntu security engineers are investigating this issue.
3401+ Fixing requested USN-4539-1
3402+ No affected source packages are installed.
3403
3404- 1 package is still affected: awl
3405- .*✘.* USN-4539-1 is not resolved.
3406+ .*✔.* USN-4539-1 does not affect your system.
3407 """
3408 When I run `pro fix CVE-2020-28196` as non-root
3409 Then stdout matches regexp:
3410@@ -462,6 +679,7 @@ Feature: Ua fix command behaviour
3411 Found Launchpad bugs:
3412 - https://launchpad.net/bugs/1834494
3413
3414+ Fixing requested USN-4038-3
3415 1 affected source package is installed: bzip2
3416 \(1/1\) bzip2:
3417 A fix is available in Ubuntu standard updates.
3418diff --git a/features/i8n.feature b/features/i8n.feature
3419new file mode 100644
3420index 0000000..f87f994
3421--- /dev/null
3422+++ b/features/i8n.feature
3423@@ -0,0 +1,128 @@
3424+Feature: Pro supports multiple languages
3425+
3426+ @series.all
3427+ @uses.config.machine_type.lxd.container
3428+ @uses.config.contract_token
3429+ Scenario Outline: Pro client's commands run successfully
3430+ Given a `<release>` machine with ubuntu-advantage-tools installed
3431+ ## Change the locale
3432+ When I run `apt install language-pack-fr -y` with sudo
3433+ And I run `update-locale LANG=fr_FR.UTF-8` with sudo
3434+ And I reboot the machine
3435+ And I run `cat /etc/default/locale` as non-root
3436+ Then stdout matches regexp:
3437+ """
3438+ LANG=fr_FR.UTF-8
3439+ """
3440+ #Attach invalid token
3441+ When I verify that running `pro attach INVALID_TOKEN` `with sudo` exits `1`
3442+ Then stderr matches regexp:
3443+ """
3444+ Invalid token. See https://ubuntu.com/pro
3445+ """
3446+ When I run `lscpu` as non-root
3447+ Then stdout does not match regexp:
3448+ """
3449+ Architecture:
3450+ """
3451+ When I run `apt update` with sudo
3452+ Then stdout does not match regexp:
3453+ """
3454+ Hit
3455+ """
3456+ When I verify that running `pro attach INVALID_TOKEN` `as non-root` exits `1`
3457+ Then I will see the following on stderr:
3458+ """
3459+ This command must be run as root (try using sudo).
3460+ """
3461+ When I verify that running `pro attach invalid-token --format json` `with sudo` exits `1`
3462+ Then stdout is a json matching the `ua_operation` schema
3463+ And I will see the following on stdout:
3464+ """
3465+ {"_schema_version": "0.1", "errors": [{"message": "Invalid token. See https://ubuntu.com/pro", "message_code": "attach-invalid-token", "service": null, "type": "system"}], "failed_services": [], "needs_reboot": false, "processed_services": [], "result": "failure", "warnings": []}
3466+ """
3467+ When I attach `contract_token` with sudo
3468+ # Refresh command
3469+ When I run `pro refresh` with sudo
3470+ Then I will see the following on stdout:
3471+ """
3472+ Successfully processed your pro configuration.
3473+ Successfully refreshed your subscription.
3474+ Successfully updated Ubuntu Pro related APT and MOTD messages.
3475+ """
3476+ # auto-attach command
3477+ When I verify that running `pro auto-attach` `with sudo` exits `2`
3478+ Then stderr matches regexp:
3479+ """
3480+ This machine is already attached to 'UA Client Test'
3481+ To use a different subscription first run: sudo pro detach.
3482+ """
3483+ # status command
3484+ When I run `pro status --format json` as non-root
3485+ Then stdout is a json matching the `ua_status` schema
3486+ When I run `pro status --format yaml` as non-root
3487+ Then stdout is a yaml matching the `ua_status` schema
3488+ When I create the file `/tmp/machine-token-overlay.json` with the following:
3489+ """
3490+ {
3491+ "machineTokenInfo": {
3492+ "contractInfo": {
3493+ "effectiveTo": null
3494+ }
3495+ }
3496+ }
3497+ """
3498+ And I append the following on uaclient config:
3499+ """
3500+ features:
3501+ machine_token_overlay: "/tmp/machine-token-overlay.json"
3502+ """
3503+ And I run `pro status` with sudo
3504+ Then stdout contains substring:
3505+ """
3506+ Valid until: Unknown/Expired
3507+ """
3508+ # api command invalid endpoint
3509+ When I verify that running `pro api invalid.endpoint` `with sudo` exits `1`
3510+ Then stdout matches regexp:
3511+ """
3512+ {\"_schema_version\": \"v1\", \"data\": {\"meta\": {\"environment_vars\": \[]}}, \"errors\": \[{\"code\": \"api\-invalid\-endpoint", \"meta\": {}, \"title\": \"'invalid\.endpoint' is not a valid endpoint\"}], \"result\": \"failure\", \"version\": \".*\", \"warnings\": \[]}
3513+ """
3514+ When I verify that running `pro api u.pro.version.v1 --args extra=arg` `with sudo` exits `1`
3515+ Then stdout matches regexp:
3516+ """
3517+ {\"_schema_version\": \"v1\", \"data\": {\"meta\": {\"environment_vars\": \[]}}, \"errors\": \[{\"code\": \"api\-no\-argument\-for\-endpoint\", \"meta\": {}, \"title\": \"u\.pro\.version\.v1 accepts no arguments\"}], \"result\": \"failure\", \"version\": \".*\", \"warnings\": \[]}
3518+ """
3519+ # api command valid endpoint
3520+ When I run `pro api u.pro.version.v1` with sudo
3521+ Then stdout matches regexp:
3522+ """
3523+ {\"_schema_version\": \"v1\", \"data\": {\"attributes\": {\"installed_version\": \".*\"}, \"meta\": {\"environment_vars\": \[]}, \"type\": \"Version\"}, \"errors\": \[], \"result\": \"success\", \"version\": \".*\", \"warnings\": \[]}
3524+ """
3525+ When I run `UA_LOG_FILE=/tmp/some_file OTHER_ENVVAR=not_there pro api u.pro.version.v1` with sudo
3526+ Then stdout matches regexp:
3527+ """
3528+ {\"_schema_version\": \"v1\", \"data\": {\"attributes\": {\"installed_version\": \".*\"}, \"meta\": {\"environment_vars\": \[{\"name\": \"UA_LOG_FILE\", \"value\": \"\/tmp\/some_file\"}]}, \"type\": \"Version\"}, \"errors\": \[], \"result\": \"success\", \"version\": \".*\", \"warnings\": \[]}
3529+ """
3530+ When I run `ua api u.pro.attach.auto.should_auto_attach.v1` with sudo
3531+ Then stdout matches regexp:
3532+ """
3533+ {"_schema_version": "v1", "data": {"attributes": {"should_auto_attach": false}, "meta": {"environment_vars": \[\]}, "type": "ShouldAutoAttach"}, "errors": \[\], "result": "success", "version": ".*", "warnings": \[\]}
3534+ """
3535+ # version
3536+ When I run `pro version` as non-root
3537+ Then I will see the uaclient version on stdout
3538+ When I run `pro version` with sudo
3539+ Then I will see the uaclient version on stdout
3540+ When I run `pro --version` as non-root
3541+ Then I will see the uaclient version on stdout
3542+ When I run `pro --version` with sudo
3543+ Then I will see the uaclient version on stdout
3544+ Examples: ubuntu release
3545+ | release |
3546+ | bionic |
3547+ | focal |
3548+ | xenial |
3549+ | jammy |
3550+ | kinetic |
3551+ | lunar |
3552diff --git a/features/livepatch.feature b/features/livepatch.feature
3553index 31641b7..724fa1a 100644
3554--- a/features/livepatch.feature
3555+++ b/features/livepatch.feature
3556@@ -5,6 +5,10 @@ Feature: Livepatch
3557 @uses.config.machine_type.lxd.vm
3558 Scenario Outline: Attached livepatch status shows warning when on unsupported kernel
3559 Given a `<release>` machine with ubuntu-advantage-tools installed
3560+ Then I verify that no files exist matching `/home/ubuntu/.cache/ubuntu-pro/livepatch-kernel-support-cache.json`
3561+ When I run `pro status` as non-root
3562+ Then I verify that files exist matching `/home/ubuntu/.cache/ubuntu-pro/livepatch-kernel-support-cache.json`
3563+ Then I verify that no files exist matching `/run/ubuntu-advantage/livepatch-kernel-support-cache.json`
3564 When I run `pro status` with sudo
3565 Then stdout matches regexp:
3566 """
3567@@ -14,6 +18,7 @@ Feature: Livepatch
3568 """
3569 Supported livepatch kernels are listed here: https://ubuntu.com/security/livepatch/docs/kernels
3570 """
3571+ Then I verify that files exist matching `/run/ubuntu-advantage/livepatch-kernel-support-cache.json`
3572 When I attach `contract_token` with sudo
3573 When I run `pro status` with sudo
3574 Then stdout matches regexp:
3575@@ -23,7 +28,7 @@ Feature: Livepatch
3576 Then stdout matches regexp:
3577 """
3578 NOTICES
3579- The current kernel \(5.4.0-(\d+)-kvm, amd64\) is not supported by livepatch.
3580+ The current kernel \(5.4.0-(\d+)-kvm, x86_64\) is not supported by livepatch.
3581 Supported kernels are listed here: https://ubuntu.com/security/livepatch/docs/kernels
3582 Either switch to a supported kernel or `pro disable livepatch` to dismiss this warning.
3583
3584@@ -37,7 +42,7 @@ Feature: Livepatch
3585 Then stdout does not match regexp:
3586 """
3587 NOTICES
3588- The current kernel \(5.4.0-(\d+)-kvm, amd64\) is not supported by livepatch.
3589+ The current kernel \(5.4.0-(\d+)-kvm, x86_64\) is not supported by livepatch.
3590 Supported kernels are listed here: https://ubuntu.com/security/livepatch/docs/kernels
3591 Either switch to a supported kernel or `pro disable livepatch` to dismiss this warning.
3592
3593diff --git a/features/logs.feature b/features/logs.feature
3594index 80924af..b64facd 100644
3595--- a/features/logs.feature
3596+++ b/features/logs.feature
3597@@ -28,3 +28,62 @@ Feature: Logs in Json Array Formatter
3598 | kinetic |
3599 | jammy |
3600 | lunar |
3601+
3602+ @series.all
3603+ @uses.config.machine_type.lxd.container
3604+ Scenario Outline: Non-root user and root user log files are different
3605+ Given a `<release>` machine with ubuntu-advantage-tools installed
3606+ # Confirm user log file does not exist
3607+ When I verify `/var/log/ubuntu-advantage.log` is empty
3608+ Then I verify that no files exist matching `/home/ubuntu/.cache/ubuntu-pro/ubuntu-pro.log`
3609+ When I verify that running `pro status` `as non-root` exits `0`
3610+ Then I verify that files exist matching `/home/ubuntu/.cache/ubuntu-pro/ubuntu-pro.log`
3611+ When I verify `/var/log/ubuntu-advantage.log` is empty
3612+ And I run `cat /home/ubuntu/.cache/ubuntu-pro/ubuntu-pro.log` as non-root
3613+ Then stdout contains substring
3614+ """
3615+ Executed with sys.argv: ['/usr/bin/pro', 'status']
3616+ """
3617+ When I run `truncate -s 0 /home/ubuntu/.cache/ubuntu-pro/ubuntu-pro.log` with sudo
3618+ And I attach `contract_token` with sudo
3619+ And I verify `/home/ubuntu/.cache/ubuntu-pro/ubuntu-pro.log` is empty
3620+ And I run `cat /var/log/ubuntu-advantage.log` as non-root
3621+ Then stdout contains substring
3622+ """
3623+ Executed with sys.argv: ['/usr/bin/pro', 'attach'
3624+ """
3625+ Examples: ubuntu release
3626+ | release |
3627+ | xenial |
3628+ | bionic |
3629+ | focal |
3630+ | kinetic |
3631+ | jammy |
3632+ | lunar |
3633+
3634+ @series.all
3635+ @uses.config.machine_type.lxd.container
3636+ Scenario Outline: Non-root user log files included in collect logs
3637+ Given a `<release>` machine with ubuntu-advantage-tools installed
3638+ When i verify that running `pro status` `with sudo` exits `0`
3639+ And I verify that running `pro collect-logs` `with sudo` exits `0`
3640+ And I run `tar -tf ua_logs.tar.gz` as non-root
3641+ Then stdout does not contain substring
3642+ """
3643+ user0.log
3644+ """
3645+ When i verify that running `pro status` `as non-root` exits `0`
3646+ And I verify that running `pro collect-logs` `with sudo` exits `0`
3647+ And I run `tar -tf ua_logs.tar.gz` as non-root
3648+ Then stdout contains substring
3649+ """
3650+ user0.log
3651+ """
3652+ Examples: ubuntu release
3653+ | release |
3654+ | xenial |
3655+ | bionic |
3656+ | focal |
3657+ | kinetic |
3658+ | jammy |
3659+ | lunar |
3660diff --git a/features/proxy_config.feature b/features/proxy_config.feature
3661index 733c4ce..dd9d6df 100644
3662--- a/features/proxy_config.feature
3663+++ b/features/proxy_config.feature
3664@@ -582,7 +582,7 @@ Feature: Proxy configuration
3665 When I create the file `/var/lib/ubuntu-advantage/user-config.json` with the following:
3666 """
3667 {
3668- "ua_apt_http_proxy": "http://someuser:somepassword@$behave_var{machine-ip proxy}:3128"
3669+ "ua_apt_http_proxy": "http://someuser:somepassword@$behave_var{machine-ip proxy}:3128",
3670 "ua_apt_https_proxy": "http://someuser:somepassword@$behave_var{machine-ip proxy}:3128"
3671 }
3672 """
3673@@ -1133,7 +1133,7 @@ Feature: Proxy configuration
3674 When I create the file `/var/lib/ubuntu-advantage/user-config.json` with the following:
3675 """
3676 {
3677- "apt_http_proxy": "http://$behave_var{machine-ip proxy}:3128"
3678+ "apt_http_proxy": "http://$behave_var{machine-ip proxy}:3128",
3679 "apt_https_proxy": "http://$behave_var{machine-ip proxy}:3128"
3680 }
3681 """
3682@@ -1206,7 +1206,8 @@ Feature: Proxy configuration
3683 esm-apps +yes +enabled +Expanded Security Maintenance for Applications
3684 esm-infra +yes +enabled +Expanded Security Maintenance for Infrastructure
3685 """
3686- When I run `pro enable realtime-kernel --beta` `with sudo` and stdin `y`
3687+ When I run `pro disable livepatch --assume-yes` with sudo
3688+ When I run `pro enable realtime-kernel` `with sudo` and stdin `y`
3689 Then stdout matches regexp:
3690 """
3691 Installing Real-time kernel packages
3692diff --git a/features/realtime_kernel.feature b/features/realtime_kernel.feature
3693index ef0cfc0..78972a2 100644
3694--- a/features/realtime_kernel.feature
3695+++ b/features/realtime_kernel.feature
3696@@ -50,65 +50,298 @@ Feature: Enable command behaviour when attached to an Ubuntu Pro subscription
3697 When I attach `contract_token` with sudo and options `--no-auto-enable`
3698 Then I verify that running `pro enable realtime-kernel` `as non-root` exits `1`
3699 And I will see the following on stderr:
3700- """
3701- This command must be run as root (try using sudo).
3702- """
3703+ """
3704+ This command must be run as root (try using sudo).
3705+ """
3706 When I run `pro enable realtime-kernel` `with sudo` and stdin `y`
3707 Then stdout matches regexp:
3708- """
3709- One moment, checking your subscription first
3710- The Real-time kernel is an Ubuntu kernel with PREEMPT_RT patches integrated.
3711+ """
3712+ One moment, checking your subscription first
3713+ The Real-time kernel is an Ubuntu kernel with PREEMPT_RT patches integrated.
3714
3715- .*This will change your kernel. To revert to your original kernel, you will need
3716- to make the change manually..*
3717+ .*This will change your kernel. To revert to your original kernel, you will need
3718+ to make the change manually..*
3719
3720- Do you want to continue\? \[ default = Yes \]: \(Y/n\) Updating package lists
3721- Installing Real-time kernel packages
3722- Real-time kernel enabled
3723- A reboot is required to complete install.
3724- """
3725+ Do you want to continue\? \[ default = Yes \]: \(Y/n\) Updating package lists
3726+ Installing Real-time kernel packages
3727+ Real-time kernel enabled
3728+ A reboot is required to complete install.
3729+ """
3730 When I run `apt-cache policy ubuntu-realtime` as non-root
3731 Then stdout does not match regexp:
3732- """
3733- .*Installed: \(none\)
3734- """
3735+ """
3736+ .*Installed: \(none\)
3737+ """
3738 And stdout matches regexp:
3739- """
3740- \s* 500 https://esm.ubuntu.com/realtime/ubuntu <release>/main amd64 Packages
3741- """
3742+ """
3743+ \s* 500 https://esm.ubuntu.com/realtime/ubuntu <release>/main amd64 Packages
3744+ """
3745 When I verify that running `pro enable realtime-kernel` `with sudo` exits `1`
3746 Then stdout matches regexp
3747- """
3748- One moment, checking your subscription first
3749- Real-time kernel is already enabled.
3750- See: sudo pro status
3751- """
3752+ """
3753+ One moment, checking your subscription first
3754+ Real-time kernel is already enabled.
3755+ See: sudo pro status
3756+ """
3757 When I reboot the machine
3758 When I run `uname -r` as non-root
3759 Then stdout matches regexp:
3760- """
3761- realtime
3762- """
3763+ """
3764+ realtime
3765+ """
3766 When I run `pro disable realtime-kernel` `with sudo` and stdin `y`
3767 Then stdout matches regexp:
3768- """
3769- This will remove the boot order preference for the Real-time kernel and
3770- disable updates to the Real-time kernel.
3771+ """
3772+ This will remove the boot order preference for the Real-time kernel and
3773+ disable updates to the Real-time kernel.
3774
3775- This will NOT fully remove the kernel from your system.
3776+ This will NOT fully remove the kernel from your system.
3777
3778- After this operation is complete you must:
3779- - Ensure a different kernel is installed and configured to boot
3780- - Reboot into that kernel
3781- - Fully remove the realtime kernel packages from your system
3782- - This might look something like `apt remove linux\*realtime`,
3783- but you must ensure this is correct before running it.
3784- """
3785+ After this operation is complete you must:
3786+ - Ensure a different kernel is installed and configured to boot
3787+ - Reboot into that kernel
3788+ - Fully remove the realtime kernel packages from your system
3789+ - This might look something like `apt remove linux\*realtime`,
3790+ but you must ensure this is correct before running it.
3791+ """
3792 When I run `apt-cache policy ubuntu-realtime` as non-root
3793 Then stdout contains substring
3794- """
3795- Installed: (none)
3796- """
3797+ """
3798+ Installed: (none)
3799+ """
3800+ When I verify that running `pro enable realtime-kernel --access-only --variant nvidia-tegra` `with sudo` exits `1`
3801+ Then I will see the following on stderr:
3802+ """
3803+ Error: Cannot use --access-only together with --variant.
3804+ """
3805+ When I run `pro status` as non-root
3806+ Then stdout does not match regexp:
3807+ """
3808+ \* Service has variants
3809+ """
3810+ When I run `pro status --all` as non-root
3811+ Then stdout does not match regexp:
3812+ """
3813+ realtime-kernel yes +disabled +Ubuntu kernel with PREEMPT_RT patches integrated
3814+ ├ generic yes +disabled +Generic version of the RT kernel \(default\)
3815+ ├ intel-iotg yes +disabled +RT kernel optimized for Intel IOTG platform
3816+ └ nvidia-tegra yes +disabled +RT kernel optimized for NVIDIA Tegra platform
3817+ """
3818+ And stdout matches regexp:
3819+ """
3820+ realtime-kernel yes +disabled +Ubuntu kernel with PREEMPT_RT patches integrated
3821+ """
3822+
3823+ # Test one variant
3824+ # We need to disable this job before adding the overlay, because we might
3825+ # write the machine token to disk with the override content
3826+ When I run `pro config set update_messaging_timer=0` with sudo
3827+ And I set the machine token overlay to the following yaml
3828+ """
3829+ machineTokenInfo:
3830+ contractInfo:
3831+ resourceEntitlements:
3832+ - type: realtime-kernel
3833+ overrides:
3834+ - directives:
3835+ additionalPackages:
3836+ - ubuntu-intel-iot-realtime
3837+ selector:
3838+ variant: intel-iotg
3839+ affordances:
3840+ platformChecks: {"cpu_vendor_ids": ["intel"]}
3841+ """
3842+ When I run `pro enable realtime-kernel --assume-yes` with sudo
3843+ When I run `pro status --all` as non-root
3844+ Then stdout matches regexp:
3845+ """
3846+ realtime-kernel yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3847+ ├ generic yes +enabled +Generic version of the RT kernel \(default\)
3848+ └ intel-iotg yes +disabled +RT kernel optimized for Intel IOTG platform
3849+ """
3850+ When I run `pro enable realtime-kernel --variant intel-iotg` `with sudo` and stdin `y\ny\n`
3851+ Then stdout contains substring:
3852+ """
3853+ Real-time Intel IOTG Kernel cannot be enabled with Real-time kernel.
3854+ Disable Real-time kernel and proceed to enable Real-time Intel IOTG Kernel? (y/N)
3855+ """
3856+ When I run `pro status --all` as non-root
3857+ Then stdout matches regexp:
3858+ """
3859+ realtime-kernel yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3860+ ├ generic yes +disabled +Generic version of the RT kernel \(default\)
3861+ └ intel-iotg yes +enabled +RT kernel optimized for Intel IOTG platform
3862+ """
3863+ When I run `pro enable realtime-kernel --variant generic` `with sudo` and stdin `y\ny\n`
3864+ When I run `pro status --all` as non-root
3865+ Then stdout matches regexp:
3866+ """
3867+ realtime-kernel yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3868+ ├ generic yes +enabled +Generic version of the RT kernel \(default\)
3869+ └ intel-iotg yes +disabled +RT kernel optimized for Intel IOTG platform
3870+ """
3871+ When I run `pro enable realtime-kernel --variant intel-iotg` `with sudo` and stdin `y\ny\n`
3872+ When I run `pro status --all` as non-root
3873+ Then stdout matches regexp:
3874+ """
3875+ realtime-kernel yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3876+ ├ generic yes +disabled +Generic version of the RT kernel \(default\)
3877+ └ intel-iotg yes +enabled +RT kernel optimized for Intel IOTG platform
3878+ """
3879+ When I verify that running `pro enable realtime-kernel` `with sudo` exits `1`
3880+ Then stdout contains substring:
3881+ """
3882+ Real-time kernel is already enabled.
3883+ """
3884+ When I run `pro disable realtime-kernel --assume-yes` with sudo
3885+ When I run `apt-cache policy hello` as non-root
3886+ Then stdout contains substring:
3887+ """
3888+ Installed: (none)
3889+ """
3890+
3891+ # Test multiple variants
3892+ When I set the machine token overlay to the following yaml
3893+ """
3894+ machineTokenInfo:
3895+ contractInfo:
3896+ resourceEntitlements:
3897+ - type: realtime-kernel
3898+ overrides:
3899+ - directives:
3900+ additionalPackages:
3901+ - nvidia-prime
3902+ selector:
3903+ variant: nvidia-tegra
3904+ - directives:
3905+ additionalPackages:
3906+ - ubuntu-intel-iot-realtime
3907+ selector:
3908+ variant: intel-iotg
3909+ affordances:
3910+ platformChecks: {"cpu_vendor_ids": ["intel"]}
3911+ """
3912+ When I run `pro enable realtime-kernel --variant nvidia-tegra` `with sudo` and stdin `y`
3913+ Then stdout matches regexp:
3914+ """
3915+ One moment, checking your subscription first
3916+ The Real-time kernel is an Ubuntu kernel with PREEMPT_RT patches integrated.
3917+
3918+ .*This will change your kernel. To revert to your original kernel, you will need
3919+ to make the change manually..*
3920+
3921+ Do you want to continue\? \[ default = Yes \]: \(Y/n\) Updating package lists
3922+ Installing Real-time NVIDIA Tegra Kernel packages
3923+ Real-time NVIDIA Tegra Kernel enabled
3924+ """
3925+ When I run `pro status` as non-root
3926+ Then stdout matches regexp:
3927+ """
3928+ realtime-kernel\* yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3929+ usg +yes +disabled +Security compliance and audit tools
3930+
3931+ \* Service has variants
3932+ """
3933+ Then stdout contains substring:
3934+ """
3935+ For a list of all Ubuntu Pro services and variants, run 'pro status --all'
3936+ """
3937+ When I run `pro status --all` as non-root
3938+ Then stdout matches regexp:
3939+ """
3940+ realtime-kernel yes +enabled +Ubuntu kernel with PREEMPT_RT patches integrated
3941+ ├ generic yes +disabled +Generic version of the RT kernel \(default\)
3942+ ├ intel-iotg yes +disabled +RT kernel optimized for Intel IOTG platform
3943+ └ nvidia-tegra yes +enabled +RT kernel optimized for NVIDIA Tegra platform
3944+ """
3945+ When I verify that running `pro enable realtime-kernel --variant intel-iotg` `with sudo` and stdin `N` exits `1`
3946+ Then stdout matches regexp:
3947+ """
3948+ Real-time Intel IOTG Kernel cannot be enabled with Real-time NVIDIA Tegra Kernel.
3949+ Disable Real-time NVIDIA Tegra Kernel and proceed to enable Real-time Intel IOTG Kernel\? \(y/N\)
3950+ """
3951+ And stdout matches regexp:
3952+ """
3953+ Cannot enable Real-time Intel IOTG Kernel when Real-time NVIDIA Tegra Kernel is enabled.
3954+ """
3955+ When I run `pro help realtime-kernel` as non-root
3956+ Then I will see the following on stdout:
3957+ """
3958+ Name:
3959+ realtime-kernel
3960+
3961+ Entitled:
3962+ yes
3963+
3964+ Status:
3965+ enabled
3966+
3967+ Help:
3968+ The Real-time kernel is an Ubuntu kernel with PREEMPT_RT patches integrated.
3969+ It services latency-dependent use cases by providing deterministic response times.
3970+ The Real-time kernel meets stringent preemption specifications and is suitable for
3971+ telco applications and dedicated devices in industrial automation and robotics.
3972+ The Real-time kernel is currently incompatible with FIPS and Livepatch.
3973+
3974+ Variants:
3975+
3976+ * generic: Generic version of the RT kernel (default)
3977+ * intel-iotg: RT kernel optimized for Intel IOTG platform
3978+ * nvidia-tegra: RT kernel optimized for NVIDIA Tegra platform
3979+ """
3980+ When I run `pro disable realtime-kernel` `with sudo` and stdin `y`
3981+ Then stdout matches regexp:
3982+ """
3983+ This will remove the boot order preference for the Real-time kernel and
3984+ disable updates to the Real-time kernel.
3985+
3986+ This will NOT fully remove the kernel from your system.
3987+
3988+ After this operation is complete you must:
3989+ - Ensure a different kernel is installed and configured to boot
3990+ - Reboot into that kernel
3991+ - Fully remove the realtime kernel packages from your system
3992+ - This might look something like `apt remove linux\*realtime`,
3993+ but you must ensure this is correct before running it.
3994+ """
3995+ When I run `pro status` as non-root
3996+ Then stdout matches regexp:
3997+ """
3998+ realtime-kernel\* +yes +disabled +Ubuntu kernel with PREEMPT_RT patches integrated
3999+ """
4000+ When I run `pro status --all` as non-root
4001+ Then stdout matches regexp:
4002+ """
4003+ realtime-kernel yes +disabled +Ubuntu kernel with PREEMPT_RT patches integrated
4004+ ├ generic yes +disabled +Generic version of the RT kernel \(default\)
4005+ ├ intel-iotg yes +disabled +RT kernel optimized for Intel IOTG platform
4006+ └ nvidia-tegra yes +disabled +RT kernel optimized for NVIDIA Tegra platform
4007+ """
4008+ When I verify that running `pro enable realtime-kernel --variant nonexistent` `with sudo` exits `1`
4009+ Then I will see the following on stdout:
4010+ """
4011+ One moment, checking your subscription first
4012+ could not find entitlement named "nonexistent"
4013+ """
4014+ When I run `pro detach --assume-yes` with sudo
4015+ And I run `pro status` as non-root
4016+ Then stdout matches regexp:
4017+ """
4018+ realtime-kernel +yes +Ubuntu kernel with PREEMPT_RT patches integrated
4019+ """
4020+ When I run `pro status --all` as non-root
4021+ Then stdout matches regexp:
4022+ """
4023+ realtime-kernel +yes +Ubuntu kernel with PREEMPT_RT patches integrated
4024+ """
4025+ And stdout does not match regexp:
4026+ """
4027+ nvidia-tegra
4028+ """
4029+ And stdout does not match regexp:
4030+ """
4031+ intel-iotg
4032+ """
4033
4034 Examples: ubuntu release
4035 | release |
4036diff --git a/features/reboot_cmds.feature b/features/reboot_cmds.feature
4037new file mode 100644
4038index 0000000..13548b8
4039--- /dev/null
4040+++ b/features/reboot_cmds.feature
4041@@ -0,0 +1,48 @@
4042+@uses.config.contract_token
4043+Feature: Reboot Commands
4044+
4045+ @series.focal
4046+ @uses.config.machine_type.lxd.container
4047+ Scenario Outline: reboot-cmds removes fips package holds and updates packages
4048+ Given a `<release>` machine with ubuntu-advantage-tools installed
4049+ When I attach `contract_token` with sudo
4050+ When I run `apt install -y strongswan` with sudo
4051+ When I run `pro enable fips --assume-yes` with sudo
4052+ When I reboot the machine
4053+ When I run `pro status` with sudo
4054+ Then stdout matches regexp:
4055+ """
4056+ fips +yes +enabled
4057+ """
4058+ When I run `apt install -y --allow-downgrades strongswan=<old_version>` with sudo
4059+ When I run `apt-mark hold strongswan` with sudo
4060+ When I run `dpkg-reconfigure ubuntu-advantage-tools` with sudo
4061+ When I run `pro status` with sudo
4062+ Then stdout matches regexp:
4063+ """
4064+ NOTICES
4065+ Reboot to FIPS kernel required
4066+ """
4067+ When I reboot the machine
4068+ And I verify that running `systemctl status ua-reboot-cmds.service` `as non-root` exits `0,3`
4069+ Then stdout matches regexp:
4070+ """
4071+ .*status=0\/SUCCESS.*
4072+ """
4073+ When I run `pro status` with sudo
4074+ Then stdout does not match regexp:
4075+ """
4076+ NOTICES
4077+ """
4078+ When I run `apt-mark showholds` with sudo
4079+ Then I will see the following on stdout:
4080+ """
4081+ """
4082+ When I run `apt policy strongswan` with sudo
4083+ Then stdout contains substring:
4084+ """
4085+ *** <new_version> 1001
4086+ """
4087+ Examples: ubuntu release
4088+ | release | old_version | new_version |
4089+ | focal | 5.8.2-1ubuntu3.5 | 5.8.2-1ubuntu3.fips.3.1.2 |
4090diff --git a/features/retry_auto_attach.feature b/features/retry_auto_attach.feature
4091index 84540ef..68db599 100644
4092--- a/features/retry_auto_attach.feature
4093+++ b/features/retry_auto_attach.feature
4094@@ -190,7 +190,8 @@ Feature: auto-attach retries periodically on failures
4095 """
4096 Active: inactive (dead)
4097 """
4098- When I run `run-parts /etc/update-motd.d/` with sudo
4099+ # Workaround for livepatch issue LP #2015585
4100+ Then I verify that running `run-parts /etc/update-motd.d/` `with sudo` exits `0,1`
4101 Then stdout does not match regexp:
4102 """
4103 Failed to automatically attach to Ubuntu Pro services
4104@@ -345,7 +346,8 @@ Feature: auto-attach retries periodically on failures
4105 """
4106 Active: inactive (dead)
4107 """
4108- When I run `run-parts /etc/update-motd.d/` with sudo
4109+ # Workaround for livepatch issue LP #2015585
4110+ Then I verify that running `run-parts /etc/update-motd.d/` `with sudo` exits `0,1`
4111 Then stdout does not match regexp:
4112 """
4113 Failed to automatically attach to Ubuntu Pro services
4114diff --git a/features/security_status.feature b/features/security_status.feature
4115index 1ee472c..a27fe5b 100644
4116--- a/features/security_status.feature
4117+++ b/features/security_status.feature
4118@@ -136,10 +136,10 @@ Feature: Security status command behavior
4119 This machine is NOT attached to an Ubuntu Pro subscription.
4120
4121 Ubuntu Pro with 'esm-infra' enabled provides security updates for
4122- Main/Restricted packages until 2026 and has \d+ pending security update[s]?\.
4123+ Main/Restricted packages until 2026\. There (is|are) \d+ pending security update[s]?\.
4124
4125 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4126- Universe/Multiverse packages until 2026 and has \d+ pending security update[s]?\.
4127+ Universe/Multiverse packages until 2026\. There (is|are) \d+ pending security update[s]?\.
4128
4129 Try Ubuntu Pro with a free personal subscription on up to 5 machines.
4130 Learn more at https://ubuntu.com/pro
4131@@ -155,17 +155,18 @@ Feature: Security status command behavior
4132 and esm-infra is not enabled.
4133
4134 Ubuntu Pro with 'esm-infra' enabled provides security updates for
4135- Main/Restricted packages until 2026 and has \d+ pending security update[s]?\.
4136+ Main/Restricted packages until 2026\. There (is|are) \d+ pending security update[s]?\.
4137
4138 Run 'pro help esm-infra' to learn more
4139
4140- Package names in .*bold.* currently have an available update
4141- with 'esm-infra' enabled
4142- Packages:
4143+ Installed packages with an available esm-infra update:
4144+ (.|\n)+
4145+
4146+ Further installed packages covered by esm-infra:
4147 (.|\n)+
4148
4149 For example, run:
4150- apt-cache policy .+
4151+ apt-cache show .+
4152 to learn more about that package\.
4153 """
4154 When I verify root and non-root `pro security-status --esm-apps` calls have the same output
4155@@ -176,17 +177,18 @@ Feature: Security status command behavior
4156 +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4157
4158 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4159- Universe/Multiverse packages until 2026 and has \d+ pending security update[s]?\.
4160+ Universe/Multiverse packages until 2026\. There (is|are) \d+ pending security update[s]?\.
4161
4162 Run 'pro help esm-apps' to learn more
4163
4164- Package names in .*bold.* currently have an available update
4165- with 'esm-apps' enabled
4166- Packages:
4167+ Installed packages with an available esm-apps update:
4168+ (.|\n)+
4169+
4170+ Further installed packages covered by esm-apps:
4171 (.|\n)+
4172
4173 For example, run:
4174- apt-cache policy .+
4175+ apt-cache show .+
4176 to learn more about that package\.
4177 """
4178 When I attach `contract_token` with sudo
4179@@ -207,10 +209,10 @@ Feature: Security status command behavior
4180 This machine is attached to an Ubuntu Pro subscription.
4181
4182 Main/Restricted packages are receiving security updates from
4183- Ubuntu Pro with 'esm-infra' enabled until 2026\.
4184+ Ubuntu Pro with 'esm-infra' enabled until 2026\. There (is|are) \d+ pending security update[s]?\.
4185
4186 Universe/Multiverse packages are receiving security updates from
4187- Ubuntu Pro with 'esm-apps' enabled until 2026\.
4188+ Ubuntu Pro with 'esm-apps' enabled until 2026\. There (is|are) \d+ pending security update[s]?\.
4189 """
4190 When I verify root and non-root `pro security-status --esm-infra` calls have the same output
4191 And I run `pro security-status --esm-infra` as non-root
4192@@ -220,17 +222,18 @@ Feature: Security status command behavior
4193 +\d+ packages from Ubuntu Main/Restricted repository
4194
4195 Main/Restricted packages are receiving security updates from
4196- Ubuntu Pro with 'esm-infra' enabled until 2026\.
4197+ Ubuntu Pro with 'esm-infra' enabled until 2026\. There (is|are) \d+ pending security update[s]?\.
4198
4199 Run 'pro help esm-infra' to learn more
4200
4201- Package names in .*bold.* currently have an available update
4202- with 'esm-infra' enabled
4203- Packages:
4204+ Installed packages with an available esm-infra update:
4205+ (.|\n)+
4206+
4207+ Further installed packages covered by esm-infra:
4208 (.|\n)+
4209
4210 For example, run:
4211- apt-cache policy .+
4212+ apt-cache show .+
4213 to learn more about that package\.
4214 """
4215 When I verify root and non-root `pro security-status --esm-apps` calls have the same output
4216@@ -241,17 +244,18 @@ Feature: Security status command behavior
4217 +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4218
4219 Universe/Multiverse packages are receiving security updates from
4220- Ubuntu Pro with 'esm-apps' enabled until 2026\.
4221+ Ubuntu Pro with 'esm-apps' enabled until 2026\. There (is|are) \d+ pending security update[s]?\.
4222
4223 Run 'pro help esm-apps' to learn more
4224
4225- Package names in .*bold.* currently have an available update
4226- with 'esm-apps' enabled
4227- Packages:
4228+ Installed packages with an available esm-apps update:
4229+ (.|\n)+
4230+
4231+ Further installed packages covered by esm-apps:
4232 (.|\n)+
4233
4234 For example, run:
4235- apt-cache policy .+
4236+ apt-cache show .+
4237 to learn more about that package\.
4238 """
4239 When I run `apt upgrade -y` with sudo
4240@@ -300,10 +304,12 @@ Feature: Security status command behavior
4241
4242 Ubuntu Pro with 'esm-infra' enabled provides security updates for
4243 Main/Restricted packages until 2026.
4244+
4245 Enable esm-infra with: pro enable esm-infra
4246
4247 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4248 Universe/Multiverse packages until 2026.
4249+
4250 Enable esm-apps with: pro enable esm-apps
4251 """
4252 When I verify root and non-root `pro security-status --thirdparty` calls have the same output
4253@@ -320,7 +326,7 @@ Feature: Security status command behavior
4254 (.|\n)+
4255
4256 For example, run:
4257- apt-cache policy .+
4258+ apt-cache show .+
4259 to learn more about that package\.
4260 """
4261 When I verify root and non-root `pro security-status --unavailable` calls have the same output
4262@@ -338,7 +344,7 @@ Feature: Security status command behavior
4263 (.|\n)+
4264
4265 For example, run:
4266- apt-cache policy .+
4267+ apt-cache show .+
4268 to learn more about that package\.
4269 """
4270 When I verify root and non-root `pro security-status --esm-infra` calls have the same output
4271@@ -356,14 +362,8 @@ Feature: Security status command behavior
4272
4273 Run 'pro help esm-infra' to learn more
4274
4275- Package names in .*bold.* currently have an available update
4276- with 'esm-infra' enabled
4277- Packages:
4278+ Installed packages covered by esm-infra:
4279 (.|\n)+
4280-
4281- For example, run:
4282- apt-cache policy .+
4283- to learn more about that package\.
4284 """
4285 When I verify root and non-root `pro security-status --esm-apps` calls have the same output
4286 And I run `pro security-status --esm-apps` as non-root
4287@@ -377,14 +377,8 @@ Feature: Security status command behavior
4288
4289 Run 'pro help esm-apps' to learn more
4290
4291- Package names in .*bold.* currently have an available update
4292- with 'esm-apps' enabled
4293- Packages:
4294+ Installed packages covered by esm-apps:
4295 (.|\n)+
4296-
4297- For example, run:
4298- apt-cache policy .+
4299- to learn more about that package\.
4300 """
4301 When I verify that running `pro security-status --thirdparty --unavailable` `as non-root` exits `2`
4302 Then I will see the following on stderr
4303@@ -393,6 +387,70 @@ Feature: Security status command behavior
4304 [--thirdparty | --unavailable | --esm-infra | --esm-apps]
4305 argument --unavailable: not allowed with argument --thirdparty
4306 """
4307+ When I run `rm /var/lib/apt/periodic/update-success-stamp` with sudo
4308+ And I run `pro security-status` as non-root
4309+ Then stdout matches regexp:
4310+ """
4311+ \d+ packages installed:
4312+ +\d+ package[s]? from Ubuntu Main/Restricted repository
4313+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4314+ +\d+ package[s]? from a third party
4315+ +\d+ package[s]? no longer available for download
4316+
4317+ To get more information about the packages, run
4318+ pro security-status --help
4319+ for a list of available options\.
4320+
4321+ The system apt cache may be outdated\. Make sure to run
4322+ sudo apt-get update
4323+ to get the latest package information from apt\.
4324+
4325+ This machine is NOT receiving security patches because the LTS period has ended
4326+ and esm-infra is not enabled.
4327+ This machine is attached to an Ubuntu Pro subscription.
4328+
4329+ Ubuntu Pro with 'esm-infra' enabled provides security updates for
4330+ Main/Restricted packages until 2026.
4331+
4332+ Enable esm-infra with: pro enable esm-infra
4333+
4334+ Ubuntu Pro with 'esm-apps' enabled provides security updates for
4335+ Universe/Multiverse packages until 2026.
4336+
4337+ Enable esm-apps with: pro enable esm-apps
4338+ """
4339+ When I run `touch -d '-2 days' /var/lib/apt/periodic/update-success-stamp` with sudo
4340+ And I run `pro security-status` as non-root
4341+ Then stdout matches regexp:
4342+ """
4343+ \d+ packages installed:
4344+ +\d+ package[s]? from Ubuntu Main/Restricted repository
4345+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4346+ +\d+ package[s]? from a third party
4347+ +\d+ package[s]? no longer available for download
4348+
4349+ To get more information about the packages, run
4350+ pro security-status --help
4351+ for a list of available options\.
4352+
4353+ The system apt information was updated 2 day\(s\) ago\. Make sure to run
4354+ sudo apt-get update
4355+ to get the latest package information from apt\.
4356+
4357+ This machine is NOT receiving security patches because the LTS period has ended
4358+ and esm-infra is not enabled.
4359+ This machine is attached to an Ubuntu Pro subscription.
4360+
4361+ Ubuntu Pro with 'esm-infra' enabled provides security updates for
4362+ Main/Restricted packages until 2026.
4363+
4364+ Enable esm-infra with: pro enable esm-infra
4365+
4366+ Ubuntu Pro with 'esm-apps' enabled provides security updates for
4367+ Universe/Multiverse packages until 2026.
4368+
4369+ Enable esm-apps with: pro enable esm-apps
4370+ """
4371
4372 @series.focal
4373 @uses.config.machine_type.lxd.container
4374@@ -423,7 +481,7 @@ Feature: Security status command behavior
4375 Main/Restricted packages until 2030.
4376
4377 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4378- Universe/Multiverse packages until 2030 and has \d+ pending security update[s]?\.
4379+ Universe/Multiverse packages until 2030\. There (is|are) \d+ pending security update[s]?\.
4380
4381 Try Ubuntu Pro with a free personal subscription on up to 5 machines.
4382 Learn more at https://ubuntu.com/pro
4383@@ -451,17 +509,18 @@ Feature: Security status command behavior
4384 +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4385
4386 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4387- Universe/Multiverse packages until 2030 and has \d+ pending security update[s]?\.
4388+ Universe/Multiverse packages until 2030\. There (is|are) \d+ pending security update[s]?\.
4389
4390 Run 'pro help esm-apps' to learn more
4391
4392- Package names in .*bold.* currently have an available update
4393- with 'esm-apps' enabled
4394- Packages:
4395+ Installed packages with an available esm-apps update:
4396+ (.|\n)+
4397+
4398+ Further installed packages covered by esm-apps:
4399 (.|\n)+
4400
4401 For example, run:
4402- apt-cache policy .+
4403+ apt-cache show .+
4404 to learn more about that package\.
4405 """
4406 When I attach `contract_token` with sudo
4407@@ -485,7 +544,7 @@ Feature: Security status command behavior
4408 Ubuntu Pro with 'esm-infra' enabled until 2030.
4409
4410 Universe/Multiverse packages are receiving security updates from
4411- Ubuntu Pro with 'esm-apps' enabled until 2030\.
4412+ Ubuntu Pro with 'esm-apps' enabled until 2030\. There (is|are) \d+ pending security update[s]?\.
4413 """
4414 When I verify root and non-root `pro security-status --esm-infra` calls have the same output
4415 And I run `pro security-status --esm-infra` as non-root
4416@@ -507,17 +566,18 @@ Feature: Security status command behavior
4417 +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4418
4419 Universe/Multiverse packages are receiving security updates from
4420- Ubuntu Pro with 'esm-apps' enabled until 2030\.
4421+ Ubuntu Pro with 'esm-apps' enabled until 2030\. There (is|are) \d+ pending security update[s]?\.
4422
4423 Run 'pro help esm-apps' to learn more
4424
4425- Package names in .*bold.* currently have an available update
4426- with 'esm-apps' enabled
4427- Packages:
4428+ Installed packages with an available esm-apps update:
4429+ (.|\n)+
4430+
4431+ Further installed packages covered by esm-apps:
4432 (.|\n)+
4433
4434 For example, run:
4435- apt-cache policy .+
4436+ apt-cache show .+
4437 to learn more about that package\.
4438 """
4439 When I run `apt upgrade -y` with sudo
4440@@ -565,10 +625,12 @@ Feature: Security status command behavior
4441
4442 Ubuntu Pro with 'esm-infra' enabled provides security updates for
4443 Main/Restricted packages until 2030.
4444+
4445 Enable esm-infra with: pro enable esm-infra
4446
4447 Ubuntu Pro with 'esm-apps' enabled provides security updates for
4448 Universe/Multiverse packages until 2030.
4449+
4450 Enable esm-apps with: pro enable esm-apps
4451 """
4452 When I verify root and non-root `pro security-status --thirdparty` calls have the same output
4453@@ -585,7 +647,7 @@ Feature: Security status command behavior
4454 (.|\n)+
4455
4456 For example, run:
4457- apt-cache policy .+
4458+ apt-cache show .+
4459 to learn more about that package\.
4460 """
4461 When I verify root and non-root `pro security-status --unavailable` calls have the same output
4462@@ -603,7 +665,7 @@ Feature: Security status command behavior
4463 (.|\n)+
4464
4465 For example, run:
4466- apt-cache policy .+
4467+ apt-cache show .+
4468 to learn more about that package\.
4469 """
4470 When I verify root and non-root `pro security-status --esm-infra` calls have the same output
4471@@ -633,14 +695,8 @@ Feature: Security status command behavior
4472
4473 Run 'pro help esm-apps' to learn more
4474
4475- Package names in .*bold.* currently have an available update
4476- with 'esm-apps' enabled
4477- Packages:
4478+ Installed packages covered by esm-apps:
4479 (.|\n)+
4480-
4481- For example, run:
4482- apt-cache policy .+
4483- to learn more about that package\.
4484 """
4485 When I verify that running `pro security-status --thirdparty --unavailable` `as non-root` exits `2`
4486 Then I will see the following on stderr
4487@@ -649,6 +705,70 @@ Feature: Security status command behavior
4488 [--thirdparty | --unavailable | --esm-infra | --esm-apps]
4489 argument --unavailable: not allowed with argument --thirdparty
4490 """
4491+ When I run `rm /var/lib/apt/periodic/update-success-stamp` with sudo
4492+ And I run `pro security-status` as non-root
4493+ Then stdout matches regexp:
4494+ """
4495+ \d+ packages installed:
4496+ +\d+ package[s]? from Ubuntu Main/Restricted repository
4497+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4498+ +\d+ package[s]? from a third party
4499+ +\d+ package[s]? no longer available for download
4500+
4501+ To get more information about the packages, run
4502+ pro security-status --help
4503+ for a list of available options\.
4504+
4505+ The system apt cache may be outdated\. Make sure to run
4506+ sudo apt-get update
4507+ to get the latest package information from apt\.
4508+
4509+ This machine is receiving security patching for Ubuntu Main/Restricted
4510+ repository until 2025.
4511+ This machine is attached to an Ubuntu Pro subscription.
4512+
4513+ Ubuntu Pro with 'esm-infra' enabled provides security updates for
4514+ Main/Restricted packages until 2030.
4515+
4516+ Enable esm-infra with: pro enable esm-infra
4517+
4518+ Ubuntu Pro with 'esm-apps' enabled provides security updates for
4519+ Universe/Multiverse packages until 2030.
4520+
4521+ Enable esm-apps with: pro enable esm-apps
4522+ """
4523+ When I run `touch -d '-2 days' /var/lib/apt/periodic/update-success-stamp` with sudo
4524+ And I run `pro security-status` as non-root
4525+ Then stdout matches regexp:
4526+ """
4527+ \d+ packages installed:
4528+ +\d+ package[s]? from Ubuntu Main/Restricted repository
4529+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4530+ +\d+ package[s]? from a third party
4531+ +\d+ package[s]? no longer available for download
4532+
4533+ To get more information about the packages, run
4534+ pro security-status --help
4535+ for a list of available options\.
4536+
4537+ The system apt information was updated 2 day\(s\) ago\. Make sure to run
4538+ sudo apt-get update
4539+ to get the latest package information from apt\.
4540+
4541+ This machine is receiving security patching for Ubuntu Main/Restricted
4542+ repository until 2025.
4543+ This machine is attached to an Ubuntu Pro subscription.
4544+
4545+ Ubuntu Pro with 'esm-infra' enabled provides security updates for
4546+ Main/Restricted packages until 2030.
4547+
4548+ Enable esm-infra with: pro enable esm-infra
4549+
4550+ Ubuntu Pro with 'esm-apps' enabled provides security updates for
4551+ Universe/Multiverse packages until 2030.
4552+
4553+ Enable esm-apps with: pro enable esm-apps
4554+ """
4555
4556 @series.kinetic
4557 @uses.config.machine_type.lxd.container
4558@@ -695,3 +815,47 @@ Feature: Security status command behavior
4559
4560 Ubuntu Pro is not available for non-LTS releases\.
4561 """
4562+ When I run `rm /var/lib/apt/periodic/update-success-stamp` with sudo
4563+ And I run `pro security-status` as non-root
4564+ Then stdout matches regexp:
4565+ """
4566+ \d+ packages installed:
4567+ +\d+ packages from Ubuntu Main/Restricted repository
4568+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4569+ +\d+ package[s]? from a third party
4570+ +\d+ package[s]? no longer available for download
4571+
4572+ To get more information about the packages, run
4573+ pro security-status --help
4574+ for a list of available options\.
4575+
4576+ The system apt cache may be outdated\. Make sure to run
4577+ sudo apt-get update
4578+ to get the latest package information from apt\.
4579+
4580+ Main/Restricted packages receive updates until 7/2023\.
4581+
4582+ Ubuntu Pro is not available for non-LTS releases\.
4583+ """
4584+ When I run `touch -d '-2 days' /var/lib/apt/periodic/update-success-stamp` with sudo
4585+ And I run `pro security-status` as non-root
4586+ Then stdout matches regexp:
4587+ """
4588+ \d+ packages installed:
4589+ +\d+ packages from Ubuntu Main/Restricted repository
4590+ +\d+ package[s]? from Ubuntu Universe/Multiverse repository
4591+ +\d+ package[s]? from a third party
4592+ +\d+ package[s]? no longer available for download
4593+
4594+ To get more information about the packages, run
4595+ pro security-status --help
4596+ for a list of available options\.
4597+
4598+ The system apt information was updated 2 day\(s\) ago\. Make sure to run
4599+ sudo apt-get update
4600+ to get the latest package information from apt\.
4601+
4602+ Main/Restricted packages receive updates until 7/2023\.
4603+
4604+ Ubuntu Pro is not available for non-LTS releases\.
4605+ """
4606diff --git a/features/steps/airgap.py b/features/steps/airgap.py
4607index 004f875..85f2ddf 100644
4608--- a/features/steps/airgap.py
4609+++ b/features/steps/airgap.py
4610@@ -10,7 +10,7 @@ from features.steps.shell import when_i_run_command
4611
4612 @when("I download the service credentials on the `{machine_name}` machine")
4613 def download_service_credentials(context, machine_name):
4614- token = context.config.contract_token
4615+ token = context.pro_config.contract_token
4616 when_i_run_command(
4617 context,
4618 "get-resource-tokens {}".format(token),
4619@@ -112,7 +112,7 @@ def serve_apt_mirror(context, service, port, machine_name):
4620 "I create the contract config overrides file for `{service_list}` on the `{machine_name}` machine" # noqa
4621 )
4622 def create_contract_overrides(context, service_list, machine_name):
4623- token = context.config.contract_token
4624+ token = context.pro_config.contract_token
4625 config_override = {token: {}} # type: Dict[str, Any]
4626
4627 for service in service_list.split(","):
4628diff --git a/features/steps/attach.py b/features/steps/attach.py
4629index ad6d7de..921bbc4 100644
4630--- a/features/steps/attach.py
4631+++ b/features/steps/attach.py
4632@@ -23,7 +23,7 @@ def when_i_attach_staging_token_with_options(
4633 def when_i_attach_staging_token(
4634 context, token_type, user_spec, verify_return=True, options=""
4635 ):
4636- token = getattr(context.config, token_type)
4637+ token = getattr(context.pro_config, token_type)
4638 if (
4639 token_type == "contract_token_staging"
4640 or token_type == "contract_token_staging_expired"
4641@@ -47,7 +47,9 @@ def when_i_attempt_to_attach_staging_token(context, token_type, user_spec):
4642 "I verify that running attach `{spec}` with json response exits `{exit_codes}`" # noqa
4643 )
4644 def when_i_verify_attach_with_json_response(context, spec, exit_codes):
4645- cmd = "pro attach {} --format json".format(context.config.contract_token)
4646+ cmd = "pro attach {} --format json".format(
4647+ context.pro_config.contract_token
4648+ )
4649 then_i_verify_that_running_cmd_with_spec_exits_with_codes(
4650 context=context, cmd_name=cmd, spec=spec, exit_codes=exit_codes
4651 )
4652@@ -59,7 +61,7 @@ def when_i_verify_attach_with_json_response(context, spec, exit_codes):
4653 def when_i_verify_attach_expired_token_with_json_response(context, spec):
4654 change_contract_endpoint_to_staging(context, user_spec="with sudo")
4655 cmd = "pro attach {} --format json".format(
4656- context.config.contract_token_staging_expired
4657+ context.pro_config.contract_token_staging_expired
4658 )
4659 then_i_verify_that_running_cmd_with_spec_exits_with_codes(
4660 context=context, cmd_name=cmd, spec=spec, exit_codes=ERROR_CODE
4661diff --git a/features/steps/files.py b/features/steps/files.py
4662index 8b34375..f4e8545 100644
4663--- a/features/steps/files.py
4664+++ b/features/steps/files.py
4665@@ -36,8 +36,11 @@ def when_i_add_this_text_on_file_above_line(
4666 )
4667
4668
4669+@when("I verify `{file_name}` is empty")
4670 @when("I verify `{file_name}` is empty on `{machine_name}` machine")
4671-def when_i_verify_file_is_empty_on_machine(context, file_name, machine_name):
4672+def when_i_verify_file_is_empty_on_machine(
4673+ context, file_name, machine_name=SUT
4674+):
4675 command = 'sh -c "cat {} | wc -l"'.format(file_name)
4676 when_i_run_command(
4677 context, command, user_spec="with sudo", machine_name=machine_name
4678@@ -97,7 +100,7 @@ def when_i_replace_string_in_file(context, original, filename, new):
4679 def when_i_replace_string_in_file_with_token(
4680 context, original, filename, token_name
4681 ):
4682- token = getattr(context.config, token_name)
4683+ token = getattr(context.pro_config, token_name)
4684 when_i_replace_string_in_file(context, original, filename, token)
4685
4686
4687diff --git a/features/steps/fix.py b/features/steps/fix.py
4688index a799d79..a9a77fe 100644
4689--- a/features/steps/fix.py
4690+++ b/features/steps/fix.py
4691@@ -9,7 +9,7 @@ from features.steps.shell import when_i_run_command
4692
4693 @when("I fix `{issue}` by attaching to a subscription with `{token_type}`")
4694 def when_i_fix_a_issue_by_attaching(context, issue, token_type):
4695- token = getattr(context.config, token_type)
4696+ token = getattr(context.pro_config, token_type)
4697
4698 if (
4699 token_type == "contract_token_staging"
4700@@ -40,7 +40,7 @@ def when_i_fix_a_issue_by_enabling_service(context, issue):
4701
4702 @when("I fix `{issue}` by updating expired token")
4703 def when_i_fix_a_issue_by_updating_expired_token(context, issue):
4704- token = getattr(context.config, "contract_token")
4705+ token = getattr(context.pro_config, "contract_token")
4706 when_i_run_command(
4707 context=context,
4708 command="pro fix {}".format(issue),
4709diff --git a/features/steps/machines.py b/features/steps/machines.py
4710index c06555d..4101649 100644
4711--- a/features/steps/machines.py
4712+++ b/features/steps/machines.py
4713@@ -40,7 +40,7 @@ def given_a_machine(
4714
4715 inbound_ports = ports.split(",") if ports is not None else None
4716
4717- is_pro = "pro" in context.config.machine_type
4718+ is_pro = "pro" in context.pro_config.machine_type
4719 pro_user_data = (
4720 "bootcmd:\n"
4721 """ - "cloud-init-per once disable-auto-attach printf '\\nfeatures: {disable_auto_attach: true}\\n' >> /etc/ubuntu-advantage/uaclient.conf"\n""" # noqa: E501
4722@@ -53,10 +53,10 @@ def given_a_machine(
4723 if user_data is not None:
4724 user_data_to_use += user_data
4725
4726- instance = context.config.cloud_manager.launch(
4727+ instance = context.pro_config.cloud_manager.launch(
4728 series=series,
4729 instance_name=instance_name,
4730- ephemeral=context.config.ephemeral_instance,
4731+ ephemeral=context.pro_config.ephemeral_instance,
4732 image_name=context.snapshots.get(snapshot_name, None),
4733 inbound_ports=inbound_ports,
4734 user_data=user_data_to_use,
4735@@ -69,7 +69,7 @@ def given_a_machine(
4736 if cleanup:
4737
4738 def cleanup_instance():
4739- if not context.config.destroy_instances:
4740+ if not context.pro_config.destroy_instances:
4741 logging.info(
4742 "--- Leaving instance running: {}".format(
4743 context.machines[machine_name].instance.name
4744@@ -92,7 +92,7 @@ def given_a_machine(
4745 @when("I take a snapshot of the machine")
4746 def when_i_take_a_snapshot(context, machine_name=SUT, cleanup=True):
4747 inst = context.machines[machine_name].instance
4748- snapshot = context.config.cloud_manager.api.snapshot(inst)
4749+ snapshot = context.pro_config.cloud_manager.api.snapshot(inst)
4750
4751 context.snapshots[machine_name] = snapshot
4752
4753@@ -100,7 +100,7 @@ def when_i_take_a_snapshot(context, machine_name=SUT, cleanup=True):
4754
4755 def cleanup_snapshot() -> None:
4756 try:
4757- context.config.cloud_manager.api.delete_image(
4758+ context.pro_config.cloud_manager.api.delete_image(
4759 context.snapshots[machine_name]
4760 )
4761 except RuntimeError as e:
4762@@ -115,13 +115,13 @@ def when_i_take_a_snapshot(context, machine_name=SUT, cleanup=True):
4763
4764 @given("a `{series}` machine with ubuntu-advantage-tools installed")
4765 def given_a_sut_machine(context, series):
4766- if context.config.install_from == InstallationSource.LOCAL:
4767+ if context.pro_config.install_from == InstallationSource.LOCAL:
4768 # build right away, this will cache the built debs for later use
4769 # building early means we catch build errors before investing in
4770 # launching instances
4771 build_debs(series)
4772
4773- if context.config.snapshot_strategy:
4774+ if context.pro_config.snapshot_strategy:
4775 if "builder" not in context.snapshots:
4776 given_a_machine(
4777 context, series, machine_name="builder", cleanup=False
4778diff --git a/features/steps/output.py b/features/steps/output.py
4779index abb1f7f..788e939 100644
4780--- a/features/steps/output.py
4781+++ b/features/steps/output.py
4782@@ -65,6 +65,13 @@ def then_stream_contains_substring(context, stream):
4783 assert_that(content, contains_string(text))
4784
4785
4786+@then("{stream} does not contain substring")
4787+def then_stream_not_contains_substring(context, stream):
4788+ content = getattr(context.process, stream).strip()
4789+ text = process_template_vars(context, context.text)
4790+ assert_that(content, not_(contains_string(text)))
4791+
4792+
4793 @then("I will see the following on stderr")
4794 def then_i_will_see_on_stderr(context):
4795 text = process_template_vars(context, context.text)
4796diff --git a/features/steps/packages.py b/features/steps/packages.py
4797index a523706..2239e51 100644
4798--- a/features/steps/packages.py
4799+++ b/features/steps/packages.py
4800@@ -3,16 +3,9 @@ import re
4801 from behave import then, when
4802 from hamcrest import assert_that, contains_string, matches_regexp
4803
4804-from features.steps.files import when_i_create_file_with_content
4805 from features.steps.shell import when_i_run_command
4806 from features.util import SUT
4807
4808-APT_REPO_ENTRY = (
4809- "deb [trusted=yes] "
4810- "http://proclientdummyrepo.s3-website.us-east-2.amazonaws.com/"
4811- "actual_ppa/ unstable main"
4812-)
4813-
4814
4815 @when("I apt install `{package_name}`")
4816 @when("I apt install `{package_name}` on the `{machine_name}` machine")
4817@@ -108,27 +101,33 @@ def verify_packages_are_installed_from_apt_source(
4818 @when("I install third-party / unknown packages in the machine")
4819 def when_i_install_packages(context):
4820 # Dummy packages are installed to serve as third-party and unknown
4821- # packages for the tests. They live happy and joyful lives in a s3 bucket.
4822+ # packages for the tests. Those packages are in Launchpad PPAs
4823+ # owned by the uaclient team.
4824 # Many APT updates just to make sure we are up to date
4825
4826- # Unknown package - installed directly, no external reference
4827+ # Unknown package - we remove the PPA afterwards so there is no
4828+ # external references for the deb.
4829 when_i_run_command(
4830 context,
4831- (
4832- "curl -L "
4833- "http://proclientdummyrepo.s3-website.us-east-2.amazonaws.com/"
4834- "unknown_deb/pro-dummy-unknown_1.2.3_all.deb "
4835- "-o /tmp/unknown.deb"
4836- ),
4837+ "add-apt-repository -y ppa:ua-client/pro-client-ci-test-unknown",
4838 "with sudo",
4839 )
4840+ when_i_run_command(context, "apt-get update", "with sudo")
4841 when_i_run_command(
4842- context, "apt-get install -y /tmp/unknown.deb", "with sudo"
4843+ context, "apt-get install -y pro-dummy-unknown", "with sudo"
4844+ )
4845+ # Why no remove-apt-repository?
4846+ when_i_run_command(
4847+ context,
4848+ "add-apt-repository -y -r ppa:ua-client/pro-client-ci-test-unknown",
4849+ "with sudo",
4850 )
4851
4852 # PPA to install the third-party package
4853- when_i_create_file_with_content(
4854- context, "/etc/apt/sources.list.d/prodummy.list", text=APT_REPO_ENTRY
4855+ when_i_run_command(
4856+ context,
4857+ "add-apt-repository -y ppa:ua-client/pro-client-ci-test-thirdparty",
4858+ "with sudo",
4859 )
4860 when_i_run_command(context, "apt-get update", "with sudo")
4861 when_i_run_command(
4862diff --git a/features/steps/shell.py b/features/steps/shell.py
4863index aad147b..6e04988 100644
4864--- a/features/steps/shell.py
4865+++ b/features/steps/shell.py
4866@@ -43,10 +43,12 @@ def when_i_run_command(
4867 machine_name=SUT,
4868 ):
4869 command = process_template_vars(context, command)
4870-
4871 prefix = get_command_prefix_for_user_spec(user_spec)
4872-
4873 full_cmd = prefix + shlex.split(command)
4874+
4875+ if stdin is not None:
4876+ stdin = stdin.replace("\\n", "\n")
4877+
4878 result = context.machines[machine_name].instance.execute(
4879 full_cmd, stdin=stdin
4880 )
4881diff --git a/features/steps/status.py b/features/steps/status.py
4882index 3fada5e..4c606da 100644
4883--- a/features/steps/status.py
4884+++ b/features/steps/status.py
4885@@ -5,7 +5,7 @@ from features.steps.shell import when_i_run_command
4886
4887 @when("I do a preflight check for `{contract_token}` {user_spec}")
4888 def when_i_preflight(context, contract_token, user_spec, verify_return=True):
4889- token = getattr(context.config, contract_token, "invalid_token")
4890+ token = getattr(context.pro_config, contract_token, "invalid_token")
4891 command = "pro status --simulate-with-token {}".format(token)
4892 if user_spec == "with the all flag":
4893 command += " --all"
4894diff --git a/features/steps/ubuntu_advantage_tools.py b/features/steps/ubuntu_advantage_tools.py
4895index 2b6bf16..827e89b 100644
4896--- a/features/steps/ubuntu_advantage_tools.py
4897+++ b/features/steps/ubuntu_advantage_tools.py
4898@@ -14,8 +14,8 @@ from features.util import SUT, InstallationSource, build_debs
4899 def when_i_install_uat(context, machine_name=SUT):
4900 instance = context.machines[machine_name].instance
4901 series = context.machines[machine_name].series
4902- is_pro = "pro" in context.config.machine_type
4903- if context.config.install_from is InstallationSource.ARCHIVE:
4904+ is_pro = "pro" in context.pro_config.machine_type
4905+ if context.pro_config.install_from is InstallationSource.ARCHIVE:
4906 instance.execute("sudo apt update")
4907 when_i_apt_install(
4908 context, "ubuntu-advantage-tools", machine_name=machine_name
4909@@ -24,8 +24,8 @@ def when_i_install_uat(context, machine_name=SUT):
4910 when_i_apt_install(
4911 context, "ubuntu-advantage-pro", machine_name=machine_name
4912 )
4913- elif context.config.install_from is InstallationSource.PREBUILT:
4914- debs_path = context.config.debs_path
4915+ elif context.pro_config.install_from is InstallationSource.PREBUILT:
4916+ debs_path = context.pro_config.debs_path
4917 deb_paths = [
4918 os.path.join(debs_path, deb_file)
4919 for deb_file in os.listdir(debs_path)
4920@@ -39,7 +39,7 @@ def when_i_install_uat(context, machine_name=SUT):
4921 context, "/tmp/behave_ua.deb", machine_name=machine_name
4922 )
4923 instance.execute("sudo rm /tmp/behave_ua.deb")
4924- elif context.config.install_from is InstallationSource.LOCAL:
4925+ elif context.pro_config.install_from is InstallationSource.LOCAL:
4926 ua_deb_path, pro_deb_path = build_debs(series)
4927 instance.push_file(ua_deb_path, "/tmp/behave_ua.deb")
4928 when_i_apt_install(
4929@@ -52,7 +52,7 @@ def when_i_install_uat(context, machine_name=SUT):
4930 context, "/tmp/behave_ua.deb", machine_name=machine_name
4931 )
4932 instance.execute("sudo rm /tmp/behave_ua.deb")
4933- elif context.config.install_from is InstallationSource.DAILY:
4934+ elif context.pro_config.install_from is InstallationSource.DAILY:
4935 instance.execute("sudo add-apt-repository ppa:ua-client/daily")
4936 instance.execute("sudo apt update")
4937 when_i_apt_install(
4938@@ -62,7 +62,7 @@ def when_i_install_uat(context, machine_name=SUT):
4939 when_i_apt_install(
4940 context, "ubuntu-advantage-pro", machine_name=machine_name
4941 )
4942- elif context.config.install_from is InstallationSource.STAGING:
4943+ elif context.pro_config.install_from is InstallationSource.STAGING:
4944 instance.execute("sudo add-apt-repository ppa:ua-client/staging")
4945 instance.execute("sudo apt update")
4946 when_i_apt_install(
4947@@ -72,7 +72,7 @@ def when_i_install_uat(context, machine_name=SUT):
4948 when_i_apt_install(
4949 context, "ubuntu-advantage-pro", machine_name=machine_name
4950 )
4951- elif context.config.install_from is InstallationSource.STABLE:
4952+ elif context.pro_config.install_from is InstallationSource.STABLE:
4953 instance.execute("sudo add-apt-repository ppa:ua-client/stable")
4954 instance.execute("sudo apt update")
4955 when_i_apt_install(
4956@@ -82,7 +82,7 @@ def when_i_install_uat(context, machine_name=SUT):
4957 when_i_apt_install(
4958 context, "ubuntu-advantage-pro", machine_name=machine_name
4959 )
4960- elif context.config.install_from is InstallationSource.PROPOSED:
4961+ elif context.pro_config.install_from is InstallationSource.PROPOSED:
4962 context.text = "deb http://archive.ubuntu.com/ubuntu/ {series}-proposed main\n".format( # noqa: E501
4963 series=series
4964 )
4965@@ -127,9 +127,9 @@ def when_i_install_uat(context, machine_name=SUT):
4966 when_i_apt_install(
4967 context, "ubuntu-advantage-pro", machine_name=machine_name
4968 )
4969- elif context.config.install_from is InstallationSource.CUSTOM:
4970+ elif context.pro_config.install_from is InstallationSource.CUSTOM:
4971 instance.execute(
4972- "sudo add-apt-repository {}".format(context.config.custom_ppa)
4973+ "sudo add-apt-repository {}".format(context.pro_config.custom_ppa)
4974 )
4975 instance.execute("sudo apt update")
4976 when_i_apt_install(
4977@@ -143,7 +143,7 @@ def when_i_install_uat(context, machine_name=SUT):
4978
4979 @when("I have the `{series}` debs under test in `{dest}`")
4980 def when_i_have_the_debs_under_test(context, series, dest):
4981- if context.config.install_from is InstallationSource.LOCAL:
4982+ if context.pro_config.install_from is InstallationSource.LOCAL:
4983 deb_paths = build_debs(series)
4984
4985 for deb_path in deb_paths:
4986@@ -151,17 +151,17 @@ def when_i_have_the_debs_under_test(context, series, dest):
4987 dest_path = "{}/ubuntu-advantage-{}.deb".format(dest, tools_or_pro)
4988 context.machines[SUT].instance.push_file(deb_path, dest_path)
4989 else:
4990- if context.config.install_from is InstallationSource.PROPOSED:
4991+ if context.pro_config.install_from is InstallationSource.PROPOSED:
4992 ppa_opts = ""
4993 else:
4994- if context.config.install_from is InstallationSource.DAILY:
4995+ if context.pro_config.install_from is InstallationSource.DAILY:
4996 ppa = "ppa:ua-client/daily"
4997- elif context.config.install_from is InstallationSource.STAGING:
4998+ elif context.pro_config.install_from is InstallationSource.STAGING:
4999 ppa = "ppa:ua-client/staging"
5000- elif context.config.install_from is InstallationSource.STABLE:
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: