Merge ~renanrodrigo/ubuntu/+source/ubuntu-advantage-tools:upload-27.14-lunar into ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel

Proposed by Renan Rodrigo
Status: Merged
Merged at revision: 01aebdc37ea06b5b7e7022ae74b110e8fddab200
Proposed branch: ~renanrodrigo/ubuntu/+source/ubuntu-advantage-tools:upload-27.14-lunar
Merge into: ubuntu/+source/ubuntu-advantage-tools:ubuntu/devel
Diff against target: 23735 lines (+9575/-5030)
183 files modified
.github/workflows/ci-base.yaml (+5/-17)
CONTRIBUTING.md (+4/-0)
README.md (+10/-50)
apt-hook/20apt-esm-hook.conf (+0/-4)
apt-hook/Makefile (+3/-10)
apt-hook/esm-counts.cc (+13/-0)
apt-hook/json-hook.cc (+3/-4)
debian/changelog (+38/-0)
debian/rules (+0/-4)
debian/ubuntu-advantage-tools.maintscript (+1/-0)
debian/ubuntu-advantage-tools.postinst (+82/-39)
debian/ubuntu-advantage-tools.postrm (+3/-6)
debian/ubuntu-advantage-tools.preinst (+19/-85)
dev-docs/devdocs_styleguide.md (+152/-0)
dev-docs/howtoguides/building.md (+1/-1)
dev-docs/howtoguides/detach_pro_instances.md (+25/-0)
dev-docs/howtoguides/testing.md (+5/-0)
dev/null (+0/-4)
docs/_static/css/custom.css (+240/-0)
docs/_static/css/github_issue_links.css (+17/-0)
docs/_static/js/github_issue_links.js (+1/-1)
docs/conf.py (+44/-5)
docs/explanations.rst (+43/-4)
docs/explanations/apt_messages.md (+130/-106)
docs/explanations/errors_explained.md (+101/-0)
docs/explanations/how_to_interpret_the_security_status_command.md (+77/-56)
docs/explanations/motd_messages.md (+100/-101)
docs/explanations/status_columns.md (+55/-26)
docs/explanations/what_are_the_timer_jobs.md (+20/-13)
docs/explanations/what_are_ubuntu_pro_cloud_instances.md (+25/-12)
docs/explanations/what_is_the_daemon.md (+7/-3)
docs/explanations/what_is_the_ubuntu_advantage_pro_package.md (+7/-3)
docs/explanations/what_refresh_does.md (+21/-9)
docs/explanations/why_trusty_is_no_longer_supported.md (+9/-6)
docs/howtoguides.rst (+9/-8)
docs/howtoguides/disable_enable_apt_news.md (+45/-0)
docs/howtoguides/enable_realtime_kernel.md (+3/-3)
docs/howtoguides/get_rid_of_corrupt_lock.md (+29/-0)
docs/index.rst (+2/-3)
docs/references.rst (+7/-4)
docs/references/api.md (+314/-130)
docs/references/network_requirements.md (+30/-13)
docs/references/ppas.md (+30/-9)
docs/references/support_matrix.md (+15/-15)
features/_version.feature (+16/-0)
features/api_packages.feature (+10/-8)
features/api_security.feature (+11/-1)
features/api_unattended_upgrades.feature (+207/-0)
features/apt_messages.feature (+81/-66)
features/attach_validtoken.feature (+30/-72)
features/attached_commands.feature (+13/-36)
features/attached_enable.feature (+79/-108)
features/config.feature (+55/-0)
features/daemon.feature (+2/-3)
features/environment.py (+13/-7)
features/fix.feature (+97/-25)
features/livepatch.feature (+72/-0)
features/logs.feature (+30/-0)
features/motd_messages.feature (+14/-148)
features/proxy_config.feature (+71/-72)
features/realtime_kernel.feature (+20/-6)
features/steps/attach.py (+4/-18)
features/steps/contract.py (+23/-0)
features/steps/files.py (+5/-4)
features/steps/misc.py (+9/-0)
features/steps/packages.py (+18/-0)
features/steps/shell.py (+11/-14)
features/steps/ubuntu_advantage_tools.py (+20/-1)
features/ubuntu_pro.feature (+11/-1)
features/ubuntu_pro_fips.feature (+12/-0)
features/unattached_commands.feature (+75/-0)
features/unattached_status.feature (+3/-3)
features/util.py (+31/-7)
lib/apt_news.py (+1/-1)
lib/auto_attach.py (+1/-1)
lib/daemon.py (+1/-1)
lib/esm_cache.py (+1/-1)
lib/migrate_user_config.py (+162/-0)
lib/reboot_cmds.py (+13/-14)
lib/timer.py (+17/-4)
lib/upgrade_lts_contract.py (+2/-3)
sru/release-27.14/test-migrate-user-config.sh (+288/-0)
systemd/apt-news.service (+10/-0)
tools/test-in-lxd.sh (+29/-12)
tools/test-in-multipass.sh (+19/-13)
uaclient-devel.conf (+0/-7)
uaclient.conf (+0/-16)
uaclient/actions.py (+7/-9)
uaclient/api/api.py (+1/-0)
uaclient/api/data_types.py (+2/-2)
uaclient/api/exceptions.py (+7/-0)
uaclient/api/tests/test_api_u_pro_attach_auto_full_auto_attach_v1.py (+13/-3)
uaclient/api/tests/test_api_u_unattended_upgrades_status_v1.py (+150/-0)
uaclient/api/u/pro/attach/auto/full_auto_attach/v1.py (+1/-1)
uaclient/api/u/unattended_upgrades/__init__.py (+0/-0)
uaclient/api/u/unattended_upgrades/status/__init__.py (+0/-0)
uaclient/api/u/unattended_upgrades/status/v1.py (+215/-0)
uaclient/apt.py (+172/-15)
uaclient/cli.py (+51/-73)
uaclient/config.py (+130/-126)
uaclient/conftest.py (+58/-8)
uaclient/contract.py (+2/-1)
uaclient/contract_data_types.py (+6/-5)
uaclient/daemon/__init__.py (+7/-3)
uaclient/daemon/retry_auto_attach.py (+17/-6)
uaclient/daemon/tests/test_poll_for_pro_license.py (+3/-12)
uaclient/data_types.py (+57/-28)
uaclient/defaults.py (+7/-1)
uaclient/entitlements/base.py (+296/-265)
uaclient/entitlements/entitlement_status.py (+1/-0)
uaclient/entitlements/esm.py (+6/-6)
uaclient/entitlements/fips.py (+28/-41)
uaclient/entitlements/livepatch.py (+46/-85)
uaclient/entitlements/realtime.py (+11/-1)
uaclient/entitlements/repo.py (+5/-9)
uaclient/entitlements/tests/test_base.py (+292/-239)
uaclient/entitlements/tests/test_cc.py (+1/-5)
uaclient/entitlements/tests/test_cis.py (+1/-3)
uaclient/entitlements/tests/test_esm.py (+2/-152)
uaclient/entitlements/tests/test_fips.py (+53/-79)
uaclient/entitlements/tests/test_livepatch.py (+54/-358)
uaclient/entitlements/tests/test_repo.py (+53/-55)
uaclient/event_logger.py (+7/-3)
uaclient/exceptions.py (+6/-0)
uaclient/files/__init__.py (+1/-2)
uaclient/files/data_types.py (+13/-6)
uaclient/files/files.py (+18/-97)
uaclient/files/notices.py (+231/-0)
uaclient/files/state_files.py (+103/-2)
uaclient/files/tests/test_files.py (+7/-4)
uaclient/files/tests/test_notices.py (+124/-0)
uaclient/jobs/tests/test_update_contract_info.py (+88/-0)
uaclient/jobs/tests/test_update_messaging.py (+294/-500)
uaclient/jobs/update_contract_info.py (+29/-0)
uaclient/jobs/update_messaging.py (+108/-327)
uaclient/livepatch.py (+397/-0)
uaclient/lock.py (+6/-2)
uaclient/log.py (+60/-0)
uaclient/messages.py (+157/-22)
uaclient/security.py (+129/-32)
uaclient/security_status.py (+70/-121)
uaclient/serviceclient.py (+6/-5)
uaclient/status.py (+87/-38)
uaclient/system.py (+36/-3)
uaclient/testing/fakes.py (+6/-0)
uaclient/tests/test_actions.py (+3/-4)
uaclient/tests/test_apt.py (+112/-10)
uaclient/tests/test_cli.py (+67/-41)
uaclient/tests/test_cli_api.py (+2/-1)
uaclient/tests/test_cli_attach.py (+43/-39)
uaclient/tests/test_cli_auto_attach.py (+3/-9)
uaclient/tests/test_cli_collect_logs.py (+2/-6)
uaclient/tests/test_cli_config.py (+57/-0)
uaclient/tests/test_cli_config_set.py (+17/-24)
uaclient/tests/test_cli_config_show.py (+17/-30)
uaclient/tests/test_cli_config_unset.py (+8/-10)
uaclient/tests/test_cli_detach.py (+15/-22)
uaclient/tests/test_cli_disable.py (+33/-23)
uaclient/tests/test_cli_enable.py (+28/-41)
uaclient/tests/test_cli_refresh.py (+55/-45)
uaclient/tests/test_cli_security_status.py (+1/-1)
uaclient/tests/test_cli_status.py (+79/-105)
uaclient/tests/test_config.py (+155/-146)
uaclient/tests/test_contract.py (+6/-5)
uaclient/tests/test_data_types.py (+41/-0)
uaclient/tests/test_event_logger.py (+3/-3)
uaclient/tests/test_lib_migrate_user_config.py (+242/-0)
uaclient/tests/test_livepatch.py (+875/-0)
uaclient/tests/test_lock.py (+9/-4)
uaclient/tests/test_log.py (+159/-0)
uaclient/tests/test_reboot_cmds.py (+17/-14)
uaclient/tests/test_security.py (+188/-46)
uaclient/tests/test_security_status.py (+69/-134)
uaclient/tests/test_serviceclient.py (+1/-1)
uaclient/tests/test_status.py (+63/-47)
uaclient/tests/test_system.py (+49/-1)
uaclient/tests/test_ua_timer.py (+8/-4)
uaclient/tests/test_util.py (+6/-3)
uaclient/util.py (+33/-23)
uaclient/version.py (+1/-1)
uaclient/yaml.py (+29/-0)
ubuntu-advantage.1 (+7/-3)
update-motd.d/91-contract-ua-esm-status (+2/-2)
Reviewer Review Type Date Requested Status
Athos Ribeiro (community) Approve
Review via email: mp+439382@code.launchpad.net

Description of the change

This is release 27.14 of ubuntu-advantage-tools.

You can find the description of changes in the overall SRU bug here: https://bugs.launchpad.net/ubuntu/+source/ubuntu-advantage-tools/+bug/2011477

To post a comment you must log in.
Revision history for this message
Athos Ribeiro (athos-ribeiro) wrote :

The diff below is being truncated.

I am adding my comments here then.

In commit 76e0a70cba62fdcbd7ea8c34fbe67728893f632e:

- Parsing the Acquire" apt option should be done with a regular expression to avoid parsing debugging option by mistake

- nitpick: uaclient/conftest.py - Could the "Useless try/except to make flake8 happy" be just an ignore hint for flake8 instead? i.e., use the resources described at https://flake8.pycqa.org/en/latest/user/violations.html.

In commit 990b3f134996c5a235aeaec608ca1e477c56d00b:

- debian/ubuntu-advantage-tools.postinst: The first message is being echo'ed to stdout, the others, to stderr. is this intentional?

Revision history for this message
Lucas Albuquerque Medeiros de Moura (lamoura) wrote :

Hi Athos, thanks for the review

In commit 76e0a70cba62fdcbd7ea8c34fbe67728893f632e:
- Yes, the Acquire fix is indeed missing. We will address it today

nitpick: uaclient/conftest.py
I Agree we can change that, but I think we can touch this later in the next release, due to the timeline we have at the moment. But I think it is indeed a good idea.

In commit 990b3f134996c5a235aeaec608ca1e477c56d00b:
- Good catch, this is indeed a mistake. I will fix that

Revision history for this message
Renan Rodrigo (renanrodrigo) wrote :

@Athos, MP updated including the requested changes

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

Thank you!

LGTM

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

I just triggered the DEP8 tests suite for the builds pushed to ppa:ua-client/staging. I will start uploading those as soon as we get the test results.

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

  - ubuntu-advantage-tools/27.14~23.04.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on lunar for amd64 @ 22.03.23 18:55:26 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on lunar for arm64 @ 22.03.23 18:23:35 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on lunar for armhf @ 22.03.23 18:14:49 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on lunar for ppc64el @ 22.03.23 18:13:59 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on lunar for s390x @ 22.03.23 18:15:40 Log️ 🗒️

  - ubuntu-advantage-tools/27.14~22.10.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on kinetic for amd64 @ 22.03.23 18:20:11 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on kinetic for arm64 @ 22.03.23 18:34:50 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on kinetic for armhf @ 22.03.23 18:16:25 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on kinetic for ppc64el @ 22.03.23 18:17:11 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on kinetic for s390x @ 22.03.23 18:15:08 Log️ 🗒️

  - ubuntu-advantage-tools/27.14~22.04.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on jammy for amd64 @ 22.03.23 18:32:04 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on jammy for arm64 @ 22.03.23 18:26:01 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on jammy for armhf @ 22.03.23 18:16:13 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on jammy for ppc64el @ 22.03.23 18:15:32 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on jammy for s390x @ 22.03.23 18:16:13 Log️ 🗒️

  - ubuntu-advantage-tools/27.14~20.04.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on focal for amd64 @ 22.03.23 18:34:01 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on focal for arm64 @ 22.03.23 18:21:46 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on focal for armhf @ 22.03.23 18:20:53 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on focal for ppc64el @ 22.03.23 18:16:55 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on focal for s390x @ 22.03.23 18:18:16 Log️ 🗒️

  - ubuntu-advantage-tools/27.14~18.04.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on bionic for amd64 @ 22.03.23 18:25:33 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on bionic for arm64 @ 22.03.23 18:39:00 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on bionic for armhf @ 22.03.23 18:18:01 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on bionic for ppc64el @ 22.03.23 18:17:45 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on bionic for s390x @ 22.03.23 18:18:12 Log️ 🗒️

  - ubuntu-advantage-tools/27.14~16.04.1~rc3+noflake8
    + ✅ ubuntu-advantage-tools on xenial for amd64 @ 22.03.23 19:01:26 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on xenial for arm64 @ 22.03.23 18:24:08 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on xenial for armhf @ 22.03.23 18:17:55 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on xenial for ppc64el @ 22.03.23 18:17:00 Log️ 🗒️
    + ✅ ubuntu-advantage-tools on xenial for s390x @ 22.03.23 18:16:54 Log️ 🗒️

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

Uploaded.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~23.04.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~23.04.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~23.04.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~23.04.1_source.changes: done.
Successfully uploaded packages.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~22.10.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~22.10.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~22.10.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~22.10.1_source.changes: done.
Successfully uploaded packages.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~22.04.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~22.04.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~22.04.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~22.04.1_source.changes: done.
Successfully uploaded packages.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~20.04.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~20.04.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~20.04.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~20.04.1_source.changes: done.
Successfully uploaded packages.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~18.04.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~18.04.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~18.04.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~18.04.1_source.changes: done.
Successfully uploaded packages.

Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading ubuntu-advantage-tools_27.14~16.04.1.dsc: done.
  Uploading ubuntu-advantage-tools_27.14~16.04.1.tar.xz: done.
  Uploading ubuntu-advantage-tools_27.14~16.04.1_source.buildinfo: done.
  Uploading ubuntu-advantage-tools_27.14~16.04.1_source.changes: done.
Successfully uploaded packages.

Revision history for this message
Renan Rodrigo (renanrodrigo) wrote :

Thank you very much again for all the effort!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.github/workflows/ci-base.yaml b/.github/workflows/ci-base.yaml
2index 0b8f1ed..59174bf 100644
3--- a/.github/workflows/ci-base.yaml
4+++ b/.github/workflows/ci-base.yaml
5@@ -23,33 +23,21 @@ jobs:
6 uses: actions/checkout@v3
7 - name: Formatting
8 run: tox -e black -e isort
9+ - name: Style
10+ run: tox -e flake8
11 - name: Mypy
12 run: tox -e mypy
13 - name: Version Consistency
14 run: python3 ./tools/check-versions-are-consistent.py
15 unit-tests:
16- name: Matrix
17- strategy:
18- matrix:
19- testenv:
20- - {os: ubuntu-18.04, pyver: py35, deadsnake: python3.5}
21- - {os: ubuntu-18.04, pyver: py36}
22- - {os: ubuntu-20.04, pyver: py38}
23- - {os: ubuntu-22.04, pyver: py310}
24- runs-on: ${{ matrix.testenv.os }}
25+ name: Unit Tests
26+ runs-on: ubuntu-22.04
27 steps:
28 - name: Install dependencies
29 run: |
30 sudo DEBIAN_FRONTEND=noninteractive apt-get -qy update
31 sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install tox
32- - name: Install older Python from deadsnakes PPA
33- if: matrix.testenv.deadsnake != ''
34- run: |
35- sudo add-apt-repository --yes ppa:deadsnakes/ppa
36- sudo DEBIAN_FRONTEND=noninteractive apt-get -qy install "${{ matrix.testenv.deadsnake }}" "${{ matrix.testenv.deadsnake }}-dev"
37 - name: Git checkout
38 uses: actions/checkout@v3
39- - name: Flake8
40- run: tox -e "${{ matrix.testenv.pyver }}-flake8"
41 - name: Unit
42- run: tox -e "${{ matrix.testenv.pyver }}-test"
43+ run: tox -e test
44diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
45index dd7809e..03568a6 100644
46--- a/CONTRIBUTING.md
47+++ b/CONTRIBUTING.md
48@@ -29,3 +29,7 @@ from the architecture of the project to how you should test any code changes.
49 ### Explanation
50
51 * [How auto-attach works](./dev-docs/explanations/how_auto_attach_works.md)
52+
53+### Documentation
54+
55+* [Documentation guide](./dev-docs/devdocs_styleguide.md)
56diff --git a/README.md b/README.md
57index 922188d..4e7a493 100644
58--- a/README.md
59+++ b/README.md
60@@ -7,13 +7,16 @@
61 </h1>
62
63 ###### Clean and Consistent CLI for your Ubuntu Pro Systems
64-![Latest Upstream Version](https://img.shields.io/github/v/tag/canonical/ubuntu-advantage-client.svg?label=Latest%20Upstream%20Version&logo=github&logoColor=white&color=33ce57)
65-![CI](https://github.com/canonical/ubuntu-advantage-client/actions/workflows/ci-base.yaml/badge.svg?branch=main)
66+[![Latest Upstream Version](https://img.shields.io/github/v/tag/canonical/ubuntu-advantage-client.svg?label=Latest%20Upstream%20Version&logo=github&logoColor=white&color=33ce57)](https://github.com/canonical/ubuntu-pro-client/tags)
67+[![CI](https://github.com/canonical/ubuntu-advantage-client/actions/workflows/ci-base.yaml/badge.svg?branch=main)](https://github.com/canonical/ubuntu-pro-client/actions)
68+[![Documentation Status](https://readthedocs.com/projects/canonical-ubuntu-pro-client/badge/?version=latest)](https://canonical-ubuntu-pro-client.readthedocs-hosted.com/en/latest/?badge=latest)
69 <br/>
70-![Released Xenial Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/xenial?label=Xenial&logo=ubuntu&logoColor=white)
71-![Released Bionic Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/bionic?label=Bionic&logo=ubuntu&logoColor=white)
72-![Released Focal Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/focal?label=Focal&logo=ubuntu&logoColor=white)
73-![Released Jammy Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/jammy?label=Jammy&logo=ubuntu&logoColor=white)
74+[![Released Xenial Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/xenial?label=Xenial&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/xenial/+source/ubuntu-advantage-tools)
75+[![Released Bionic Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/bionic?label=Bionic&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/bionic/+source/ubuntu-advantage-tools)
76+[![Released Focal Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/focal?label=Focal&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/focal/+source/ubuntu-advantage-tools)
77+[![Released Jammy Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/jammy?label=Jammy&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/jammy/+source/ubuntu-advantage-tools)
78+[![Released Kinetic Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/kinetic?label=Kinetic&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/kinetic/+source/ubuntu-advantage-tools)
79+[![Released Lunar Version](https://img.shields.io/ubuntu/v/ubuntu-advantage-tools/lunar?label=Lunar&logo=ubuntu&logoColor=white)](https://launchpad.net/ubuntu/lunar/+source/ubuntu-advantage-tools)
80
81 The Ubuntu Pro Client (`pro`) is the official tool to enable Canonical offerings on your
82 system.
83@@ -33,50 +36,7 @@ If you need any of those services for your machine, `pro` is the right tool for
84
85 `pro` is already installed on every Ubuntu system. Try it out by running `pro help`!
86
87-## Documentation
88-
89-### Tutorials
90-
91-* [Getting started with Ubuntu Pro Client](./docs/tutorials/basic_commands.md)
92-* [Create a FIPS compliant Ubuntu Docker image](./docs/tutorials/create_a_fips_docker_image.md)
93-* [Fix vulnerabilities by CVE or USN using `pro fix`](./docs/tutorials/fix_scenarios.md)
94-* [Create a Custom Ubuntu Pro Cloud Image with FIPS Updates](./docs/tutorials/create_a_fips_updates_pro_cloud_image.md)
95-
96-### How To Guides
97-
98-* [How to get an Ubuntu Pro token and attach to a subscription](./docs/howtoguides/get_token_and_attach.md)
99-* [How to Configure Proxies](./docs/howtoguides/configure_proxies.md)
100-* [How to Enable Ubuntu Pro Services in a Dockerfile](./docs/howtoguides/enable_in_dockerfile.md)
101-* [How to Create a custom Golden Image based on Public Cloud Ubuntu Pro images](./docs/howtoguides/create_pro_golden_image.md)
102-* [How to Manually update MOTD and APT messages](./docs/howtoguides/update_motd_messages.md)
103-* [How to enable CIS](./docs/howtoguides/enable_cis.md)
104-* [How to enable CC EAL](./docs/howtoguides/enable_cc.md)
105-* [How to enable ESM Infra](./docs/howtoguides/enable_esm_infra.md)
106-* [How to enable FIPS](./docs/howtoguides/enable_fips.md)
107-* [How to enable Livepatch](./docs/howtoguides/enable_livepatch.md)
108-* [How to configure a timer job](./docs/howtoguides/configuring_timer_jobs.md)
109-* [How to attach with a configuration file](./docs/howtoguides/how_to_attach_with_config_file.md)
110-* [How to collect Ubuntu Pro Client logs](./docs/howtoguides/how_to_collect_logs.md)
111-* [How to simulate attach operation](./docs/howtoguides/how_to_simulate_attach.md)
112-* [How to run `pro fix` in dry-run mode](./docs/howtoguides/how_to_run_fix_in_dry_run_mode.md)
113-
114-### Reference
115-
116-* [Ubuntu Release and Architecture Support Matrix](./docs/references/support_matrix.md)
117-* [Network Requirements](./docs/references/network_requirements.md)
118-* [API Reference Guide](./docs/references/api.md)
119-* [PPAs with different versions of `pro`](./docs/references/ppas.md)
120-
121-### Explanation
122-
123-* [What is the daemon for? (And how to disable it)](./docs/explanations/what_is_the_daemon.md)
124-* [What are Public Cloud Ubuntu Pro instances?](./docs/explanations/what_are_ubuntu_pro_cloud_instances.md)
125-* [What is the ubuntu-advantage-pro package?](./docs/explanations/what_is_the_ubuntu_advantage_pro_package.md)
126-* [What are the timer jobs?](./docs/explanations/what_are_the_timer_jobs.md)
127-* [What are the Ubuntu Pro related MOTD messages?](./docs/explanations/motd_messages.md)
128-* [What are the Ubuntu Pro related APT messages?](./docs/explanations/apt_messages.md)
129-* [How to interpret the security-status command](./docs/explanations/how_to_interpret_the_security_status_command.md)
130-* [Why Trusty (14.04) is no longer supported](./docs/explanations/why_trusty_is_no_longer_supported.md)
131+Or [check out the docs](https://canonical-ubuntu-pro-client.readthedocs-hosted.com/en/latest/).
132
133 ## Project and community
134
135diff --git a/apt-hook/20apt-esm-hook.conf b/apt-hook/20apt-esm-hook.conf
136index 7bcae44..36a7593 100644
137--- a/apt-hook/20apt-esm-hook.conf
138+++ b/apt-hook/20apt-esm-hook.conf
139@@ -2,10 +2,6 @@ APT::Update::Pre-Invoke {
140 "[ ! -e /run/systemd/system ] || [ $(id -u) -ne 0 ] || systemctl start --no-block apt-news.service esm-cache.service || true";
141 };
142
143-APT::Update::Post-Invoke-Stats {
144- "[ ! -f /usr/lib/ubuntu-advantage/apt-esm-hook ] || /usr/lib/ubuntu-advantage/apt-esm-hook || true";
145-};
146-
147 binary::apt::AptCli::Hooks::Upgrade {
148 "[ ! -f /usr/lib/ubuntu-advantage/apt-esm-json-hook ] || /usr/lib/ubuntu-advantage/apt-esm-json-hook || true";
149 };
150diff --git a/apt-hook/Makefile b/apt-hook/Makefile
151index 9bb2bcd..ad7d586 100644
152--- a/apt-hook/Makefile
153+++ b/apt-hook/Makefile
154@@ -1,12 +1,6 @@
155 all: build
156
157-build: hook ubuntu-advantage.pot json-hook
158-
159-ubuntu-advantage.pot: hook.cc
160- xgettext hook.cc -o ubuntu-advantage.pot
161-
162-hook: hook.cc
163- $(CXX) -Wall -Wextra -pedantic -std=c++11 $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -g -o hook hook.cc esm-templates.cc -lapt-pkg $(LDLIBS)
164+build: json-hook
165
166 json-hook: json-hook.cc
167 $(CXX) -Wall -Wextra -pedantic -std=c++11 $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -g -o json-hook json-hook-main.cc json-hook.cc esm-counts.cc -ljson-c -lapt-pkg $(LDLIBS)
168@@ -18,11 +12,10 @@ test:
169 install-conf:
170 install -D -m 644 20apt-esm-hook.conf $(DESTDIR)/etc/apt/apt.conf.d/20apt-esm-hook.conf
171
172-install: hook json-hook
173- install -D -m 755 hook $(DESTDIR)/usr/lib/ubuntu-advantage/apt-esm-hook
174+install: json-hook
175 install -D -m 755 json-hook $(DESTDIR)/usr/lib/ubuntu-advantage/apt-esm-json-hook
176
177 clean:
178- rm -f hook json-hook json-hook-test ubuntu-advantage.pot
179+ rm -f json-hook json-hook-test
180
181 .PHONY: test
182diff --git a/apt-hook/esm-counts.cc b/apt-hook/esm-counts.cc
183index 82aea99..1a94d87 100644
184--- a/apt-hook/esm-counts.cc
185+++ b/apt-hook/esm-counts.cc
186@@ -52,11 +52,24 @@ bool get_potential_esm_updates(ESMUpdates &updates) {
187 }
188
189 // set up esm cache
190+ // make sure the configuration is isolated, apart from Acquire
191+ for (const Configuration::Item *ConfigItem = _config->Tree(0); ConfigItem != NULL; ConfigItem = ConfigItem->Next) {
192+ if (ConfigItem->FullTag(0) != "Acquire") {
193+ _config->Clear(ConfigItem->FullTag(0));
194+ }
195+ }
196+
197 _config->Set("Dir", "/var/lib/ubuntu-advantage/apt-esm/");
198 _config->Set("Dir::State::status", "/var/lib/ubuntu-advantage/apt-esm/var/lib/dpkg/status");
199+
200+ if (!pkgInitConfig(*_config)) {
201+ return false;
202+ }
203+
204 if (!pkgInitSystem(*_config, _system)) {
205 return false;
206 }
207+
208 pkgCacheFile esm_cachefile;
209 pkgCache *esm_cache = esm_cachefile.GetPkgCache();
210 if (esm_cache == NULL) {
211diff --git a/apt-hook/esm-templates.cc b/apt-hook/esm-templates.cc
212deleted file mode 100644
213index 3444e2e..0000000
214--- a/apt-hook/esm-templates.cc
215+++ /dev/null
216@@ -1,273 +0,0 @@
217-#include <apt-pkg/cachefile.h>
218-#include <apt-pkg/error.h>
219-#include <apt-pkg/init.h>
220-#include <apt-pkg/pkgsystem.h>
221-#include <apt-pkg/policy.h>
222-#include <apt-pkg/strutl.h>
223-
224-#include <algorithm>
225-#include <array>
226-#include <fstream>
227-#include <iostream>
228-#include <sstream>
229-#include <string>
230-#include <vector>
231-
232-#include "esm-templates.hh"
233-
234-
235-struct result {
236- int enabled_esms_i;
237- int disabled_esms_i;
238- std::vector<std::string> esm_i_packages;
239-
240- int enabled_esms_a;
241- int disabled_esms_a;
242- std::vector<std::string> esm_a_packages;
243-};
244-
245-// Check if we have an ESM upgrade for the specified package
246-static void check_esm_upgrade(pkgCache::PkgIterator pkg, pkgPolicy *policy, result &res)
247-{
248- pkgCache::VerIterator cur = pkg.CurrentVer();
249-
250- if (cur.end())
251- return;
252-
253- // Search all versions >= cur (list in decreasing order)
254- for (pkgCache::VerIterator ver = pkg.VersionList(); !ver.end() && ver->ID != cur->ID; ver++)
255- {
256- for (pkgCache::VerFileIterator pf = ver.FileList(); !pf.end(); pf++)
257- {
258- if (pf.File().Archive() != 0 && DeNull(pf.File().Origin()) == std::string("UbuntuESM"))
259- {
260- if (std::find(res.esm_i_packages.begin(), res.esm_i_packages.end(), pkg.Name()) == res.esm_i_packages.end()) {
261- res.esm_i_packages.push_back(pkg.Name());
262-
263- // Pin-Priority: never unauthenticated APT repos == -32768
264- if (policy->GetPriority(pf.File()) == -32768)
265- {
266- res.disabled_esms_i++;
267- }
268- else
269- {
270- res.enabled_esms_i++;
271- }
272- }
273- }
274- if (pf.File().Archive() != 0 && DeNull(pf.File().Origin()) == std::string("UbuntuESMApps"))
275- {
276- if (std::find(res.esm_a_packages.begin(), res.esm_a_packages.end(), pkg.Name()) == res.esm_a_packages.end()) {
277- res.esm_a_packages.push_back(pkg.Name());
278-
279- // Pin-Priority: never unauthenticated APT repos == -32768
280- if (policy->GetPriority(pf.File()) == -32768)
281- {
282- res.disabled_esms_a++;
283- }
284- else
285- {
286- res.enabled_esms_a++;
287- }
288- }
289- }
290- }
291- }
292-}
293-
294-// Calculate the update count
295-static int get_update_count(result &res)
296-{
297- int count = 0;
298- if (!pkgInitConfig(*_config))
299- return -1;
300-
301- if (!pkgInitSystem(*_config, _system))
302- return -1;
303-
304- pkgCacheFile cachefile;
305-
306- pkgCache *cache = cachefile.GetPkgCache();
307- pkgPolicy *policy = cachefile.GetPolicy();
308-
309- if (cache == NULL || policy == NULL)
310- return -1;
311-
312- for (pkgCache::PkgIterator pkg = cache->PkgBegin(); !pkg.end(); pkg++)
313- {
314- check_esm_upgrade(pkg, policy, res);
315- }
316- return count;
317-}
318-
319-
320-static void process_template_file(
321- std::string template_file_name,
322- std::string static_file_name,
323- std::string esm_a_pkgs_count,
324- std::string esm_a_pkgs,
325- std::string esm_i_pkgs_count,
326- std::string esm_i_pkgs
327-) {
328- std::ifstream message_tmpl_file(template_file_name.c_str());
329- if (message_tmpl_file.is_open()) {
330- // This line loads the whole file contents into a string
331- std::string message_tmpl((std::istreambuf_iterator<char>(message_tmpl_file)), (std::istreambuf_iterator<char>()));
332-
333- message_tmpl_file.close();
334-
335- // Process all template variables
336- std::array<std::string, 4> tmpl_var_names = {
337- ESM_APPS_PKGS_COUNT_TEMPLATE_VAR,
338- ESM_APPS_PACKAGES_TEMPLATE_VAR,
339- ESM_INFRA_PKGS_COUNT_TEMPLATE_VAR,
340- ESM_INFRA_PACKAGES_TEMPLATE_VAR
341- };
342- std::array<std::string, 4> tmpl_var_vals = {
343- esm_a_pkgs_count,
344- esm_a_pkgs,
345- esm_i_pkgs_count,
346- esm_i_pkgs
347- };
348- for (uint i = 0; i < tmpl_var_names.size(); i++) {
349- size_t pos = message_tmpl.find(tmpl_var_names[i]);
350- if (pos != std::string::npos) {
351- message_tmpl.replace(pos, tmpl_var_names[i].size(), tmpl_var_vals[i]);
352- }
353- }
354-
355- std::ofstream message_static_file(static_file_name.c_str());
356- if (message_static_file.is_open()) {
357- message_static_file << message_tmpl;
358- message_static_file.close();
359- }
360- } else {
361- remove(static_file_name.c_str());
362- }
363-}
364-
365-void process_all_templates() {
366- int bytes_written;
367- int length;
368-
369- // Iterate over apt cache looking for esm packages
370- result res = {0, 0, std::vector<std::string>(), 0, 0, std::vector<std::string>()};
371- get_update_count(res);
372- if (_error->PendingError())
373- {
374- _error->DumpErrors();
375- return;
376- }
377-
378- // Compute all strings necessary to fill in templates
379- std::string space_separated_esm_i_packages = "";
380- if (res.esm_i_packages.size() > 0) {
381- for (uint i = 0; i < res.esm_i_packages.size() - 1; i++) {
382- space_separated_esm_i_packages.append(res.esm_i_packages[i]);
383- space_separated_esm_i_packages.append(" ");
384- }
385- space_separated_esm_i_packages.append(res.esm_i_packages[res.esm_i_packages.size() - 1]);
386- }
387- std::string space_separated_esm_a_packages = "";
388- if (res.esm_a_packages.size() > 0) {
389- for (uint i = 0; i < res.esm_a_packages.size() - 1; i++) {
390- space_separated_esm_a_packages.append(res.esm_a_packages[i]);
391- space_separated_esm_a_packages.append(" ");
392- }
393- space_separated_esm_a_packages.append(res.esm_a_packages[res.esm_a_packages.size() - 1]);
394- }
395-
396- std::array<std::string, 4> static_file_names = {
397- APT_PRE_INVOKE_APPS_PKGS_STATIC_PATH,
398- MOTD_APPS_PKGS_STATIC_PATH,
399- APT_PRE_INVOKE_INFRA_PKGS_STATIC_PATH,
400- MOTD_INFRA_PKGS_STATIC_PATH,
401- };
402- std::array<std::string, 2> apt_static_files = {
403- APT_PRE_INVOKE_APPS_PKGS_STATIC_PATH,
404- APT_PRE_INVOKE_INFRA_PKGS_STATIC_PATH,
405- };
406- std::array<std::string, 2> motd_static_files = {
407- MOTD_APPS_PKGS_STATIC_PATH,
408- MOTD_INFRA_PKGS_STATIC_PATH,
409- };
410-
411- // Decide which templates to use (nopkg or pkg variants)
412- std::vector<std::string> template_file_names;
413- if (res.esm_a_packages.size() > 0) {
414- template_file_names.push_back(APT_PRE_INVOKE_APPS_PKGS_TEMPLATE_PATH);
415- template_file_names.push_back(MOTD_APPS_PKGS_TEMPLATE_PATH);
416- } else {
417- template_file_names.push_back(APT_PRE_INVOKE_APPS_NO_PKGS_TEMPLATE_PATH);
418- template_file_names.push_back(MOTD_APPS_NO_PKGS_TEMPLATE_PATH);
419- }
420- if (res.esm_i_packages.size() > 0) {
421- template_file_names.push_back(APT_PRE_INVOKE_INFRA_PKGS_TEMPLATE_PATH);
422- template_file_names.push_back(MOTD_INFRA_PKGS_TEMPLATE_PATH);
423- } else {
424- template_file_names.push_back(APT_PRE_INVOKE_INFRA_NO_PKGS_TEMPLATE_PATH);
425- template_file_names.push_back(MOTD_INFRA_NO_PKGS_TEMPLATE_PATH);
426- }
427- // Insert values into selected templates and render to separate file
428- for (uint i = 0; i < template_file_names.size(); i++) {
429- process_template_file(
430- template_file_names[i],
431- static_file_names[i],
432- std::to_string(res.esm_a_packages.size()),
433- space_separated_esm_a_packages,
434- std::to_string(res.esm_i_packages.size()),
435- space_separated_esm_i_packages
436- );
437- }
438-
439- // combine rendered files so that there is one apt file and one motd file
440- // first apt
441- std::ofstream apt_pre_invoke_msg;
442- apt_pre_invoke_msg.open(APT_PRE_INVOKE_MESSAGE_STATIC_PATH);
443- for (uint i = 0; i < apt_static_files.size(); i++) {
444- std::ifstream message_file(apt_static_files[i]);
445- if (message_file.is_open()) {
446- apt_pre_invoke_msg << message_file.rdbuf();
447- message_file.close();
448- };
449- }
450- bytes_written = apt_pre_invoke_msg.tellp();
451- if (bytes_written > 0) {
452- // Then we wrote some content add trailing newline
453- apt_pre_invoke_msg << std::endl;
454- }
455- apt_pre_invoke_msg.close();
456- if (bytes_written == 0) {
457- // We added nothing. Remove the file
458- remove(APT_PRE_INVOKE_MESSAGE_STATIC_PATH);
459- }
460-
461- // then motd
462- std::ofstream motd_msg;
463- motd_msg.open(MOTD_ESM_SERVICE_STATUS_MESSAGE_STATIC_PATH);
464- for (uint i = 0; i < motd_static_files.size(); i++) {
465- std::ifstream message_file(motd_static_files[i]);
466- if (message_file.is_open()) {
467- message_file.seekg(0, message_file.end);
468- length = message_file.tellg();
469- if ( length > 0 ) {
470- message_file.seekg(0, message_file.beg);
471- if ( motd_msg.tellp() > 0 ) {
472- motd_msg << std::endl;
473- }
474- motd_msg << message_file.rdbuf();
475- }
476- message_file.close();
477- };
478- }
479- bytes_written = motd_msg.tellp();
480- if (bytes_written > 0) {
481- // Then we wrote some content add trailing newline
482- motd_msg << std::endl;
483- }
484- motd_msg.close();
485- if (bytes_written == 0) {
486- // We added nothing. Remove the file
487- remove(MOTD_ESM_SERVICE_STATUS_MESSAGE_STATIC_PATH);
488- }
489-}
490diff --git a/apt-hook/esm-templates.hh b/apt-hook/esm-templates.hh
491deleted file mode 100644
492index 26115f5..0000000
493--- a/apt-hook/esm-templates.hh
494+++ /dev/null
495@@ -1,24 +0,0 @@
496-#include <string>
497-#include <vector>
498-
499-#define MOTD_ESM_SERVICE_STATUS_MESSAGE_STATIC_PATH "/var/lib/ubuntu-advantage/messages/motd-esm-service-status"
500-#define MOTD_APPS_NO_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/motd-no-packages-apps.tmpl"
501-#define MOTD_INFRA_NO_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/motd-no-packages-infra.tmpl"
502-#define MOTD_APPS_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/motd-packages-apps.tmpl"
503-#define MOTD_INFRA_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/motd-packages-infra.tmpl"
504-#define MOTD_APPS_PKGS_STATIC_PATH "/var/lib/ubuntu-advantage/messages/motd-packages-apps"
505-#define MOTD_INFRA_PKGS_STATIC_PATH "/var/lib/ubuntu-advantage/messages/motd-packages-infra"
506-#define APT_PRE_INVOKE_APPS_NO_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-no-packages-apps.tmpl"
507-#define APT_PRE_INVOKE_INFRA_NO_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-no-packages-infra.tmpl"
508-#define APT_PRE_INVOKE_APPS_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-packages-apps.tmpl"
509-#define APT_PRE_INVOKE_APPS_PKGS_STATIC_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-packages-apps"
510-#define APT_PRE_INVOKE_INFRA_PKGS_TEMPLATE_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-packages-infra.tmpl"
511-#define APT_PRE_INVOKE_INFRA_PKGS_STATIC_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-packages-infra"
512-#define APT_PRE_INVOKE_MESSAGE_STATIC_PATH "/var/lib/ubuntu-advantage/messages/apt-pre-invoke-esm-service-status"
513-
514-#define ESM_APPS_PKGS_COUNT_TEMPLATE_VAR "{ESM_APPS_PKG_COUNT}"
515-#define ESM_APPS_PACKAGES_TEMPLATE_VAR "{ESM_APPS_PACKAGES}"
516-#define ESM_INFRA_PKGS_COUNT_TEMPLATE_VAR "{ESM_INFRA_PKG_COUNT}"
517-#define ESM_INFRA_PACKAGES_TEMPLATE_VAR "{ESM_INFRA_PACKAGES}"
518-
519-void process_all_templates();
520diff --git a/apt-hook/hook.cc b/apt-hook/hook.cc
521deleted file mode 100644
522index d8ec2e7..0000000
523--- a/apt-hook/hook.cc
524+++ /dev/null
525@@ -1,35 +0,0 @@
526-/*
527- * Copyright (C) 2018-2019 Canonical Ltd
528- * Author: Julian Andres Klode <juliank@ubuntu.com>
529- *
530- * This program is free software: you can redistribute it and/or modify
531- * it under the terms of the GNU General Public License as published by
532- * the Free Software Foundation, version 3 of the License.
533- *
534- * This package is distributed in the hope that it will be useful,
535- * but WITHOUT ANY WARRANTY; without even the implied warranty of
536- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
537- * GNU General Public License for more details.
538- *
539- * You should have received a copy of the GNU General Public License
540- * along with this program. If not, see <https://www.gnu.org/licenses/>.
541- *
542-*/
543-
544-#include <libintl.h>
545-#include <locale.h>
546-
547-#include "esm-templates.hh"
548-
549-int main(int argc, char *argv[])
550-{
551- (void) argc; // unused
552- (void) argv; // unused
553-
554- setlocale(LC_ALL, "");
555- textdomain("ubuntu-advantage");
556-
557- process_all_templates();
558-
559- return 0;
560-}
561diff --git a/apt-hook/json-hook.cc b/apt-hook/json-hook.cc
562index a107a3e..1d36bd2 100644
563--- a/apt-hook/json-hook.cc
564+++ b/apt-hook/json-hook.cc
565@@ -206,11 +206,11 @@ CloudID get_cloud_id() {
566 CloudID ret = NONE;
567 if (cloud_id_file.is_open()) {
568 std::string cloud_id_str((std::istreambuf_iterator<char>(cloud_id_file)), (std::istreambuf_iterator<char>()));
569- if (cloud_id_str == "aws") {
570+ if (cloud_id_str.find("aws") == 0) {
571 ret = AWS;
572- } else if (cloud_id_str == "azure") {
573+ } else if (cloud_id_str.find("azure") == 0) {
574 ret = AZURE;
575- } else if (cloud_id_str == "gce") {
576+ } else if (cloud_id_str.find("gce") == 0) {
577 ret = GCE;
578 }
579 cloud_id_file.close();
580@@ -239,7 +239,6 @@ struct ESMContext {
581 ESMContext get_esm_context() {
582 CloudID cloud_id = get_cloud_id();
583 bool is_x = is_xenial();
584- bool non_azure_cloud = cloud_id != NONE && cloud_id != AZURE;
585
586 ESMContext ret;
587 ret.context = "";
588diff --git a/debian/changelog b/debian/changelog
589index fff7487..29fcf04 100644
590--- a/debian/changelog
591+++ b/debian/changelog
592@@ -1,3 +1,41 @@
593+ubuntu-advantage-tools (27.14~23.04.1) lunar; urgency=medium
594+
595+ * d/ubuntu-advantage-tools.{postinst,postrm,preinst}:
596+ - migrate certain settings out of uaclient.conf to a new file managed by
597+ the pro config subcommand (LP: #2004280)
598+ * d/ubuntu-advantage-tools.postinst:
599+ - refactor PREVIOUS_PKG_VER as a global variable
600+ - simplify how we add notices
601+ * New upstream release 27.14 (LP: #2011477)
602+ - api: new u.unattended_upgrades.status.v1 endpoint for querying status of
603+ unattended upgrades
604+ - apt:
605+ + remove legacy apt-hook
606+ + deliver json apt-hook for interim releases
607+ + fix cloud identification logic in json apt-hook
608+ + make all calls to esm-cache isolated from system configuration
609+ (LP: #2008280)
610+ + only set up the esm cache on supported systems (LP: #2004018)
611+ - fix:
612+ + format the output to be more readable (LP: #1926182)
613+ + add option to attach during a fix without a token
614+ + verify if fixed version can be installed before trying (LP: #2006705)
615+ - livepatch: show warning if current kernel is not supported
616+ - locks: alert user about corrupted lock files (LP: #1996931)
617+ - logging: logs are now formatted as jsonlines
618+ - motd: remove esm-apps announcement
619+ - notices: new representation on disk as separate files (LP: #1987738)
620+ - realtime: remove ubuntu-realtime package on disablement
621+ - status:
622+ + removed contract info update check network call
623+ + no longer includes warnings about notices when non-root (LP: #2006138)
624+ + unattached status sends virt type to contract server for better
625+ resource availability calculation
626+ - timer jobs: add daily job to check for contract updates
627+ - yaml: always import distro-provided pyyaml (LP: #2007234, LP: #2007241)
628+
629+ -- Grant Orndorff <grant.orndorff@canonical.com> Mon, 13 Mar 2023 15:28:33 -0400
630+
631 ubuntu-advantage-tools (27.13.6~23.04.1) lunar; urgency=medium
632
633 * apt-news:
634diff --git a/debian/rules b/debian/rules
635index 48a17d2..09d805c 100755
636--- a/debian/rules
637+++ b/debian/rules
638@@ -66,11 +66,7 @@ override_dh_auto_install:
639
640 # We install the conf file even on non-LTS version to avoid issues on upgrade scenarios
641 make -C apt-hook DESTDIR=$(CURDIR)/debian/ubuntu-advantage-tools install-conf
642-
643-# Hooks will only be delivered on LTS instances
644-ifeq (LTS,$(findstring LTS,$(VERSION)))
645 make -C apt-hook DESTDIR=$(CURDIR)/debian/ubuntu-advantage-tools install
646-endif
647
648 # We want to guarantee that we are not shipping any conftest files
649 find $(CURDIR)/debian/ubuntu-advantage-tools -type f -name conftest.py -delete
650diff --git a/debian/ubuntu-advantage-tools.maintscript b/debian/ubuntu-advantage-tools.maintscript
651index a37d265..f4c89c9 100644
652--- a/debian/ubuntu-advantage-tools.maintscript
653+++ b/debian/ubuntu-advantage-tools.maintscript
654@@ -3,3 +3,4 @@ rm_conffile /etc/update-motd.d/80-esm 19.1~ ubuntu-advantage-tools
655 rm_conffile /etc/update-motd.d/80-livepatch 19.1~ ubuntu-advantage-tools
656 rm_conffile /etc/cron.daily/ubuntu-advantage-tools 19.1~ ubuntu-advantage-tools
657 rm_conffile /etc/init/ua-auto-attach.conf 20.2~ ubuntu-advantage-tools
658+rm_conffile /etc/update-motd.d/88-esm-announce 27.14~ ubuntu-advantage-tools
659diff --git a/debian/ubuntu-advantage-tools.postinst b/debian/ubuntu-advantage-tools.postinst
660index 5551478..7d9d03e 100644
661--- a/debian/ubuntu-advantage-tools.postinst
662+++ b/debian/ubuntu-advantage-tools.postinst
663@@ -57,6 +57,20 @@ APT_NEWS_FLAG_FILE="$UA_FLAGS_DIR/show-apt-news"
664
665 TMP_CANDIDATE_CACHE_PATH="/tmp/ubuntu-advantage/candidate-version"
666
667+NOTICES_DIR="/var/lib/ubuntu-advantage/notices"
668+TEMP_NOTICES_DIR="/run/ubuntu-advantage/notices"
669+
670+add_notice() {
671+ notice=$1
672+ mkdir -p $NOTICES_DIR
673+ touch $NOTICES_DIR/$notice
674+}
675+add_temp_notice() {
676+ notice=$1
677+ mkdir -p $TEMP_NOTICES_DIR
678+ touch $TEMP_NOTICES_DIR/$notice
679+}
680+
681 # Rename apt config files for ua services removing ubuntu release names
682 redact_ubuntu_release_from_ua_apt_filenames() {
683 DIR=$1
684@@ -140,27 +154,15 @@ esm_apps_cleanup() {
685 mark_reboot_for_fips_pro() {
686 FIPS_HOLDS=$(apt-mark showholds | grep -E 'fips|libssl1|openssh-client|openssh-server|linux-fips|openssl|strongswan' || exit 0)
687 if [ "$FIPS_HOLDS" ]; then
688- mark_reboot_cmds_as_needed FIPS_REBOOT_REQUIRED_MSG
689+ mark_reboot_cmds_as_needed
690+ add_temp_notice 20-fips_reboot_required
691 fi
692 }
693
694-
695-add_notice() {
696- msg_name=$1
697- /usr/bin/python3 -c "
698-from uaclient.config import UAConfig
699-from uaclient.messages import ${msg_name}
700-cfg = UAConfig(root_mode=True)
701-cfg.notice_file.add(label='', description=${msg_name})
702-"
703-}
704-
705 mark_reboot_cmds_as_needed() {
706- msg_name=$1
707 if [ ! -f "$REBOOT_CMD_MARKER_FILE" ]; then
708 touch $REBOOT_CMD_MARKER_FILE
709 fi
710- add_notice "$msg_name"
711 }
712
713 patch_status_json_0_1_for_non_root() {
714@@ -195,7 +197,7 @@ notify_wrong_fips_metapackage_on_cloud() {
715
716 if echo "$cloud_id" | grep -E -q "^(azure|aws)"; then
717 if echo "$fips_installed" | grep -E -q "installed"; then
718- add_notice NOTICE_WRONG_FIPS_METAPACKAGE_ON_CLOUD
719+ add_notice 25-wrong_fips_metapackage_on_cloud
720 fi
721 fi
722 }
723@@ -209,7 +211,6 @@ disable_new_timer_if_old_timer_already_disabled() {
724 # then we will assume that the user would want the
725 # ua-timer to be disabled as well. In that case, we will
726 # disable the ua-timer here.
727- PREVIOUS_PKG_VER=$1
728
729 # We should only perform this check on UA version that have the
730 # ua-messaging.timer: 27.0 until 27.2. This will also guarantee
731@@ -236,7 +237,6 @@ disable_new_timer_if_old_timer_already_disabled() {
732 }
733
734 remove_old_systemd_units() {
735- PREVIOUS_PKG_VER=$1
736 # These are the commands that are run when the package is purged.
737 # Since we actually want to remove this service from now on
738 # we have replicated that behavior here
739@@ -282,12 +282,11 @@ create_public_machine_token_file() {
740 from uaclient.files import MachineTokenFile
741 machine_token_file = MachineTokenFile()
742 content = machine_token_file.read()
743-machine_token_file.write(content=content)
744+machine_token_file.write(content)
745 "
746 }
747
748 migrate_ubuntu_pro_beta_banner() {
749- PREVIOUS_PKG_VER=$1
750 # This only shipped in 27.11.2~
751 if dpkg --compare-versions "$PREVIOUS_PKG_VER" ge "27.11.2~" \
752 && dpkg --compare-versions "$PREVIOUS_PKG_VER" lt "27.11.3~"; then
753@@ -302,6 +301,25 @@ migrate_ubuntu_pro_beta_banner() {
754 fi
755 fi
756 }
757+migrate_old_notices(){
758+ notices_file=/var/lib/ubuntu-advantage/notices.json
759+ # only run if notices.json is present
760+ if [ ! -f $notices_file ];then
761+ return
762+ fi
763+
764+ # This migration will happen for pro client versions <27.14 that still use notices.json.
765+ # Notices are generally short lived, so the chances of an upgrade happening while a
766+ # notice is in place is very small.
767+ # Despite that we do a simple migration here of the most important notices: reboot required notices.
768+ # All notices with "reboot" in them can be safely transformed into a generic reboot required message.
769+ # The new message won't include the exact reason for the reboot, but the recommended action is the same.
770+ if grep -q -i "reboot" $notices_file; then
771+ add_temp_notice 10-reboot_required
772+ fi
773+ rm -f $notices_file
774+}
775+
776
777 cleanup_candidate_version_stamp_permissions() {
778 if [ -f $TMP_CANDIDATE_CACHE_PATH ]; then
779@@ -315,6 +333,32 @@ cleanup_apt_news_flag_file() {
780 fi
781 }
782
783+cleanup_old_motd_files() {
784+ rm -rf $UA_MESSAGES_DIR/motd*
785+}
786+
787+migrate_user_config_post() {
788+ # LP: #2004280
789+ preinst_file="/etc/ubuntu-advantage/uaclient.conf.preinst-backup"
790+ bkp_file="/etc/ubuntu-advantage/uaclient.conf.dpkg-bak"
791+
792+ if [ -f /etc/ubuntu-advantage/uaclient.conf.preinst-backup ]; then
793+ # This script modifies the preinst-backup version of the file in-place
794+ /usr/bin/python3 /usr/lib/ubuntu-advantage/migrate_user_config.py
795+
796+ if cmp --silent $preinst_file $bkp_file; then
797+ # This should only happen if we failed to perform the migration.
798+ # Therefore, there is no need to keep the backup file around
799+ rm -f $bkp_file
800+ fi
801+
802+ # Overwrite uaclient.conf with the now-migrated version from preinst
803+ mv $preinst_file /etc/ubuntu-advantage/uaclient.conf
804+ # just in case this temp file was left behind
805+ rm -f /etc/ubuntu-advantage/uaclient.conf.preinst-backup-migrated-temp
806+ fi
807+}
808+
809 case "$1" in
810 configure)
811 PREVIOUS_PKG_VER=$2
812@@ -343,7 +387,7 @@ case "$1" in
813 # Repo for FIPS packages changed from old client
814 if [ -f $FIPS_APT_SOURCE_FILE ]; then
815 if grep -q $OLD_CLIENT_FIPS_PPA $FIPS_APT_SOURCE_FILE; then
816- add_notice FIPS_INSTALL_OUT_OF_DATE
817+ add_notice 22-fips_install_out_of_date
818 fi
819 fi
820
821@@ -369,7 +413,8 @@ case "$1" in
822
823 if [ "$VERSION_ID" = "16.04" ]; then
824 if echo "$PREVIOUS_PKG_VER" | grep -q "14.04"; then
825- mark_reboot_cmds_as_needed LIVEPATCH_LTS_REBOOT_REQUIRED
826+ mark_reboot_cmds_as_needed
827+ add_temp_notice 30-lp_lts_reboot_required
828 fi
829 if dpkg --compare-versions "$PREVIOUS_PKG_VER" lt "27.13~"; then
830 # Clean any unauthenticated ESM infra files previously inserted
831@@ -385,8 +430,8 @@ case "$1" in
832
833 mark_reboot_for_fips_pro
834 rm_old_license_check_marker
835- disable_new_timer_if_old_timer_already_disabled $PREVIOUS_PKG_VER
836- remove_old_systemd_units $PREVIOUS_PKG_VER
837+ disable_new_timer_if_old_timer_already_disabled
838+ remove_old_systemd_units
839 /usr/lib/ubuntu-advantage/cloud-id-shim.sh || true
840
841 # On old version of ubuntu-advantange-tools, we don't have a public
842@@ -395,27 +440,25 @@ case "$1" in
843 if [ -f $MACHINE_TOKEN_FILE ] && [ ! -f $PUBLIC_MACHINE_TOKEN_FILE ]; then
844 create_public_machine_token_file
845 fi
846- migrate_ubuntu_pro_beta_banner $PREVIOUS_PKG_VER
847+ migrate_ubuntu_pro_beta_banner
848 cleanup_candidate_version_stamp_permissions
849 if dpkg --compare-versions "$PREVIOUS_PKG_VER" lt "27.13~"; then
850 cleanup_apt_news_flag_file
851 fi
852
853-
854- # LP: #2003977
855- # The version gate is open ended, and should be closed when the apt_news
856- # configuration is moved away from a conffile.
857- if dpkg --compare-versions "$2" ge 27.11.3~; then
858- if [ -f /var/lib/ubuntu-advantage/preinst-detected-apt-news-disabled ]; then
859- # The preinst has left us a note to tell us that apt-news was
860- # previously disabled and should be re-disabled, so disable it
861- # and discard the note.
862- pro config set apt_news=false
863- rm /var/lib/ubuntu-advantage/preinst-detected-apt-news-disabled
864- fi
865- # Remove the conffile backup if it exists now that an error unwind is
866- # no longer possible
867- rm -f /etc/ubuntu-advantage/uaclient.conf.preinst-remove
868+ if dpkg --compare-versions "$PREVIOUS_PKG_VER" lt "27.14~"; then
869+ cleanup_old_motd_files
870+ migrate_old_notices
871+ migrate_user_config_post
872+ fi
873+
874+ if grep -q "ua_config:" /etc/ubuntu-advantage/uaclient.conf; then
875+ echo "Warning: uaclient.conf contains old ua_config field." >&2
876+ echo " Please do the following:" >&2
877+ echo " 1. Run 'pro config set field=value' for each field/value pair" >&2
878+ echo " present under ua_config in /etc/ubuntu-advantage/uaclient.conf" >&2
879+ echo " 2. Delete ua_config and all sub-fields in" >&2
880+ echo " /etc/ubuntu-advantage/uaclient.conf" >&2
881 fi
882 ;;
883 esac
884diff --git a/debian/ubuntu-advantage-tools.postrm b/debian/ubuntu-advantage-tools.postrm
885index 3f69ce8..c1bcdf5 100644
886--- a/debian/ubuntu-advantage-tools.postrm
887+++ b/debian/ubuntu-advantage-tools.postrm
888@@ -31,12 +31,9 @@ case "$1" in
889 remove_gpg_files
890 ;;
891 abort-install|abort-upgrade)
892- # LP: #2003977
893- # The version gate is open ended, and should be closed when the
894- # apt_news configuration is moved away from a conffile.
895- if dpkg --compare-versions "$2" ge 27.11.3~; then
896- rm -f /var/lib/ubuntu-advantage/preinst-detected-apt-news-disabled
897- [ -f /etc/ubuntu-advantage/uaclient.conf.preinst-remove ] && mv /etc/ubuntu-advantage/uaclient.conf.preinst-remove /etc/ubuntu-advantage/uaclient.conf
898+ # LP: #2004280
899+ if dpkg --compare-versions "$2" lt "27.14~"; then
900+ [ -f /etc/ubuntu-advantage/uaclient.conf.preinst-backup ] && mv /etc/ubuntu-advantage/uaclient.conf.preinst-backup /etc/ubuntu-advantage/uaclient.conf
901 fi
902 ;;
903 esac
904diff --git a/debian/ubuntu-advantage-tools.preinst b/debian/ubuntu-advantage-tools.preinst
905index a45c602..f7270bb 100644
906--- a/debian/ubuntu-advantage-tools.preinst
907+++ b/debian/ubuntu-advantage-tools.preinst
908@@ -2,100 +2,34 @@
909
910 set -e
911
912-remove_old_config_fields() {
913- PREVIOUS_PKG_VER="$1"
914- if dpkg --compare-versions "$PREVIOUS_PKG_VER" le "27.8"; then
915- if grep -q "^license_check_log_file:" /etc/ubuntu-advantage/uaclient.conf; then
916- sed -i '/^license_check_log_file:.*$/d' /etc/ubuntu-advantage/uaclient.conf || true
917- fi
918- fi
919-}
920
921-restore_previous_conffile() {
922- previous_pkg_version=$1
923- # Back up existing conffile in case of an error unwind
924- cp -a /etc/ubuntu-advantage/uaclient.conf /etc/ubuntu-advantage/uaclient.conf.preinst-remove
925-
926- if dpkg --compare-versions "$previous_pkg_version" ge 27.13.1~; then
927- # Restore the default conffile that shipped with 27.13.X
928- cat > /etc/ubuntu-advantage/uaclient.conf <<EOT
929-# Ubuntu Pro Client config file.
930-# If you modify this file, run "pro refresh config" to ensure changes are
931-# picked up by Ubuntu Pro Client.
932-
933-contract_url: https://contracts.canonical.com
934-data_dir: /var/lib/ubuntu-advantage
935-log_file: /var/log/ubuntu-advantage.log
936-log_level: debug
937-security_url: https://ubuntu.com/security
938-timer_log_file: /var/log/ubuntu-advantage-timer.log
939-daemon_log_file: /var/log/ubuntu-advantage-daemon.log
940-ua_config:
941- apt_http_proxy: null
942- apt_https_proxy: null
943- http_proxy: null
944- https_proxy: null
945- update_messaging_timer: 21600
946- metering_timer: 14400
947-EOT
948- else
949- # Restore the default conffile that shipped with 27.11.3 through 27.12
950- cat > /etc/ubuntu-advantage/uaclient.conf <<EOT
951-# Ubuntu Pro Client config file.
952-# If you modify this file, run "pro refresh config" to ensure changes are
953-# picked up by Ubuntu Pro Client.
954+migrate_user_config_pre() {
955+ if [ ! -f /etc/ubuntu-advantage/uaclient.conf ]; then
956+ return
957+ fi
958
959+ curr_conf_hash=$(md5sum /etc/ubuntu-advantage/uaclient.conf | awk '{print $1}')
960+ expected_conf_hash=$(dpkg-query --showformat='${Conffiles}\n' --show ubuntu-advantage-tools | grep /etc/ubuntu-advantage/uaclient.conf | awk '{print $2}')
961+
962+ if [ "$curr_conf_hash" != "$expected_conf_hash" ]; then
963+ # Back up existing conffile in case of an error unwind
964+ cp -a /etc/ubuntu-advantage/uaclient.conf /etc/ubuntu-advantage/uaclient.conf.preinst-backup
965+ # Create this backup in case the user has made some comments on the config file.
966+ # In that way, the user can retrive them if they want to
967+ cp -a /etc/ubuntu-advantage/uaclient.conf /etc/ubuntu-advantage/uaclient.conf.dpkg-bak
968+ # Insert the new about-to-be-installed uaclient.conf to avoid conffile prompts
969+ cat > /etc/ubuntu-advantage/uaclient.conf <<EOT
970 contract_url: https://contracts.canonical.com
971-data_dir: /var/lib/ubuntu-advantage
972-log_file: /var/log/ubuntu-advantage.log
973 log_level: debug
974-security_url: https://ubuntu.com/security
975-timer_log_file: /var/log/ubuntu-advantage-timer.log
976-daemon_log_file: /var/log/ubuntu-advantage-daemon.log
977-ua_config:
978- apt_http_proxy: null
979- apt_https_proxy: null
980- http_proxy: null
981- https_proxy: null
982- update_messaging_timer: 21600
983- update_status_timer: 43200
984- metering_timer: 14400
985 EOT
986- fi
987+ fi
988 }
989
990 case "$1" in
991 install|upgrade)
992- if [ -n "$2" ]; then
993- PREVIOUS_PKG_VER=$2
994- remove_old_config_fields "$PREVIOUS_PKG_VER"
995- fi
996-
997- # LP: #2003977
998- # If the user used "pro config set apt_news=false|true" previously,
999- # then we don't want a conffile prompt if they haven't otherwise
1000- # changed the conffile. In these two cases, restore the conffile back
1001- # to how it shipped, and then fix up in postinst if required. The
1002- # version gate is open ended, and should be closed when the apt_news
1003- # configuration is moved away from a conffile.
1004- if dpkg --compare-versions "$2" ge 27.11.3~; then
1005- if [ -f /etc/ubuntu-advantage/uaclient.conf ]; then
1006- conffile_hash=$(md5sum /etc/ubuntu-advantage/uaclient.conf|awk '{print $1}')
1007- case "$conffile_hash" in
1008- 038902993a843cac6cbe3efa4d1fcb92|f8049c664dff27e212a77aef514e4b64)
1009- # User had run "pro config set apt_news=false" with no other
1010- # conffile changes
1011- mkdir -p /var/lib/ubuntu-advantage
1012- touch /var/lib/ubuntu-advantage/preinst-detected-apt-news-disabled
1013- restore_previous_conffile $2
1014- ;;
1015- 3b01d7406cbb4ba628a9ffa57485d324|d9971401a6409032b1c9069236040dc4)
1016- # User had run "pro config set apt_news=true" with no other
1017- # conffile changes
1018- restore_previous_conffile $2
1019- ;;
1020- esac
1021- fi
1022+ # LP: #2004280
1023+ if dpkg --compare-versions "$2" lt "27.14~"; then
1024+ migrate_user_config_pre
1025 fi
1026 ;;
1027 esac
1028diff --git a/dev-docs/devdocs_styleguide.md b/dev-docs/devdocs_styleguide.md
1029new file mode 100644
1030index 0000000..818a189
1031--- /dev/null
1032+++ b/dev-docs/devdocs_styleguide.md
1033@@ -0,0 +1,152 @@
1034+# Documentation
1035+
1036+Our docs are hosted on [Read the Docs](https://readthedocs.com/). This page
1037+will explain how to contribute to the docs and build them locally.
1038+
1039+The documentation is *primarily* written in standard Markdown, but pages can
1040+be written in reStructuredText if you prefer.
1041+
1042+We also use the
1043+[MyST-Parser Sphinx extension](https://myst-parser.readthedocs.io/en/latest/intro.html).
1044+This causes all Markdown (.md) files to be parsed as MyST, and
1045+[enables the use of directives](https://myst-parser.readthedocs.io/en/latest/syntax/roles-and-directives.html),
1046+which can be awkward to achieve in standard Markdown.
1047+
1048+## Building the docs
1049+
1050+To build the docs for Ubuntu Pro Client, you can use a `tox` command. You can
1051+install `tox` on your machine by running the `make test` command. Once tox is
1052+installed, just run the command:
1053+
1054+```
1055+$ tox -e docs
1056+```
1057+
1058+The command will generate the HTML pages inside `docs/build`. The makefile
1059+target will build the documentation for you using Sphinx.
1060+
1061+Once built, the HTML files will be viewable in `docs/build/html/`. Use your web
1062+browser to open `index.html` to preview the site.
1063+
1064+## Style guide
1065+
1066+We use the [Canonical style guide](https://docs.ubuntu.com/styleguide/en) in
1067+our documentation, which is summarised below -- with a few additions relevant
1068+to our docs.
1069+
1070+### Language
1071+
1072+Where possible, text should be written in UK English. However, discretion and
1073+common sense can both be applied. For example, where text refers to code
1074+elements that exist in US English, the spelling of these elements should not
1075+be changed to UK English.
1076+
1077+### Voice
1078+
1079+Try to use active voice where possible, rather than the passive voice. The
1080+active voice is generally more concise and easier to read. As an example, you
1081+could say "we recommend" (active) rather than "it is recommended that"
1082+(passive).
1083+
1084+### Headings
1085+
1086+Headings should be written in sentence case. This means that only the first
1087+letter is capitalised (unless the header text refers to e.g., a product name
1088+that would normally be capitalised, such as "Ubuntu Pro Client").
1089+
1090+Ensure that you do not skip header levels when creating your document
1091+structure, i.e., that a section is followed by a subsection, and not a
1092+sub-subsection. Skipping header levels can lead to de-ranking of pages in
1093+search engines.
1094+
1095+Try to craft your headings to be descriptive, but as short as possible, to help
1096+readers understand what content to expect if they click on it.
1097+
1098+### Line length
1099+
1100+Please keep the line lengths to a maximum of **79** characters. This ensures
1101+that the pages and tables do not get so wide that side scrolling is required.
1102+
1103+### Links
1104+
1105+Where possible, use contextual text in your links to aid users with screen
1106+readers and other accessibility tools. For example, "check out our
1107+[documentation style guide](#links) is preferable to "click
1108+[here](#links) for more".
1109+
1110+### Code blocks
1111+
1112+Our documentation uses the
1113+[Sphinx extension "sphinx-copybutton"](https://sphinx-copybutton.readthedocs.io/en/latest/),
1114+which creates a small button on the right-hand side of code blocks for users to
1115+copy the code snippets we provide.
1116+
1117+The copied code will strip out any prompt symbols so that users can
1118+paste commands directly into their terminal. For user convenience, please
1119+ensure that if you show any code output, it is presented in a separate code
1120+block to the commands.
1121+
1122+Please also specify the language used in your code block, to make sure it
1123+renders with the correct syntax highlighting.
1124+
1125+### Vertical whitespace
1126+
1127+One newline between each section helps ensure readability of the documentation
1128+source code. Keeping paragraphs relatively short (up to ~5-6 sentences) aids in
1129+keeping the text readable when rendered to a web page. Some rST elements also
1130+require an empty newline before and after, so for consistency, ensure that all
1131+elements (tables, images, headers, etc) have a newline before and after.
1132+
1133+### Acronyms and jargon
1134+
1135+Acronyms are always capitalised (e.g., JSON, YAML, QEMU, LXD) in text.
1136+
1137+The first time an acronym is used on a page, it is best practice to introduce
1138+it by showing the expanded name followed by the acronym in parentheses. E.g.,
1139+Quick EMUlator (QEMU). If the acronym is *very* common (e.g., URL, HTTP), or
1140+you provide a link to a documentation page with these details, you do not need
1141+to include them.
1142+
1143+Avoid using jargon unless absolutely necessary, to keep our documentation
1144+accessible to as wide a range of users as possible. If jargon is unavoidable,
1145+consider including brief explanations to help the user keep up with the
1146+material.
1147+
1148+### Admonitions and callouts
1149+
1150+Notes, warnings, or other information you wish to draw the reader's attention
1151+to can be called out in an admonition block. If you are writing your code in
1152+Markdown, this is where the MyST extension comes in handy. Here is an example:
1153+
1154+````
1155+ ```{note}
1156+ The options are: note, important, hint, seealso, tip, attention, caution,
1157+ warning, danger, and error.
1158+ ```{warning}
1159+ Although it's possible to nest admonitions inside each other, it's better to
1160+ avoid doing that unless it's strictly necessary!
1161+ ```
1162+````
1163+
1164+```{note}
1165+The options are: note, important, hint, seealso, tip, attention, caution,
1166+warning, danger, and error.
1167+```{warning}
1168+Although it's possible to nest admonitions inside each other, it's better to
1169+avoid doing that unless it's strictly necessary!
1170+```
1171+
1172+## Organisation
1173+
1174+We follow the [principles of Diataxis](https://diataxis.fr/) in our
1175+documentation. When writing new docs, try to consider the purpose of the
1176+document and how the reader will probably use it. This will help you to decide
1177+which section it belongs in.
1178+
1179+### Getting advice
1180+
1181+If you are in any doubt, please contact our team's
1182+[Technical Author (Sally)](https://github.com/s-makin) for guidance. If you
1183+would like her to review any documentation, she would be very happy to help!
1184+Please also tag her as a reviewer on any PR that contains documentation
1185+elements.
1186diff --git a/dev-docs/howtoguides/building.md b/dev-docs/howtoguides/building.md
1187index 084a3a1..17be892 100644
1188--- a/dev-docs/howtoguides/building.md
1189+++ b/dev-docs/howtoguides/building.md
1190@@ -30,7 +30,7 @@ bash ./tools/setup_sbuild.sh
1191 debuild -S
1192 sbuild --dist=<target> ../ubuntu-advantage-tools_*.dsc
1193 # emulating different architectures in sbuild-launchpad-chroot
1194-sbuild-launchpad-chroot create --architecture="riscv64" "--name=focal-riscv64" "--series=focal
1195+sbuild-launchpad-chroot create --architecture="riscv64" "--name=focal-riscv64" "--series=focal"
1196 ```
1197
1198 > **Note**
1199diff --git a/dev-docs/howtoguides/detach_pro_instances.md b/dev-docs/howtoguides/detach_pro_instances.md
1200new file mode 100644
1201index 0000000..5bbf541
1202--- /dev/null
1203+++ b/dev-docs/howtoguides/detach_pro_instances.md
1204@@ -0,0 +1,25 @@
1205+# How to permanently detach Pro instances
1206+
1207+## TL;DR
1208+
1209+1. Modify the client configuration file, normally `/etc/ubuntu-advantage/uaclient.conf`,
1210+to contain:
1211+
1212+ ```yaml
1213+ features:
1214+ disable_auto_attach: true
1215+ ```
1216+
1217+2. Perform a `sudo pro detach --assume-yes`.
1218+
1219+## Explanation
1220+
1221+On Pro instances, a `pro detach` won't permanently detach them as,
1222+the instance will be reauto-attached on the next boot (on non GCE instances)
1223+or immediately (on GCE instances due to the daemon).
1224+
1225+The config in step 1 will prevent the [daemon](../../systemd/ubuntu-advantage.service)
1226+and the a [service](../../systemd/ua-auto-attach.service) at next boot to auto-reattach.
1227+
1228+If you want to allow the instance to reauto attach by itself, then remove or set to false
1229+`disable_auto_attach` in the configuration file.
1230diff --git a/dev-docs/howtoguides/testing.md b/dev-docs/howtoguides/testing.md
1231index f7872b8..fb0519a 100644
1232--- a/dev-docs/howtoguides/testing.md
1233+++ b/dev-docs/howtoguides/testing.md
1234@@ -16,6 +16,11 @@ Refresh your terminal to make sure pyenv is working. Then you can run the unit a
1235 tox
1236 ```
1237
1238+> **Note**
1239+> There are a number of `autouse` mocks in our unit tests. These are intended to prevent accidental side effects on the host system from running the unit tests, as well as prevent leaks of the system environment into the unit tests.
1240+> One such `autouse` mock tells the unit tests that they are run as root (unless the mock is overriden for a particular test).
1241+> These `autouse` mocks have helped, but may not be preventing all side effects or environment leakage.
1242+
1243 The client also includes built-in dep8 tests. These are run as follows:
1244
1245 ```shell
1246diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css
1247new file mode 100644
1248index 0000000..49efd28
1249--- /dev/null
1250+++ b/docs/_static/css/custom.css
1251@@ -0,0 +1,240 @@
1252+/** Fix the font weight (300 for normal, 400 for slightly bold) **/
1253+/** Should be 100 for all headers, 400 for normal text **/
1254+
1255+h1, h2, h3, h4, h5, h6, .sidebar-tree .current-page>.reference, button, input, optgroup, select, textarea, th.head {
1256+ font-weight: 200;
1257+}
1258+
1259+.toc-title {
1260+ font-weight: 400;
1261+}
1262+
1263+div.page, li.scroll-current>.reference, dl.glossary dt, dl.simple dt, dl:not([class]) dt {
1264+ font-weight: 300;
1265+ line-height: 1.5;
1266+ font-size: var(--font-size--normal);
1267+}
1268+
1269+
1270+/** Side bars (side-bar tree = left, toc-tree = right) **/
1271+div.sidebar-tree {
1272+ font-weight: 200;
1273+ line-height: 1.5;
1274+ font-size: var(--font-size--normal);
1275+}
1276+
1277+div.toc-tree {
1278+ font-weight: 200;
1279+ font-size: var(--font-size--medium);
1280+ line-height: 1.5;
1281+}
1282+
1283+.sidebar-tree .toctree-l1>.reference, .toc-tree li.scroll-current>.reference {
1284+ font-weight: 400;
1285+}
1286+
1287+/** List styling **/
1288+ol, ul {
1289+ margin-bottom: 1.5rem;
1290+ margin-left: 1rem;
1291+ margin-top: 0;
1292+ padding-left: 1rem;
1293+}
1294+
1295+/** Table styling **/
1296+
1297+th.head {
1298+ text-transform: uppercase;
1299+ font-size: var(--font-size--small);
1300+}
1301+
1302+table.docutils {
1303+ border: 0;
1304+ box-shadow: none;
1305+ width:100%;
1306+}
1307+
1308+table.docutils td, table.docutils th, table.docutils td:last-child, table.docutils th:last-child, table.docutils td:first-child, table.docutils th:first-child {
1309+ border-right: none;
1310+ border-left: none;
1311+}
1312+
1313+/* center align table cells with ":-:" */
1314+td.text-center {
1315+ text-align: center;
1316+}
1317+
1318+/** No rounded corners **/
1319+
1320+.admonition, code.literal, .sphinx-tabs-tab, .sphinx-tabs-panel, .highlight {
1321+ border-radius: 0;
1322+}
1323+
1324+/** code blocks and literals **/
1325+code.docutils.literal.notranslate, .highlight pre, pre.literal-block {
1326+ font-size: var(--font-size--medium);
1327+}
1328+
1329+
1330+/** Admonition styling **/
1331+
1332+.admonition {
1333+ font-size: var(--font-size--medium);
1334+ box-shadow: none;
1335+}
1336+
1337+/** Styling for links **/
1338+/* unvisited link */
1339+a:link {
1340+ color: #06c;
1341+ text-decoration: none;
1342+}
1343+
1344+/* visited link */
1345+a:visited {
1346+ color: #7d42b8;
1347+ text-decoration: none;
1348+}
1349+
1350+/* mouse over link */
1351+a:hover {
1352+ text-decoration: underline;
1353+}
1354+
1355+/* selected link */
1356+a:active {
1357+ text-decoration: underline;
1358+}
1359+
1360+a.sidebar-brand.centered {
1361+ text-decoration: none;
1362+}
1363+
1364+/** Color for the "copy link" symbol next to headings **/
1365+
1366+a.headerlink {
1367+ color: var(--color-brand-primary);
1368+}
1369+
1370+/** Line to the left of the current navigation entry **/
1371+
1372+.sidebar-tree li.current-page {
1373+ border-left: 2px solid var(--color-brand-primary);
1374+}
1375+
1376+/** Some tweaks for issue #16 **/
1377+
1378+[role="tablist"] {
1379+ border-bottom: 1px solid var(--color-sidebar-item-background--hover);
1380+}
1381+
1382+.sphinx-tabs-tab[aria-selected="true"] {
1383+ border: 0;
1384+ border-bottom: 2px solid var(--color-brand-primary);
1385+ background-color: var(--color-sidebar-item-background--current);
1386+ font-weight:300;
1387+}
1388+
1389+.sphinx-tabs-tab{
1390+ color: var(--color-brand-primary);
1391+ font-weight:300;
1392+}
1393+
1394+.sphinx-tabs-panel {
1395+ border: 0;
1396+ border-bottom: 1px solid var(--color-sidebar-item-background--hover);
1397+ background: var(--color-background-primary);
1398+}
1399+
1400+button.sphinx-tabs-tab:hover {
1401+ background-color: var(--color-sidebar-item-background--hover);
1402+}
1403+
1404+/** Custom classes to fix scrolling in tables by decreasing the
1405+ font size or breaking certain columns.
1406+ Specify the classes in the Markdown file with, for example:
1407+ ```{rst-class} break-col-4 min-width-4-8
1408+ ```
1409+**/
1410+
1411+table.dec-font-size {
1412+ font-size: smaller;
1413+}
1414+table.break-col-1 td.text-left:first-child {
1415+ word-break: break-word;
1416+}
1417+table.break-col-4 td.text-left:nth-child(4) {
1418+ word-break: break-word;
1419+}
1420+table.min-width-1-15 td.text-left:first-child {
1421+ min-width: 15em;
1422+}
1423+table.min-width-4-8 td.text-left:nth-child(4) {
1424+ min-width: 8em;
1425+}
1426+
1427+/** Underline for abbreviations **/
1428+
1429+abbr[title] {
1430+ text-decoration: underline solid #cdcdcd;
1431+}
1432+
1433+/** Use the same style for right-details as for left-details **/
1434+.bottom-of-page .right-details {
1435+ font-size: var(--font-size--small);
1436+ display: block;
1437+}
1438+
1439+/** Version switcher */
1440+button.version_select {
1441+ color: var(--color-foreground-primary);
1442+ background-color: var(--color-toc-background);
1443+ padding: 5px 10px;
1444+ border: none;
1445+}
1446+
1447+.version_select:hover, .version_select:focus {
1448+ background-color: var(--color-sidebar-item-background--hover);
1449+}
1450+
1451+.version_dropdown {
1452+ position: relative;
1453+ display: inline-block;
1454+ text-align: right;
1455+ font-size: var(--sidebar-item-font-size);
1456+}
1457+
1458+.available_versions {
1459+ display: none;
1460+ position: absolute;
1461+ right: 0px;
1462+ background-color: var(--color-toc-background);
1463+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
1464+ z-index: 11;
1465+}
1466+
1467+.available_versions a {
1468+ color: var(--color-foreground-primary);
1469+ padding: 12px 16px;
1470+ text-decoration: none;
1471+ display: block;
1472+}
1473+
1474+.available_versions a:hover {background-color: var(--color-sidebar-item-background--current)}
1475+
1476+.show {display:block;}
1477+
1478+/** Fix for nested numbered list - the nested list is lettered **/
1479+ol.arabic ol.arabic {
1480+ list-style: lower-alpha;
1481+}
1482+
1483+/** Make expandable sections look like links **/
1484+details summary {
1485+ color: var(--color-link);
1486+}
1487+
1488+/** Context links at the bottom of the page **/
1489+footer {
1490+ font-size: var(--font-size--medium);
1491+}
1492diff --git a/docs/_static/css/github_issue_links.css b/docs/_static/css/github_issue_links.css
1493index d72a145..af4be86 100644
1494--- a/docs/_static/css/github_issue_links.css
1495+++ b/docs/_static/css/github_issue_links.css
1496@@ -4,4 +4,21 @@
1497 .github-issue-link {
1498 font-size: var(--font-size--small);
1499 font-weight: bold;
1500+ background-color: #DD4814;
1501+ padding: 13px 23px;
1502+ text-decoration: none;
1503+}
1504+.github-issue-link:link {
1505+ color: #FFFFFF;
1506+}
1507+.github-issue-link:visited {
1508+ color: #FFFFFF
1509+}
1510+.muted-link.github-issue-link:hover {
1511+ color: #FFFFFF;
1512+ text-decoration: underline;
1513+}
1514+.github-issue-link:active {
1515+ color: #FFFFFF;
1516+ text-decoration: underline;
1517 }
1518diff --git a/docs/_static/js/github_issue_links.js b/docs/_static/js/github_issue_links.js
1519index 162706a..e449b4e 100644
1520--- a/docs/_static/js/github_issue_links.js
1521+++ b/docs/_static/js/github_issue_links.js
1522@@ -4,7 +4,7 @@ window.onload = function() {
1523 link.classList.add("github-issue-link");
1524 link.text = "Have a question?";
1525 link.href = (
1526- "https://github.com/canonical/ubuntu-advantage-client/issues/new?"
1527+ "https://github.com/canonical/ubuntu-pro-client/issues/new?"
1528 + "title=docs%3A+TYPE+YOUR+QUESTION+HERE"
1529 + "&body=*Please describe the question or issue you're facing with "
1530 + `"${document.title}"`
1531diff --git a/docs/conf.py b/docs/conf.py
1532index a803a70..8dd4d59 100644
1533--- a/docs/conf.py
1534+++ b/docs/conf.py
1535@@ -14,18 +14,20 @@
1536 # import sys
1537 # sys.path.insert(0, os.path.abspath('.'))
1538
1539+import datetime
1540
1541 # -- Project information -----------------------------------------------------
1542
1543 project = "Ubuntu Pro Client"
1544-copyright = "2022, Canonical Ltd."
1545-
1546+author = "Canonical Group Ltd"
1547+copyright = "%s, %s" % (datetime.date.today().year, author)
1548
1549 # -- General configuration ---------------------------------------------------
1550
1551 # Add any Sphinx extension module names here, as strings. They can be
1552 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
1553 # ones.
1554+
1555 extensions = [
1556 "myst_parser",
1557 "sphinx_copybutton",
1558@@ -33,26 +35,62 @@ extensions = [
1559 ]
1560
1561 # Add any paths that contain templates here, relative to this directory.
1562+
1563 templates_path = ["_templates"]
1564
1565 # List of patterns, relative to source directory, that match files and
1566 # directories to ignore when looking for source files.
1567 # This pattern also affects html_static_path and html_extra_path.
1568+
1569 exclude_patterns = []
1570
1571 # It seems we need to request creation of automatic anchors for our headings.
1572 # Setting to 2 because that's what we need now.
1573 # If referencing any heading of lesser importance, adjust here.
1574-myst_heading_anchors = 2
1575+
1576+myst_heading_anchors = 3
1577
1578
1579 # -- Options for HTML output -------------------------------------------------
1580
1581 # The theme to use for HTML and HTML Help pages. See the documentation for
1582-# a list of builtin themes.
1583-#
1584+# a list of builtin themes:
1585+# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
1586+
1587 html_theme = "furo"
1588 html_logo = "_static/circle_of_friends.png"
1589+html_theme_options = {
1590+ "light_css_variables": {
1591+ "color-sidebar-background-border": "none",
1592+ "font-stack": "Ubuntu, -apple-system, Segoe UI, Roboto, Oxygen, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif",
1593+ "font-stack--monospace": "Ubuntu Mono variable, Ubuntu Mono, Consolas, Monaco, Courier, monospace",
1594+ "color-foreground-primary": "#111",
1595+ "color-foreground-secondary": "var(--color-foreground-primary)",
1596+ "color-foreground-muted": "#333",
1597+ "color-background-secondary": "#FFF",
1598+ "color-background-hover": "#f2f2f2",
1599+ "color-brand-primary": "#111",
1600+ "color-brand-content": "#06C",
1601+ "color-inline-code-background": "rgba(0,0,0,.03)",
1602+ "color-sidebar-link-text": "#111",
1603+ "color-sidebar-item-background--current": "#ebebeb",
1604+ "color-sidebar-item-background--hover": "#f2f2f2",
1605+ "sidebar-item-line-height": "1.3rem",
1606+ "color-link-underline": "var(--color-background-primary)",
1607+ "color-link-underline--hover": "var(--color-background-primary)",
1608+ },
1609+ "dark_css_variables": {
1610+ "color-foreground-secondary": "var(--color-foreground-primary)",
1611+ "color-foreground-muted": "#CDCDCD",
1612+ "color-background-secondary": "var(--color-background-primary)",
1613+ "color-background-hover": "#666",
1614+ "color-brand-primary": "#fff",
1615+ "color-brand-content": "#06C",
1616+ "color-sidebar-link-text": "#f7f7f7",
1617+ "color-sidebar-item-background--current": "#666",
1618+ "color-sidebar-item-background--hover": "#333",
1619+ },
1620+}
1621
1622 # Add any paths that contain custom static files (such as style sheets) here,
1623 # relative to this directory. They are copied after the builtin static files,
1624@@ -62,6 +100,7 @@ html_static_path = ["_static"]
1625 html_css_files = [
1626 "css/logo.css",
1627 "css/github_issue_links.css",
1628+ "css/custom.css"
1629 ]
1630 html_js_files = [
1631 "js/github_issue_links.js",
1632diff --git a/docs/explanations.rst b/docs/explanations.rst
1633index e27f11f..a424451 100644
1634--- a/docs/explanations.rst
1635+++ b/docs/explanations.rst
1636@@ -5,11 +5,50 @@ Our explanatory and conceptual guides are written to provide a better
1637 understanding of how the Ubuntu Pro Client (``pro``) works. They enable you
1638 to expand your knowledge and become better at using and configuring ``pro``.
1639
1640-Explanation
1641-===========
1642+Messaging
1643+=========
1644+
1645+Here you'll find details about Ubuntu Pro Client-related APT and MOTD messages
1646+-- what they are, when they are used and how they work.
1647
1648 .. toctree::
1649 :maxdepth: 1
1650- :glob:
1651
1652- explanations/*
1653+ Pro-related APT messages <explanations/apt_messages.md>
1654+ Pro-related MOTD messages <explanations/motd_messages.md>
1655+
1656+Commands
1657+========
1658+
1659+Some of the commands in ``pro`` do more than you think. Here we'll show you a
1660+selection of some of the commands -- what they do, and how they work.
1661+
1662+.. toctree::
1663+ :maxdepth: 1
1664+
1665+ explanations/how_to_interpret_the_security_status_command.md
1666+ explanations/status_columns.md
1667+ explanations/what_refresh_does.md
1668+
1669+Public Cloud Ubuntu Pro
1670+=======================
1671+
1672+Here we talk about Ubuntu Pro images for AWS, Azure and GCP, and the related
1673+tooling: the ``ubuntu-advantage-pro`` package.
1674+
1675+.. toctree::
1676+ :maxdepth: 1
1677+
1678+ explanations/what_are_ubuntu_pro_cloud_instances.md
1679+ explanations/what_is_the_ubuntu_advantage_pro_package.md
1680+
1681+Other Pro features explained
1682+============================
1683+
1684+.. toctree::
1685+ :maxdepth: 1
1686+
1687+ explanations/what_are_the_timer_jobs.md
1688+ explanations/what_is_the_daemon.md
1689+ explanations/why_trusty_is_no_longer_supported.md
1690+ explanations/errors_explained.md
1691diff --git a/docs/explanations/apt_messages.md b/docs/explanations/apt_messages.md
1692index 2201442..d4e62ef 100644
1693--- a/docs/explanations/apt_messages.md
1694+++ b/docs/explanations/apt_messages.md
1695@@ -1,131 +1,155 @@
1696-# Ubuntu Pro related APT messages
1697+# Ubuntu Pro-related APT messages
1698
1699-When running some APT commands, you might see Ubuntu Pro related messages on
1700+When running some APT commands, you might see Ubuntu Pro-related messages in
1701 the output of those commands. Currently, we deliver those messages when
1702-running either `apt-get upgrade` or `apt-get dist-upgrade` commands. The scenarios
1703+running either `apt upgrade` or `apt dist-upgrade`. The scenarios
1704 where we deliver those messages are:
1705
1706-* **ESM series with esm-infra service disabled**: When you are running a machine
1707- with an ESM series, like Xenial, we advertise the `esm-infra` service if packages could
1708- be upgraded by enabling the service:
1709-
1710- ```
1711- Reading package lists... Done
1712- Building dependency tree
1713- Reading state information... Done
1714- Calculating upgrade... Done
1715- The following package was automatically installed and is no longer required:
1716- libfreetype6
1717- Use 'apt autoremove' to remove it.
1718- Get more security updates through Ubuntu Pro with 'esm-infra' enabled
1719- libpam0g libpam-modules openssl ntfs-3g git-man libsystemd0 squashfs-tools git openssh-sftp-server udev libpam-runtime isc-dhcp-common libx11-6 libudev1 apport python3-apport systemd-sysv liblz4-1 libpam-systemd systemd libpam-modules-bin openssh-server libx11-data openssh-client libxml2 curl isc-dhcp-client python3-problem-report libcurl3-gnutls libssl1.0.0
1720- Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04
1721- ```
1722-
1723- Note that the ESM message is located in the middle of the `apt-get` command output. Additionally,
1724- if there are no packages to upgrade at the moment, we would instead deliver:
1725-
1726- ```
1727- Receive additional future security updates with Ubuntu Pro.
1728- Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04
1729- ```
1730-
1731- ```{note}
1732- If the user is using a LTS series instead, we will advertise `esm-apps`.
1733- ```
1734-
1735-* **esm package count**: If both ESM services are enabled on the system,
1736- we deliver a package count related to each service near the end of the `apt-get` command:
1737-
1738- ```
1739- 1 standard LTS security update, 29 esm-infra security updates and 8 esm-apps security updates
1740- ```
1741-
1742- We only deliver that message if the service is enabled and we did upgrade packages related
1743- to it. For example, if we had no `esm-infra` package upgrades, the message would be:
1744-
1745- ```
1746- 1 standard LTS security update and 8 esm-apps security updates
1747- ```
1748-
1749-* **expired contract**: If we detect that your contract is expired, we will deliver the following
1750- message advertising `esm-infra` in the middle of the `apt` command:
1751-
1752- ```
1753- *Your Ubuntu Pro subscription has EXPIRED*
1754- Get more security updates through Ubuntu Pro with 'esm-infra' enabled
1755- libpam0g libpam-modules openssl ntfs-3g git-man libsystemd0 squashfs-tools git openssh-sftp-server udev libpam-runtime isc-dhcp-common libx11-6 libudev1 apport python3-apport systemd-sysv liblz4-1 libpam-systemd systemd libpam-modules-bin openssh-server libx11-data openssh-client libxml2 curl isc-dhcp-client python3-problem-report libcurl3-gnutls libssl1.0.0
1756- Renew your service at https://ubuntu.com/pro
1757- ```
1758+## ESM series with esm-infra service disabled
1759+
1760+When you run `apt upgrade` on an ESM release, like Xenial, we advertise
1761+the `esm-infra` service if packages could be upgraded by enabling the service:
1762+
1763+```
1764+Reading package lists... Done
1765+Building dependency tree
1766+Reading state information... Done
1767+Calculating upgrade... Done
1768+The following package was automatically installed and is no longer required:
1769+ libfreetype6
1770+ Use 'apt autoremove' to remove it.
1771+The following security updates require Ubuntu Pro with 'esm-infra' enabled:
1772+ libpam0g libpam-modules openssl ntfs-3g git-man libsystemd0 squashfs-tools git openssh-sftp-server udev libpam-runtime isc-dhcp-common libx11-6 libudev1 apport python3-apport systemd-sysv liblz4-1 libpam-systemd systemd libpam-modules-bin openssh-server libx11-data openssh-client libxml2 curl isc-dhcp-client python3-problem-report libcurl3-gnutls libssl1.0.0
1773+Learn more about Ubuntu Pro for 16.04 at https://ubuntu.com/16-04
1774+```
1775+
1776+## LTS series with esm-apps service disabled
1777+
1778+When you are running `apt upgraded` on a LTS release, like Focal, we advertise
1779+the `esm-apps` service if packages could be upgraded by enabling the service:
1780+
1781+```
1782+Reading package lists... Done
1783+Building dependency tree
1784+Reading state information... Done
1785+Calculating upgrade... Done
1786+The following package was automatically installed and is no longer required:
1787+ libfreetype6
1788+Use 'apt autoremove' to remove it.
1789+Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
1790+ adminer editorconfig ansible
1791+Learn more about Ubuntu Pro at https://ubuntu.com/pro
1792+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
1793+```
1794+
1795+## ESM package count
1796+
1797+If both ESM services are enabled on the system, we deliver a package count
1798+related to each service near the end of the `apt` command:
1799+
1800+```
1801+1 standard LTS security update, 29 esm-infra security updates and 8 esm-apps security updates
1802+```
1803+
1804+We only deliver this message if the service is enabled *and* we upgraded
1805+packages related to it. For example, if we had no `esm-infra` package upgrades,
1806+the message would be:
1807+
1808+```
1809+1 standard LTS security update and 8 esm-apps security updates
1810+```
1811+
1812+## Expired contract
1813+
1814+If we detect that your contract is expired, we will deliver the following
1815+message advertising `esm-infra` in the middle of the `apt upgrade` command:
1816+
1817+```
1818+#
1819+# *Your Ubuntu Pro subscription has EXPIRED*
1820+# 10 additional security update(s) require Ubuntu Pro with '{service}' enabled.
1821+# Renew your service at https://ubuntu.com/pro
1822+#
1823+```
1824
1825- Note that if we don't have any package to upgrade related to `esm-infra`, we would deliver instead
1826- the message:
1827-
1828- ```
1829- *Your Ubuntu Pro subscription has EXPIRED*
1830- Renew your service at https://ubuntu.com/pro
1831- ```
1832-
1833-* **contract is about to expire**: Similarly, if we detect that your contract is about to expire,
1834- we deliver the following message in the middle of the `apt-get` command:
1835-
1836- ```
1837- CAUTION: Your Ubuntu Pro subscription will expire in 2 days.
1838- Renew your subscription at https://ubuntu.com/pro to ensure continued security
1839- coverage for your applications.
1840- ```
1841-
1842-* **contract expired, but in grace period**: Additionally, if we detect that the contract is
1843- expired, but still in the grace period, the following message will be seen in the middle
1844- of the `apt-get` command:
1845-
1846- ```
1847- CAUTION: Your Ubuntu Pro subscription expired on 10 Sep 2021.
1848- Renew your subscription at https://ubuntu.com/pro to ensure continued security
1849- coverage for your applications.
1850- Your grace period will expire in 8 days.
1851- ```
1852+If we don't have any `esm-infra`-related packages to upgrade, we would show the
1853+following message instead:
1854
1855-```{note}
1856-For contract expired messages, we only advertise `esm-infra`.
1857+```
1858+#
1859+# *Your Ubuntu Pro subscription has EXPIRED*
1860+# Renew your service at https://ubuntu.com/pro
1861+#
1862+```
1863+
1864+## Contract is about to expire
1865+
1866+Similarly, if we detect that your contract is about to expire, we deliver the
1867+following message in the middle of the `apt` command:
1868+
1869+```
1870+#
1871+# CAUTION: Your Ubuntu Pro subscription will expire in 2 days.
1872+# Renew your subscription at https://ubuntu.com/pro to ensure continued
1873+# security coverage for your applications.
1874+#
1875+```
1876+
1877+## Contract has expired, but still in grace period
1878+
1879+Additionally, if we detect that the contract has expired, but is still in the
1880+grace period, the following message will be seen in the middle of the `apt`
1881+command output:
1882+
1883+```
1884+#
1885+# CAUTION: Your Ubuntu Pro subscription expired on 10 Sep 2021.
1886+# Renew your subscription at https://ubuntu.com/pro to ensure continued
1887+# security coverage for your applications.
1888+# Your grace period will expire in 11 days.
1889+#
1890 ```
1891
1892+## How are the APT messages generated?
1893
1894-## How are the APT messages generated
1895+We have two distinct `apt` hooks that allow us to deliver these messages when
1896+you run `apt upgrade` or `apt dist-upgrade`. They are:
1897
1898-We have two distinct `apt` hooks that allow us to deliver those messages when you
1899-are running `apt-get upgrade` or `apt-get dist-upgrade`, they are:
1900+### `apt-esm-hook`
1901
1902-* **apt-esm-hook**: Responsible for delivering the contract expired and ESM services
1903- advertising. However, the messaging here is created by two distinct steps:
1904+Responsible for populating templates with accurate package counts (i.e. the package
1905+count we see on the Expired contract messages).
1906+However, the messaging here is created by two distinct steps:
1907
1908- 1. Our [update_messages](what_are_the_timer_jobs.md) timer job create templates for
1909- the APT messages this hook will deliver. We cannot create the full message on the
1910- timer job, because we need the accurate package names and count. That information
1911- can only be obtained when running the `apt-get` command.
1912+1. Our [update_messages](what_are_the_timer_jobs.md) timer job creates
1913+ templates for the APT messages this hook will deliver. We cannot create the
1914+ full message on the timer job, because we need the accurate package names
1915+ and count. This information can only be obtained when running the `apt`
1916+ command.
1917
1918- ```{note}
1919- These templates will only be produced if some conditions are met. For example,
1920- we only produce expired contract templates if the contracts are indeed expired.
1921- ```
1922+ ```{note}
1923+ These templates will only be produced if certain conditions are met. For
1924+ example, we only produce "expired contract" templates if the contracts are
1925+ indeed expired.
1926+ ```
1927
1928- 2. When you run either `apt-get upgrade` or `apt-get dist-upgrade`, the hook searches
1929- for these templates and if they exist, they are populated with the right `apt`
1930- content and delivered to the user.
1931+2. When you run either `apt upgrade` or `apt dist-upgrade`, the hook
1932+ searches for these templates and if they exist, they are populated with the
1933+ correct `apt` content and delivered to the user.
1934
1935-* **apt-esm-json-hook**: The json hook is responsible for delivering the package count
1936- message we mentioned on the `esm package count` item. This hook is used because
1937- to inject that message on the exact place we want, we need to use a specific apt`
1938- [json hook](https://salsa.debian.org/apt-team/apt/-/blob/main/doc/json-hooks-protocol.md)
1939- to communicate with.
1940+### `apt-esm-json-hook`
1941
1942+The JSON hook is responsible for delivering the rest of the message we have presented here.
1943+This hook is used to inject the message in the exact place we want, so we need to use a specific `apt`
1944+[JSON hook](https://salsa.debian.org/apt-team/apt/-/blob/main/doc/json-hooks-protocol.md)
1945+to communicate with it.
1946
1947 ```{note}
1948 Those hooks are only delivered on LTS releases. This is because the hooks will
1949 not deliver useful messages on non-LTS due to lack of support for ESM services.
1950 ```
1951
1952-## How are APT configured to deliver those messages
1953+## How are APT configured to deliver those messages?
1954
1955 We currently ship the package the `20apt-esm-hook.conf` configuration that
1956 configures both the basic apt hooks to call our `apt-esm-hook` binary, and also
1957diff --git a/docs/explanations/errors_explained.md b/docs/explanations/errors_explained.md
1958new file mode 100644
1959index 0000000..6739e8b
1960--- /dev/null
1961+++ b/docs/explanations/errors_explained.md
1962@@ -0,0 +1,101 @@
1963+# Errors you may encounter and their meaning
1964+
1965+If you encounter an error or warning message from Pro Client that you don't understand and cannot find it in this document, please click "Have a question?" at the top of the page and let us know so that we can add it.
1966+
1967+## User Configuration Migration in version 27.14
1968+
1969+Version 27.14 of Ubuntu Pro Client changed how some user configuration settings are stored on disk. It moved several settings out of `/etc/ubuntu-advantage/uaclient.conf` and into a file managed solely by the `pro config {set,unset,show}` subcommands.
1970+
1971+Most settings should've gotten automatically migrated to the new file when Pro Client upgraded. If something failed you may see one of the following messages:
1972+
1973+### Migration error 1
1974+**Error message:**
1975+```
1976+Warning: Failed to load /etc/ubuntu-advantage/uaclient.conf
1977+ No automatic migration will occur.
1978+ You may need to use "pro config set" to re-set your settings.
1979+```
1980+
1981+**Where you'll see it:**
1982+
1983+During an `apt upgrade` or `apt install ubuntu-advantage-tools`
1984+
1985+**What does it mean:**
1986+
1987+This means that `/etc/ubuntu-advantage/uaclient.conf` was unable to be read or unable to be parsed as yaml during the migration.
1988+
1989+**What you can do about it:**
1990+
1991+Check the contents of `/etc/ubuntu-advantage/uaclient.conf`.
1992+1. Ensure it is valid yaml
1993+2. For any setting that is nested under `ua_config`:
1994+ - If you modified the value in the past: run `pro config set field_name=your_custom_value`
1995+ - delete the setting from `/etc/ubuntu-advantage/uaclient.conf`
1996+ - delete the `ua_config:` line from `/etc/ubuntu-advantage/uaclient.conf`
1997+
1998+### Migration error 2
1999+**Error message:**
2000+```
2001+Warning: Failed to migrate user_config from /etc/ubuntu-advantage/uaclient.conf
2002+ Please run the following to keep your custom settings:
2003+ pro config set example=example
2004+```
2005+
2006+**Where you'll see it:**
2007+
2008+During an `apt upgrade` or `apt install ubuntu-advantage-tools`
2009+
2010+**What does it mean:**
2011+
2012+This means that `/var/lib/ubuntu-advantage/user-config.json` was unable to be written or a json serialization error occurred.
2013+
2014+**What you can do about it:**
2015+
2016+Run each of the `pro config set` commands recommended in the warning message.
2017+
2018+### Migration error 3
2019+**Error message:**
2020+```
2021+Warning: Failed to migrate /etc/ubuntu-advantage/uaclient.conf
2022+ Please add following to uaclient.conf to keep your config:
2023+ example: example
2024+```
2025+
2026+**Where you'll see it:**
2027+
2028+During an `apt upgrade` or `apt install ubuntu-advantage-tools`
2029+
2030+**What does it mean:**
2031+
2032+This means that `/etc/ubuntu-advantage/uaclient.conf` was unable to be written or a yaml serialization error occurred.
2033+
2034+**What you can do about it:**
2035+
2036+Ensure that the settings listed in the warning output make it into your new uaclient.conf.
2037+
2038+### Warnings in versions >=27.14~
2039+
2040+**Error message:**
2041+```
2042+legacy "ua_config" found in uaclient.conf
2043+```
2044+or
2045+```
2046+Warning: uaclient.conf contains old ua_config field.
2047+```
2048+
2049+**Where you'll see it:**
2050+
2051+In `/var/log/ubuntu-advantage.log` after using the `pro` cli or during an `apt upgrade` to a newer version of ubuntu-advantage-tools.
2052+
2053+**What does it mean:**
2054+
2055+This means that there are still settings nested under `ua_config` in `/etc/ubuntu-advantage/uaclient.conf`. These will still be honored, but support may be removed in the future.
2056+
2057+**What you can do about it:**
2058+
2059+Check the contents of `/etc/ubuntu-advantage/uaclient.conf`.
2060+For any setting that is nested under `ua_config`:
2061+- If you modified the value in the past: run `pro config set field_name=your_custom_value`
2062+- delete the setting from `/etc/ubuntu-advantage/uaclient.conf`
2063+- delete the `ua_config:` line from `/etc/ubuntu-advantage/uaclient.conf`
2064diff --git a/docs/explanations/how_to_interpret_the_security_status_command.md b/docs/explanations/how_to_interpret_the_security_status_command.md
2065index 43fb3d2..21be0b4 100644
2066--- a/docs/explanations/how_to_interpret_the_security_status_command.md
2067+++ b/docs/explanations/how_to_interpret_the_security_status_command.md
2068@@ -1,10 +1,10 @@
2069-# How to interpret the security-status command output
2070+# What does `security-status` do?
2071
2072-The `security-status` command is used to get an overview
2073-of the packages installed in your machine.
2074+The `security-status` command is used to get an overview of the packages
2075+installed on your machine.
2076
2077-If you run the `pro security-status --format yaml` command on your
2078-machine, you are expected to see the output following this structure:
2079+If you run the `pro security-status --format yaml` command on your machine, you
2080+should expect to see an output that follows this structure:
2081
2082 ```
2083 _schema_version: '0.1'
2084@@ -41,31 +41,44 @@ livepatch:
2085 Patched: true
2086 ```
2087
2088-Let's understand what each key mean on the output of the `pro security-status` command:
2089-
2090-* **`summary`**: The summary of the system related to Ubuntu Pro and
2091- the different package sources in the system:
2092-
2093- * **`num_installed_packages`**: The total number of installed packages in the system.
2094- * **`num_esm_apps_packages`**: The number of packages installed from `esm-apps`.
2095- * **`num_esm_apps_updates`**: The number of `esm-apps` package updates available to the system.
2096- * **`num_esm_infra_packages`**: The number of packages installed from `esm-infra`.
2097- * **`num_esm_infra_updates`**: The number of `esm-infra` package updates available to the system.
2098- * **`num_main_packages`**: The number of packages installed from the `main` archive component.
2099- * **`num_multiverse_packages**: The number of packages installed from the `multiverse` archive
2100- component.
2101- * **`num_restricted_packages`**: The number of packages installed from the `restricted` archive
2102- component.
2103- * **`num_third_party_packages`** : The number of packages installed from `third party` sources.
2104- * **`num_universe_packages`**: The number of packages installed from the `universe` archive
2105- component.
2106- * **`num_unknown_packages`**: The number of packages installed from sources not known to `apt`
2107- (installed locally through dpkg or packages without a remote reference).
2108- * **`num_standard_security_updates`**: The number of standard security updates available to the system.
2109-
2110- It is worth mentioning here that the `_updates` fields are presenting the number of **security**
2111- updates for **installed** packages. For example, let's assume your machine has a universe package that
2112- has a security update from `esm-infra`. The count will be displayed as:
2113+Let's understand what each key means in the output of the `pro security-status`
2114+command:
2115+
2116+## `summary`
2117+
2118+This provides a summary of the system related to Ubuntu Pro and the different
2119+package sources in the system:
2120+
2121+* **`num_installed_packages`**: The total number of installed packages on the
2122+ system.
2123+* **`num_esm_apps_packages`**: The number of packages installed from `esm-apps`.
2124+* **`num_esm_apps_updates`**: The number of `esm-apps` package updates available
2125+ to the system.
2126+* **`num_esm_infra_packages`**: The number of packages installed from
2127+ `esm-infra`.
2128+* **`num_esm_infra_updates`**: The number of `esm-infra` package updates
2129+ available to the system.
2130+* **`num_main_packages`**: The number of packages installed from the `main`
2131+ archive component.
2132+* **`num_multiverse_packages`**: The number of packages installed from the
2133+ `multiverse` archive component.
2134+* **`num_restricted_packages`**: The number of packages installed from the
2135+ `restricted` archive component.
2136+* **`num_third_party_packages`** : The number of packages installed from
2137+ `third party` sources.
2138+* **`num_universe_packages`**: The number of packages installed from the
2139+ `universe` archive component.
2140+* **`num_unknown_packages`**: The number of packages installed from sources not
2141+ known to `apt` (e.g., those installed locally through `dpkg` or packages
2142+ without a remote reference).
2143+* **`num_standard_security_updates`**: The number of standard security updates
2144+ available to the system.
2145+
2146+```{note}
2147+ It is worth mentioning here that the `_updates` fields are presenting the
2148+ number of **security** updates for **installed** packages. For example, let's
2149+ assume your machine has a universe package that has a security update from
2150+ `esm-infra`. The count will be displayed as:
2151
2152 ```
2153 num_esm_infra_packages: 0
2154@@ -80,30 +93,38 @@ Let's understand what each key mean on the output of the `pro security-status` c
2155 num_esm_infra_updates: 0
2156 num_universe_packages: 0
2157 ```
2158+```
2159+
2160+* **`ua`**: An object representing the state of Ubuntu Pro on the system:
2161+ * **`attached`**: If the system is attached to an Ubuntu Pro subscription.
2162+ * **`enabled_services`**: A list of services that are enabled on the system.
2163+ If unattached, this will always be an empty list.
2164+ * **`entitled_services`**: A list of services that are entitled on your
2165+ Ubuntu Pro subscription. If unattached, this will always be an empty list.
2166+
2167+## `packages`
2168+
2169+This provides a list of security updates for packages installed on the system.
2170+Every entry on the list will follow this structure:
2171+
2172+* **`origin`**: The host where the update comes from.
2173+* **`package`**: The name of the package.
2174+* **`service_name`**: The service that provides the package update. It can be
2175+ one of: `esm-infra`, `esm-apps` or `standard-security`.
2176+* **`status`**: The status for this update. It will be one of:
2177+ * **"upgrade_available"**: The package can be upgraded right now.
2178+ * **"pending_attach"**: The package needs an Ubuntu Pro subscription attached
2179+ to be upgraded.
2180+ * **"pending_enable"**: The machine is attached to an Ubuntu Pro subscription,
2181+ but the service required to provide the upgrade is not enabled.
2182+ * **"upgrade_unavailable"**: The machine is attached, but the contract is not
2183+ entitled to the service which provides the upgrade.
2184+* **`version`**: The update version.
2185+* **`download_size`**: The number of bytes that would be downloaded in order to
2186+ install the update.
2187+
2188+## `livepatch`
2189
2190- * **`ua`**: An object representing the state of Ubuntu Pro on the system:
2191- * **`attached`**: If the system is attached to an Ubuntu Pro subscription.
2192- * **`enabled_services`**: A list of services that are enabled on the system. If unattached, this
2193- will always be an empty list.
2194- * **`entitled_services`**: A list of services that are entitled on your Ubuntu Pro subscription. If
2195- unattached, this will always be an empty list.
2196-
2197-* **`packages`**: A list of security updates for packages installed in the system.
2198- Every entry on the list will follow this structure:
2199-
2200- * **`origin`**: The host were the update comes from.
2201- * **`package`**: The name of the package.
2202- * **`service_name`**: The service that provides that package update. It can be either: `esm-infra`,
2203- `esm-apps` or `standard-security`.
2204- * **`status`**: The status for this update. It will be one of:
2205- * **"upgrade_available"**: The package can be upgraded right now.
2206- * **"pending_attach"**: The package needs an Ubuntu Pro subscription attached to be upgraded.
2207- * **"pending_enable"**: The machine is attached to an Ubuntu Pro subscription, but the service required to
2208- provide the upgrade is not enabled.
2209- * **"upgrade_unavailable"**: The machine is attached, but the contract is not entitled to
2210- the service which provides the upgrade.
2211- * **`version`**: The update version.
2212- * **`download_size`**: The number of bytes that would be downloaded in order to install the update.
2213-
2214-* **`livepatch`**: Livepatch related information. Currently, the only information
2215-presented is **`fixed_cves`** - a list of CVEs that were fixed by Livepatches applied to the kernel.
2216+This displays Livepatch-related information. Currently, the only information
2217+presented is **`fixed_cves`**. This represents a list of CVEs that were fixed
2218+by Livepatches applied to the kernel.
2219diff --git a/docs/explanations/motd_messages.md b/docs/explanations/motd_messages.md
2220index 7defd66..337a4bd 100644
2221--- a/docs/explanations/motd_messages.md
2222+++ b/docs/explanations/motd_messages.md
2223@@ -1,112 +1,111 @@
2224-# Ubuntu Pro related messages on MOTD
2225+# Ubuntu Pro-related MOTD messages
2226
2227-When Ubuntu Pro Client (`pro`) is installed on the system, it delivers custom messages on [MOTD](https://wiki.debian.org/motd).
2228-Those messages are generated directly by two different sources:
2229+When the Ubuntu Pro Client (`pro`) is installed on the system, it delivers
2230+custom messages on ["Message of the Day" (MOTD)](https://wiki.debian.org/motd).
2231+Those messages are generated directly by two different sources.
2232
2233-* **python script**: The [update-notifier](https://wiki.ubuntu.com/UpdateNotifier) deliver a script
2234- called `apt_check.py`. Considering Ubuntu Pro related information, this script is responsible for:
2235+## Python-scripted MOTD
2236+
2237+The [update-notifier](https://wiki.ubuntu.com/UpdateNotifier) delivers a script
2238+called `apt_check.py`. With regards to Ubuntu Pro, this script is responsible
2239+for:
2240+
2241+* Informing the user about the status of one of the ESM services; `esm-apps` if
2242+ the machine is an LTS series, or `esm-infra` if the series is in ESM mode.
2243+* Showing the number of `esm-infra` or `esm-apps` packages that can be upgraded
2244+ on the machine.
2245+
2246+For example, here is the output of the `apt_check.py` script on a LTS machine
2247+when both of those services are enabled:
2248+
2249+```
2250+Expanded Security Maintenance for Applications is enabled.
2251+
2252+11 updates can be applied immediately.
2253+5 of these updates are ESM Apps security updates.
2254+1 of these updates is a ESM Infra security update.
2255+5 of these updates are standard security updates.
2256+To see these additional updates run: apt list --upgradable
2257+```
2258+
2259+However, if we were running this on an ESM series, we would instead see
2260+`esm-infra` being advertised:
2261+
2262+```
2263+Expanded Security Maintenance Infrastructure is enabled.
2264+
2265+11 updates can be applied immediately.
2266+5 of these updates are ESM Apps security updates.
2267+1 of these updates is a ESM Infra security update.
2268+5 of these updates are standard security updates.
2269+To see these additional updates run: apt list --upgradable
2270+```
2271+
2272+Now let's consider a scenario where one of these services is not enabled. For
2273+example, if `esm-apps` was disabled, the output will be:
2274+
2275+```
2276+Expanded Security Maintenance for Applications is not enabled.
2277+
2278+6 updates can be applied immediately.
2279+1 of these updates is a ESM Infra security update.
2280+5 of these updates are standard security updates.
2281+To see these additional updates run: apt list --upgradable
2282
2283- * inform the user about the status of one of the ESM services, `esm-apps` if the machine is a
2284- LTS series or `esm-infra` if the series is on ESM mode.
2285- * showing the number of `esm-infra` or `esm-apps` packages that can be upgraded in the machine
2286+5 additional security updates can be applied with ESM Apps
2287+Learn more about enabling ESM Apps for Ubuntu 16.04 at
2288+https://ubuntu.com/16-04
2289+```
2290
2291- For example, this is the output of the `apt_check.py` script on a LTS machine when both of
2292- those services are enabled:
2293+At the end of the output we can see the number of packages that *could* be
2294+upgraded if that service was enabled. Note that we would deliver the same
2295+information for `esm-infra` if the service was disabled and the series running
2296+on the machine is in ESM state.
2297
2298- ```
2299- Expanded Security Maintenance for Applications is enabled.
2300+## MOTD through Ubuntu Pro timer jobs
2301
2302- 11 updates can be applied immediately.
2303- 5 of these updates are ESM Apps security updates.
2304- 1 of these updates is a ESM Infra security update.
2305- 5 of these updates are standard security updates.
2306- To see these additional updates run: apt list --upgradable
2307- ```
2308+One of the timer jobs Ubuntu Pro uses can insert additional messages into MOTD.
2309+These messages will be always delivered before or after the content created by
2310+the Python script delivered by `update-notifier`. These additional messages are
2311+generated when `pro` detects that certain conditions on the machine have been
2312+met. They are:
2313
2314- Note that if we were running this on a ESM series, we would instead see `esm-infra` being
2315- advertised:
2316+### Subscription expired
2317
2318- ```
2319- Expanded Security Maintenance Infrastructure is enabled.
2320+When the Ubuntu Pro subscription is expired, `pro` will deliver the following
2321+message after the `update-notifier` message:
2322
2323- 11 updates can be applied immediately.
2324- 5 of these updates are ESM Apps security updates.
2325- 1 of these updates is a ESM Infra security update.
2326- 5 of these updates are standard security updates.
2327- To see these additional updates run: apt list --upgradable
2328- ```
2329+```
2330+*Your Ubuntu Pro subscription has EXPIRED*
2331+2 additional security update(s) require Ubuntu Pro with 'esm-infra' enabled.
2332+Renew your service at https://ubuntu.com/pro
2333+```
2334
2335- Now considering the scenario were one of those services is not enabled. For example, if
2336- `esm-apps` was not enabled, the output will be:
2337+### Subscription about to expire
2338
2339- ```
2340- Expanded Security Maintenance for Applications is not enabled.
2341-
2342- 6 updates can be applied immediately.
2343- 1 of these updates is a ESM Infra security update.
2344- 5 of these updates are standard security updates.
2345- To see these additional updates run: apt list --upgradable
2346-
2347- 5 additional security updates can be applied with ESM Apps
2348- Learn more about enabling ESM Apps for Ubuntu 16.04 at
2349- https://ubuntu.com/16-04
2350- ```
2351-
2352- In the end of the output we can see the number of packages that could
2353- be upgraded if that service was enabled. Note that we would deliver the same information
2354- for `esm-infra` if the service was disabled and the series running on the machine is on ESM
2355- state.
2356-
2357-* **Ubuntu Pro timer jobs**: One of the timer jobs Ubuntu Pro has is used to insert additional messages into MOTD.
2358- Those messages will be always delivered before or after the content created by the python
2359- script delivered by `update-notifier`. Those additional messages are generated when `pro` detects
2360- some conditions on the machine. They are:
2361-
2362- * **subscription expired**: When the Ubuntu Pro subscription is expired, `pro` will deliver the following
2363- message after the `update-notifier` message:
2364-
2365- ```
2366- *Your Ubuntu Pro subscription has EXPIRED*
2367- 2 additional security update(s) require Ubuntu Pro with 'esm-infra' enabled.
2368- Renew your service at https://ubuntu.com/pro
2369- ```
2370-
2371- * **subscription about to expire**: When the Ubuntu Pro subscription is about to expire, we deliver the
2372- following message after the `update-notifier` message:
2373-
2374- ```
2375- CAUTION: Your Ubuntu Pro subscription will expire in 2 days.
2376- Renew your subscription at https://ubuntu.com/pro to ensure continued security
2377- coverage for your applications.
2378- ```
2379-
2380- * **subscription expired but within grace period**: When the Ubuntu Pro subscription is expired, but is
2381- still within the grace period, we deliver the following message after the `update-notifier`
2382- script:
2383-
2384- ```
2385- CAUTION: Your Ubuntu Pro subscription expired on 10 Sep 2021.
2386- Renew your subscription at https://ubuntu.com/pro to ensure continued security
2387- coverage for your applications.
2388- Your grace period will expire in 9 days.
2389- ```
2390-
2391- * **advertising esm-apps service**: When we detect that `esm-apps` is supported and not enabled
2392- in the system, we advertise it using the following message that is delivered before the
2393- `update-notifier` message:
2394-
2395- ```
2396- * Introducing Expanded Security Maintenance for Applications.
2397- Receive updates to over 25,000 software packages with your
2398- Ubuntu Pro subscription. Free for personal use
2399-
2400- https://ubuntu.com/16-04
2401- ```
2402-
2403- Note that we could also advertise the `esm-infra` service instead. This will happen
2404- if you use an ESM release. Additionally, the the url we use to advertise the service is different
2405- based on the series that is running on the machine.
2406-
2407- Additionally, all of those Ubuntu Pro custom messages are delivered into
2408- `/var/lib/ubuntu-advantage/messages`. We also add custom scripts into `/etc/update-motd.d` to
2409- check if those messages exist and if they do, insert them on the full MOTD message.
2410+When the Ubuntu Pro subscription is about to expire, we deliver the following
2411+message after the `update-notifier` message:
2412+
2413+```
2414+CAUTION: Your Ubuntu Pro subscription will expire in 2 days.
2415+Renew your subscription at https://ubuntu.com/pro to ensure continued security
2416+coverage for your applications.
2417+```
2418+
2419+### Subscription expired but within grace period
2420+
2421+When the Ubuntu Pro subscription has expired, but is still within the grace
2422+period, we deliver the following message after the `update-notifier` script:
2423+
2424+```
2425+CAUTION: Your Ubuntu Pro subscription expired on 10 Sep 2021.
2426+Renew your subscription at https://ubuntu.com/pro to ensure continued security
2427+coverage for your applications.
2428+Your grace period will expire in 9 days.
2429+```
2430+
2431+### How are these messages updated and inserted into MOTD?
2432+
2433+1. The contract status is checked periodically in the background when the machine is attached to an Ubuntu Pro contract.
2434+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`.
2435+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.
2436diff --git a/docs/explanations/status_columns.md b/docs/explanations/status_columns.md
2437index 40a11e5..1447b44 100644
2438--- a/docs/explanations/status_columns.md
2439+++ b/docs/explanations/status_columns.md
2440@@ -1,7 +1,11 @@
2441-# Status output explanation
2442+# The `pro status` output explained
2443
2444-When running `pro status` we can observe two different types of outputs, attached vs unattached.
2445-When unattached, users will see the status table containing only three columns:
2446+When running `pro status` we can observe two different types of outputs, which
2447+depend on whether the Ubuntu Pro subscription is attached or unattached.
2448+
2449+## Pro subscription unattached
2450+When unattached, users will see the following status table containing only
2451+three columns:
2452
2453 ```
2454 SERVICE AVAILABLE DESCRIPTION
2455@@ -15,12 +19,16 @@ livepatch yes Canonical Livepatch service
2456
2457 Where:
2458
2459-* **SERVICE**: is the name of service being offered
2460-* **AVAILABLE**: if that service is available on that machine. To verify if a service is available, we
2461- check the machine kernel version, architecture and Ubuntu release it is running.
2462+* **SERVICE**: Is the name of service being offered
2463+* **AVAILABLE**: Shows if that service is available on that machine. To verify
2464+ if a service is available, we check the machine kernel version, architecture,
2465+ Ubuntu release being used and the machine type (i.e lxd for LXD containers)
2466 * **DESCRIPTION**: A short description of the service.
2467
2468-However, if we run the same command when attached, we have an output with 4 columns:
2469+## With Pro subscription attached
2470+
2471+However, if we run the same command when attached, we have an output with 4
2472+columns:
2473
2474 ```
2475 SERVICE ENTITLED STATUS DESCRIPTION
2476@@ -29,46 +37,67 @@ esm-infra yes enabled Expanded Security Maintenance for Infrastructu
2477 fips yes n/a NIST-certified core packages
2478 fips-updates yes n/a NIST-certified core packages with priority security updates
2479 livepatch yes n/a Canonical Livepatch service
2480-```
2481+```
2482+
2483+You may notice that the column **AVAILABLE** is no longer shown, and instead we
2484+see the following new columns:
2485+
2486+* **ENTITLED**: Shows if the user subscription allows that service to be
2487+ enabled.
2488+* **STATUS**: Reports the state of that service on the machine.
2489
2490-Here we can notice that the column **AVAILABLE** no longer applies and we have new columns:
2491+It is possible that a service could appear as "available" when the Pro status is
2492+unattached, but then shows as "not entitled" if the subscription is later
2493+attached. This happens because even if the service is available, if your Ubuntu
2494+Pro subscription doesn't allow you access to a service, `pro` cannot enable it.
2495
2496-* **ENTITLED**: If the user subscription allow that service to be enabled
2497-* **STATUS**: The state of that service on the machine.
2498+The **STATUS** column allows for three possible states:
2499
2500-It is possible that a service appears as available when running status unattached, but turns
2501-out as not entitled. This happens because even if the service can be enabled on the machine,
2502-if your Ubuntu Pro subscription doesn't allow you to do that, `pro` cannot enable it.
2503+* **enabled**: The service is enabled on the machine.
2504+* **disabled**: The service is not currently running.
2505+* **n/a**: This means "not applicable". This will show if the service cannot be
2506+ enabled on the machine due to a non-contract restriction. For example, we
2507+ cannot enable `livepatch` on a container.
2508
2509-Additionally, the **STATUS** column allows for three possible states:
2510+## Notices
2511
2512-* **enabled**: service is enabled in the machine
2513-* **disabled**: service is not currently running
2514-* **n/a**: This means non-applicable. This can happen if the service cannot be enabled on the machine
2515- due to a non-contract restriction. For example, we cannot enable `livepatch` on a container.
2516+"Notices" are information regarding the Ubuntu Pro status which either require
2517+some kind of action from the user, or may impact the experience with Ubuntu Pro.
2518
2519-### Notices
2520-Notices are information regarding the Ubuntu Pro status which either require some kind of action from the user, or may impact the experience with Ubuntu Pro.
2521+For example, let's say FIPS was just enabled, but the system wasn't rebooted
2522+yet (which is required for booting into the FIPS Kernel). The output of
2523+`pro status` in this case will contain:
2524
2525-For example, let's say FIPS was just enabled, but the system wasn't rebooted yet (which is needed for booting into the FIPS Kernel), the output of `pro status` will contain:
2526 ```
2527 NOTICES
2528 FIPS support requires system reboot to complete configuration.
2529 ```
2530+
2531 After the system is rebooted, the notice will go away.
2532
2533-Notices can always be resolved, and the way to resolve it should be explicit in the notice itself.
2534+Notices can always be resolved, and the instructions on how to resolve it will
2535+be explicitly stated in the notice itself.
2536+
2537+## Features
2538+
2539+"Features" are extra configuration values that can be set and unset in
2540+`uaclient.conf`. Most of these are meant for development/testing purposes, but
2541+some can be used in application flows. For example, to always have beta services
2542+with the same flow as the non-beta (for `enable`, `status`, etc.),
2543+`uaclient.conf` may have:
2544
2545-### Features
2546-Features are extra configuration values that can be set/unset in `uaclient.conf`. Most of those are meant for development/testing purposes, but some can be used in application flows. For example, to always have beta services with the same flow as the non-beta (for enable, status, etc), `uaclient.conf` may have:
2547 ```
2548 features:
2549 allow_beta: true
2550 ```
2551+
2552 In this case, the output of `pro status` will contain:
2553+
2554 ```
2555 FEATURES
2556 allow_beta: True
2557 ```
2558
2559-Keep in mind that any feature defined like this will be listed, even if it is invalid or typed the wrong way. Those appear on status for information/debugging purposes.
2560+It's important to keep in mind that any feature defined like this will be
2561+listed, even if it is invalid or typed the wrong way. Those appear in `status`
2562+output for informational and debugging purposes.
2563diff --git a/docs/explanations/what_are_the_timer_jobs.md b/docs/explanations/what_are_the_timer_jobs.md
2564index 30de317..fa84b36 100644
2565--- a/docs/explanations/what_are_the_timer_jobs.md
2566+++ b/docs/explanations/what_are_the_timer_jobs.md
2567@@ -1,19 +1,26 @@
2568-# Timer jobs
2569+# Timer jobs explained
2570
2571-Ubuntu Pro Client (`pro`) sets up a systemd timer to run jobs that need to be executed recurrently. Everytime the
2572-timer runs, it decides which jobs need to be executed based on their intervals. When a job runs
2573-successfully, its next run is determined by the interval defined for that job.
2574+Ubuntu Pro Client (`pro`) sets up a `systemd` timer to run jobs that need to be
2575+carried out periodically. Every time the timer runs, it decides which jobs need
2576+to be performed based on their intervals. When a job runs successfully, its next
2577+run is determined by the interval defined for that job.
2578
2579 ## Current jobs
2580
2581-The jobs that `pro` runs periodically are:
2582+The jobs that `pro` runs periodically are `metering` and `update_messaging`.
2583
2584-| Job | Description | Interval |
2585-| --- | ----------- | -------- |
2586-| update_messaging | Update MOTD and APT messages | 6 hours |
2587-| metering | (Only when attached to Ubuntu Pro services) Pings Canonical servers for contract metering | 4 hours |
2588+### The `update_messaging` job
2589
2590-- The `update_messaging` job makes sure that the MOTD and APT messages match the
2591-available/enabled services on the system, showing information about available
2592-packages or security updates.
2593-- The `metering` will inform Canonical on which services are enabled on the machine.
2594+`update_messaging` updates the MOTD and APT messages every 6 hours. It ensures
2595+that the MOTD and APT messages displayed on the system match those that are
2596+available/enabled. It finds updated information about available packages or
2597+security updates and shows these to the user.
2598+
2599+### The `metering` job
2600+
2601+`metering` pings the Canonical servers for contract metering every 4 hours. It
2602+informs Canonical which services are enabled on the machine.
2603+
2604+```{note}
2605+The `metering` job only runs when attached to an Ubuntu Pro subscription.
2606+```
2607diff --git a/docs/explanations/what_are_ubuntu_pro_cloud_instances.md b/docs/explanations/what_are_ubuntu_pro_cloud_instances.md
2608index 84437e1..4e84d7e 100644
2609--- a/docs/explanations/what_are_ubuntu_pro_cloud_instances.md
2610+++ b/docs/explanations/what_are_ubuntu_pro_cloud_instances.md
2611@@ -1,15 +1,28 @@
2612-# What is a Public Cloud Ubuntu Pro machine?
2613+# About Public Cloud Ubuntu Pro images
2614
2615-Ubuntu Pro images are published to [AWS](https://ubuntu.com/aws/pro), [Azure](https://ubuntu.com/azure/pro) and [GCP](https://ubuntu.com/gcp/pro) which come with Ubuntu
2616-Pro support and services built in. On first boot, Ubuntu Pro images will automatically attach
2617-to an Ubuntu Pro support contract and enable necessary Ubuntu Pro services so
2618-that no extra setup is required to ensure a secure and supported Ubuntu machine.
2619+Ubuntu Pro images are published to [AWS](https://ubuntu.com/aws/pro),
2620+[Azure](https://ubuntu.com/azure/pro) and [GCP](https://ubuntu.com/gcp/pro).
2621+All of these come with Ubuntu Pro support and services built in.
2622
2623-There are two primary flavors of Ubuntu Pro images in clouds:
2624+On first boot, Ubuntu Pro images will automatically attach to an Ubuntu Pro
2625+support contract and enable all necessary Ubuntu Pro services so that no extra
2626+setup is required to ensure a secure and supported Ubuntu machine.
2627
2628-* Ubuntu Pro: Ubuntu LTS images with attached Ubuntu Pro support with kernel Livepatch and
2629-ESM security access already enabled. Ubuntu Pro images are entitled to enable any additional Ubuntu Pro
2630-services (like [`fips`](../howtoguides/enable_fips.md) or [`usg`](../howtoguides/enable_cis.md)).
2631-* Ubuntu Pro FIPS: Specialized Ubuntu Pro images for 16.04, 18.04 and 20.04 which come pre-enabled
2632-with the cloud-optimized FIPS-certified kernel and all additional SSL and security hardening
2633-enabled. These images are available as [AWS Ubuntu Pro FIPS](https://ubuntu.com/aws/fips), [Azure Ubuntu Pro FIPS](https://ubuntu.com/azure/fips) and GCP Ubuntu Pro FIPS.
2634+There are two primary flavors of Ubuntu Pro images in clouds: *Ubuntu Pro*, and
2635+*Ubuntu Pro FIPS*.
2636+
2637+## Ubuntu Pro
2638+
2639+These Ubuntu LTS images are provided already attached to Ubuntu Pro support,
2640+with kernel Livepatch and ESM security access enabled. Ubuntu Pro images are
2641+entitled to enable any additional Ubuntu Pro services (like
2642+[`fips`](../howtoguides/enable_fips.md) or
2643+[`usg`](../howtoguides/enable_cis.md)).
2644+
2645+## Ubuntu Pro FIPS
2646+
2647+These specialized Ubuntu Pro images for 16.04, 18.04 and 20.04 come pre-enabled
2648+with the cloud-optimized FIPS-certified kernel, as well as all additional SSL
2649+and security hardening enabled. These images are available as
2650+[AWS Ubuntu Pro FIPS](https://ubuntu.com/aws/fips),
2651+[Azure Ubuntu Pro FIPS](https://ubuntu.com/azure/fips) and GCP Ubuntu Pro FIPS.
2652diff --git a/docs/explanations/what_is_the_daemon.md b/docs/explanations/what_is_the_daemon.md
2653index f7b1195..0ad510f 100644
2654--- a/docs/explanations/what_is_the_daemon.md
2655+++ b/docs/explanations/what_is_the_daemon.md
2656@@ -1,8 +1,12 @@
2657-# What is the Pro Upgrade Daemon?
2658+# What is the Pro upgrade daemon?
2659
2660-Ubuntu Pro Client sets up a daemon on supported platforms (currently GCP only) to detect if an Ubuntu Pro license is purchased for the machine. If a Pro license is detected, then the machine is automatically attached.
2661+Ubuntu Pro Client sets up a daemon on supported platforms (currently GCP
2662+only) to detect if an Ubuntu Pro license has been purchased for the machine.
2663+If a Pro license is detected, then the machine is automatically attached.
2664
2665-If you are uninterested in Ubuntu Pro services, you can safely stop and disable the daemon using systemctl:
2666+If you are not interested in Ubuntu Pro services and don't want your machine to
2667+be automatically attached to your subscription, you can safely stop and disable
2668+the daemon using `systemctl`:
2669
2670 ```
2671 sudo systemctl stop ubuntu-advantage.service
2672diff --git a/docs/explanations/what_is_the_ubuntu_advantage_pro_package.md b/docs/explanations/what_is_the_ubuntu_advantage_pro_package.md
2673index 10a4d1d..337e97c 100644
2674--- a/docs/explanations/what_is_the_ubuntu_advantage_pro_package.md
2675+++ b/docs/explanations/what_is_the_ubuntu_advantage_pro_package.md
2676@@ -1,4 +1,8 @@
2677-# What is the ubuntu-advantage-pro package?
2678+# What is the `ubuntu-advantage-pro` package?
2679
2680-The ubuntu-advantage-pro package is used by [Public Cloud Ubuntu Pro](what_are_ubuntu_pro_cloud_instances.md) machines to automate machine attach on boot.
2681-Therefore, the only thing that `ubuntu-advantage-pro` does is ship a systemd unit that runs an auto-attach command on first boot.
2682+The `ubuntu-advantage-pro` package is used by
2683+[Public Cloud Ubuntu Pro](what_are_ubuntu_pro_cloud_instances.md) machines to
2684+automate the process of attaching a machine on boot.
2685+
2686+Therefore, the only thing that `ubuntu-advantage-pro` does is ship a `systemd`
2687+unit that runs an auto-attach command on first boot.
2688diff --git a/docs/explanations/what_refresh_does.md b/docs/explanations/what_refresh_does.md
2689index 16542f7..5312962 100644
2690--- a/docs/explanations/what_refresh_does.md
2691+++ b/docs/explanations/what_refresh_does.md
2692@@ -1,13 +1,25 @@
2693-# What refresh does
2694+# What `pro refresh` does
2695
2696-When you run the `pro refresh` command on your machine, three distinct stages are performed:
2697+When you run the `pro refresh` command on your machine, three distinct stages
2698+are performed.
2699
2700-* **contract**: The contract information on the machine is refreshed. If we find any deltas
2701- between the old contract and the new one, we process that delta and apply the changes
2702- on the machine. If you need only this stage during refresh, run `pro refresh contract`.
2703+## Contract
2704
2705-* **config**: If there is any config change made on `/etc/ubuntu-advantage/uaclient.conf`, those
2706- changes will now be applied to the machine. If you need only this stage during refresh, run `pro refresh config`.
2707+The contract information on the machine is refreshed. If we find any deltas
2708+between the old contract and the new one, we process that delta and apply the
2709+changes to the machine.
2710
2711-* **MOTD and APT messages**: Process new MOTD and APT messages and refresh the machine to use
2712- them. If you need only this stage during refresh, run `pro refresh messages`.
2713+If you need *only* this stage during refresh, run `pro refresh contract`.
2714+
2715+## Configuration
2716+
2717+If there is any config change made to `/etc/ubuntu-advantage/uaclient.conf`,
2718+those changes will now be applied to the machine.
2719+
2720+If you need *only* this stage during refresh, run `pro refresh config`.
2721+
2722+## MOTD and APT messages
2723+
2724+Processes new MOTD and APT messages, and refreshes the machine to use them.
2725+
2726+If you need *only* this stage during refresh, run `pro refresh messages`.
2727diff --git a/docs/explanations/why_trusty_is_no_longer_supported.md b/docs/explanations/why_trusty_is_no_longer_supported.md
2728index f3e26d3..3d37ee6 100644
2729--- a/docs/explanations/why_trusty_is_no_longer_supported.md
2730+++ b/docs/explanations/why_trusty_is_no_longer_supported.md
2731@@ -1,7 +1,10 @@
2732-# Why trusty is no longer supported
2733+# Why is 14.04 (Trusty) no longer supported?
2734
2735-On 14.04 (Trusty), the Ubuntu Pro Client package is not receiving upstream updates
2736-beyond version 19.6 plus any critical CVE maintenance related to this version. Version 19.6 already
2737-has full-featured support of the applicable Ubuntu Pro service offerings `esm-infra` and `livepatch`. In the
2738-event that a CVE is discovered that affects the Ubuntu Pro Client version on Trusty, a fix and backport will be
2739-provided for those specific issues.
2740+On 14.04 (Trusty), the Ubuntu Pro Client package is not receiving upstream
2741+updates beyond version 19.6, plus any critical CVE maintenance related to this
2742+version.
2743+
2744+Version 19.6 already has full-featured support of the applicable Ubuntu Pro
2745+service offerings `esm-infra` and `livepatch`. In the event that a CVE is
2746+discovered that affects the Ubuntu Pro Client version on Trusty, a fix and
2747+backport will be provided for those specific issues.
2748diff --git a/docs/howtoguides.rst b/docs/howtoguides.rst
2749index 8ddbc0c..7127394 100644
2750--- a/docs/howtoguides.rst
2751+++ b/docs/howtoguides.rst
2752@@ -34,6 +34,7 @@ How to use ``pro`` commands
2753 .. toctree::
2754 :maxdepth: 1
2755
2756+ Disable or re-enable APT News <howtoguides/disable_enable_apt_news.md>
2757 Configure a proxy <howtoguides/configure_proxies.md>
2758 Configure a timer job <howtoguides/configuring_timer_jobs.md>
2759
2760@@ -82,19 +83,19 @@ How to use ``pro`` commands
2761 :maxdepth: 1
2762
2763 Check Ubuntu Pro Client version <howtoguides/check_pro_version>
2764-
2765-Create a ``pro`` Golden Image
2766-=============================
2767+
2768+``lock``
2769+-----------
2770
2771 .. toctree::
2772 :maxdepth: 1
2773
2774- Create a customised Cloud Ubuntu Pro image <howtoguides/create_pro_golden_image.md>
2775-
2776-Use ``pro`` in an airgapped environment
2777-=======================================
2778+ Get rid of corrupted locks <howtoguides/get_rid_of_corrupt_lock.md>
2779+
2780+Create a ``pro`` Golden Image
2781+=============================
2782
2783 .. toctree::
2784 :maxdepth: 1
2785
2786- Use Ubuntu Pro in an airgapped environment <howtoguides/pro_in_airgapped.md>
2787+ Create a customised Cloud Ubuntu Pro image <howtoguides/create_pro_golden_image.md>
2788diff --git a/docs/howtoguides/disable_enable_apt_news.md b/docs/howtoguides/disable_enable_apt_news.md
2789new file mode 100644
2790index 0000000..c9ffd59
2791--- /dev/null
2792+++ b/docs/howtoguides/disable_enable_apt_news.md
2793@@ -0,0 +1,45 @@
2794+# How to disable or re-enable APT News
2795+
2796+APT News is a feature that allows for timely package-related news to be displayed during an `apt upgrade`. It is distinct from [Ubuntu Pro 'available update' messages](../explanations/apt_messages.md) that are also displayed during an `apt upgrade`. APT News messages are fetched from [https://motd.ubuntu.com/aptnews.json](https://motd.ubuntu.com/aptnews.json) at most once per day.
2797+
2798+By default, APT News is turned on. In this How-to-guide, we show how to turn off and on the APT News feature for a particular machine.
2799+
2800+## Step 1: Check the current configuration of APT News
2801+
2802+```
2803+pro config show apt_news
2804+```
2805+
2806+The default value is `True`, so if you haven't yet modified this setting, you will see:
2807+```
2808+apt_news True
2809+```
2810+
2811+## Step 2: Disable APT News
2812+
2813+```
2814+pro config set apt_news=false
2815+```
2816+
2817+This should also clear any current APT News you may be seeing on your system during `apt upgrade`.
2818+
2819+You can double-check that the setting was successful by running the following again:
2820+
2821+```
2822+pro config show apt_news
2823+```
2824+
2825+You should now see:
2826+```
2827+apt_news False
2828+```
2829+
2830+## Step 3: (Optional) Re-enable APT News
2831+
2832+If you change your mind and want APT News to start appearing again in `apt upgrade`, run the following:
2833+
2834+```
2835+pro config set apt_news=true
2836+```
2837+
2838+And verify the setting worked with `pro config show apt_news`.
2839diff --git a/docs/howtoguides/enable_realtime_kernel.md b/docs/howtoguides/enable_realtime_kernel.md
2840index 4cf56c0..e5ca5e8 100644
2841--- a/docs/howtoguides/enable_realtime_kernel.md
2842+++ b/docs/howtoguides/enable_realtime_kernel.md
2843@@ -1,7 +1,7 @@
2844 # How to enable Real-time kernel
2845
2846 ```{caution}
2847-Real-Time Kernel is only supported on 22.04. For more information, please see
2848+Real-time kernel is only supported on 22.04. For more information, please see
2849 https://ubuntu.com/realtime-kernel
2850 ```
2851
2852@@ -14,7 +14,7 @@ $ sudo pro enable realtime-kernel
2853 ```
2854
2855 You'll need to acknowledge a warning, and then you should see output like the
2856-following, indicating that the Real-Time Kernel package has been installed.
2857+following, indicating that the Real-time kernel package has been installed.
2858
2859 ```
2860 One moment, checking your subscription first
2861@@ -39,7 +39,7 @@ After rebooting you'll be running the Real-time kernel!
2862 The --access-only flag is introduced in version 27.11
2863 ```
2864
2865-If you would like to enable access to the Real-Time Kernel APT repository but
2866+If you would like to enable access to the Real-time kernel APT repository but
2867 not install the kernel right away, use the `--access-only` flag while enabling.
2868
2869 ```console
2870diff --git a/docs/howtoguides/get_rid_of_corrupt_lock.md b/docs/howtoguides/get_rid_of_corrupt_lock.md
2871new file mode 100644
2872index 0000000..03da4a3
2873--- /dev/null
2874+++ b/docs/howtoguides/get_rid_of_corrupt_lock.md
2875@@ -0,0 +1,29 @@
2876+# How to get rid of a corrupt lock
2877+
2878+Some pro commands (`attach`, `enable`, `detach` and `disable`) will potentially change the
2879+internal state of your system. Since those commands can run in parallel, we have a lock file
2880+mechanism to guarantee that only one of these commands can run at the same time. The lock follow
2881+this pattern:
2882+
2883+```
2884+PROCESS_PID:LOCK_HOLDER_NAME
2885+```
2886+
2887+Where:
2888+
2889+*PROCESS_PID*: The PID of the process that is running the pro command
2890+*LOCK_HOLDER_NAME*: The name of the command that is using the lock (i.e. `pro disable`)
2891+
2892+If the lock file doesn't follow that pattern, we say that it is corrupted. That might happen if we
2893+have any type of disk failures in the system. Once we detect a corrupted lock file, any of
2894+the mentioned pro commands will generate the following output:
2895+
2896+```
2897+There is a corrupted lock file in the system. To continue, please remove it
2898+from the system by running:
2899+
2900+$ sudo rm /var/lib/ubuntu-advantage/lock
2901+```
2902+
2903+You can follow the instructions presented on the output to get rid of the corrupted lock.
2904+After that, running the command should generate a correct lock file and continue as expected.
2905diff --git a/docs/howtoguides/pro_in_airgapped.md b/docs/howtoguides/pro_in_airgapped.md
2906deleted file mode 100644
2907index f8f41a7..0000000
2908--- a/docs/howtoguides/pro_in_airgapped.md
2909+++ /dev/null
2910@@ -1,103 +0,0 @@
2911-# Get started with `pro` in airgapped environment
2912-Want to use `pro` in an offline (=airgapped/internetless) environment? This how-to guide will help you understand how to use the power of Ubuntu Pro in an internetless environment.
2913-
2914-We will show you how to use your existing token in the machine without Internet access and get the same resources as if your machine had network access.
2915-
2916-What you’ll learn
2917-* How to use the airgapped functionality
2918-* How to configure the Pro client to use airgapped
2919-* How to configure resources in the internetless environment
2920-
2921-What you’ll need
2922-* Preliminary Ubuntu Pro knowledge (refer [here](https://canonical-ubuntu-pro-client.readthedocs-hosted.com/) for more info)
2923-* Two Ubuntu machines (one in the airgapped & one in the non-airgapped environment) running 16.04 LTS, 18.04 LTS, 20.04 LTS or 22.04 LTS
2924-* `sudo` access on both machines
2925-* Existing Ubuntu One account
2926-* Ubuntu Pro client version 27.11.2 or newer on the airgapped machine
2927-
2928-## Before we start
2929-1. Check your machines are up-to-date: \
2930-`sudo apt update && sudo apt upgrade`
2931-2. Check the Ubuntu Pro client is installed on the airgapped machine: \
2932-`pro --version`
2933-3. Get the token from the [Ubuntu Pro dashboard](https://ubuntu.com/pro/dashboard) you plan to use in the airgapped environment. In this guide, we’ll refer to this token as `[YOUR_CONTRACT_TOKEN]`
2934-
2935-
2936-## Installation
2937-Run these commands on both machines:
2938-```bash
2939-sudo add-apt-repository ppa:yellow/ua-airgapped && sudo apt update
2940-sudo apt install ua-airgapped contracts-airgapped get-resource-tokens
2941-```
2942-
2943-These three commands serve the following purposes:
2944-1. `ua-airgapped` creates the configuration for running the server locally
2945-2. `contracts-airgapped` runs the server for the Ubuntu Pro client
2946-3. `get-resource-tokens` fetches resource tokens for setting up mirrors of Canonical repositories (as we cannot access Canonical-hosted resources in an offline environment)
2947-
2948-
2949-## Get configuration to set up mirrors
2950-The Ubuntu Pro client cannot access Canonical-hosted services in an offline environment, so we will mirror these repositories locally.
2951-
2952-First, find out the repositories’ URLs of all the resources your contract is entitled to. Run the following in a non-airgapped environment: \
2953-`echo '[YOUR_CONTRACT_TOKEN]:' | ua-airgapped | grep 'aptURL:'`
2954-
2955-Then, get the resource tokens to access these resources in a non-airgapped environment: \
2956-`get-resource-tokens [YOUR_CONTRACT_TOKEN]`
2957-
2958-Stdout from `get-resource-tokens` gives pairs of services and their resource tokens (one token per service). The repository URL is specified as `aptURL` from the first command and, together with the resource token, they are required to set up a mirror, be it `apt-mirror`, `aptly`, Landscape or another software.
2959-
2960-You can check the resource token's correctness. For example, let’s say we want to set a mirror for `esm-infra`. It has `aptURL: https://esm.ubuntu.com`. If the resource token is `[ESM_INFRA_RESOURCE_TOKEN]`, then the command on the non-airgapped machine will be:
2961-```bash
2962-/usr/lib/apt/apt-helper download-file https://bearer:[ESM_INFRA_RESOURCE_TOKEN]@esm.ubuntu.com/ubuntu/ /tmp/check-esm-resource-token.txt
2963-```
2964-Response must be `200`. `401 Unauthorized` shows that the resource token or the URL is wrong. Please note that the specifics of setting up mirrors may be different depending on the product, but the bearer authentication will be identical in all cases, so refer to the command above to distinguish between airgapped and mirror problems.
2965-
2966-## Set up mirrors
2967-If you have experience in setting up mirrors, this section is optional for you. However, if you want to get started with the simplest option of setting up mirrors and have no prior experience, keep reading.
2968-
2969-Suppose you want to set up mirrors for esm-infra. Then, the steps to set up a mirror would be:
2970-1. Install `apt-mirror`: \
2971-`sudo apt install apt-mirror`
2972-2. Fetch the resource token for `esm-infra` (as per the section above).
2973-3. Change the `/etc/apt/mirror.list` file to the following contents:
2974- ```
2975- set nthreads 20
2976- set _tilde 0
2977-
2978- deb https://bearer:[ESM_INFRA_RESOURCE_TOKEN]@esm.ubuntu.com/infra/ubuntu/ jammy-infra-updates main
2979- deb https://bearer:[ESM_INFRA_RESOURCE_TOKEN]@esm.ubuntu.com/infra/ubuntu/ jammy-infra-security main
2980-
2981- clean http://archive.ubuntu.com/ubuntu
2982- ```
2983-4. Run `apt-mirror`: \
2984-`sudo -u apt-mirror apt-mirror`
2985-5. Serve the `esm-infra` mirror on port `9090` (will be `[ESM_INFRA_MIRROR_URL]` in the next section): \
2986-`python3 -m http.server --directory /var/spool/apt-mirror/mirror/esm.ubuntu.com/infra/ 9090`
2987-
2988-
2989-## Get configuration to run the server
2990-The prerequisites for this step are:
2991-1. Mirrors of needed resources are set up on the airgapped machine
2992-2. Mirrors of needed resources are served on some port on the airgapped machine
2993-
2994-We need to create such a configuration for our server so that it points to the local mirror server on the airgapped machine, not the Canonical one. For example, if we want to use `esm-infra` in the airgapped environment, create the `02-overridden.yml` file on the non-airgapped machine with the following contents:
2995-```yaml
2996-[YOUR_CONTRACT_TOKEN]:
2997- esm-infra:
2998- directives:
2999- aptURL: [ESM_INFRA_MIRROR_URL]
3000-```
3001-Run `ua-airgapped` for the new config in non-airgapped environment: `cat 02-overridden.yml | ua-airgapped > 02-server-ready.yml`
3002-
3003-`02-server-ready.yml` is our final configuration to run the server.
3004-
3005-## Running the server and final tweaks
3006-Run the following commands in the airgapped environment:
3007-1. Run the server: `contracts-airgapped --input=./02-server-ready.yml`
3008-2. Change the `contract_url` setting in `uaclient.conf` to point to the server: `http://1.2.3.4:8484`. Here `1.2.3.4` is the IP address of the airgapped machine.
3009-3. Run `sudo pro refresh` to check everything works fine.
3010-4. Finally, attach your token: `sudo pro attach [YOUR_CONTRACT_TOKEN]`.
3011-
3012-## Congratulations!
3013-That’s been a long run, but you’ve made it! Now you are all set to run all the `pro` commands in the airgapped environment as you are used to.
3014diff --git a/docs/index.rst b/docs/index.rst
3015index 588bed0..b63cce0 100644
3016--- a/docs/index.rst
3017+++ b/docs/index.rst
3018@@ -55,9 +55,8 @@ for you.
3019 Getting help
3020 ============
3021
3022-Having trouble? We would like to help! For help on a specific page in this
3023-documentation, click on the "Have a question?" link at the top of that page.
3024-You can also...
3025+Ubuntu Pro is a new product, and we're keen to know about your experience of
3026+using it!
3027
3028 - **Have questions?**
3029 You might find the answers `in our FAQ`_.
3030diff --git a/docs/references.rst b/docs/references.rst
3031index 3190e66..ea61895 100644
3032--- a/docs/references.rst
3033+++ b/docs/references.rst
3034@@ -1,9 +1,9 @@
3035 Ubuntu Pro Client reference
3036 ***************************
3037
3038-Our reference section contains support information for the Ubuntu Pro Client.
3039-This includes details on the network requirements, API definitions, support
3040-matrices and so on.
3041+Our reference section contains technical information for the Ubuntu Pro Client.
3042+This includes details of the network requirements, API definitions, and other
3043+related tools.
3044
3045 Reference
3046 =========
3047@@ -12,4 +12,7 @@ Reference
3048 :maxdepth: 1
3049 :glob:
3050
3051- references/*
3052+ API reference guide <references/api.md>
3053+ Network requirements <references/network_requirements.md>
3054+ Personal Package Archives (PPAs) <references/ppas.md>
3055+ Support matrix <references/support_matrix.md>
3056diff --git a/docs/references/api.md b/docs/references/api.md
3057index 996835d..4708d9b 100644
3058--- a/docs/references/api.md
3059+++ b/docs/references/api.md
3060@@ -1,10 +1,16 @@
3061-# Pro API Reference Guide
3062+# The Ubuntu Pro API reference guide
3063
3064+The Ubuntu Pro Client has a Python-based API to be consumed by users who want
3065+to integrate the Client's functionality with their software.
3066
3067-The Pro Client has a Python-based API to be consumed by users who want to integrate the client's functionality to their software.
3068-The functions and objects are available through the `uaclient.api` module, and all of the available endpoints return an object with specific data for the calls.
3069+The functions and objects are available through the `uaclient.api` module, and
3070+all of the available endpoints return an object with specific data for the
3071+calls.
3072
3073-Besides importing the Python code directly, consumers who are not writing Python may use the CLI to call the same functionality, using the `pro api` command. This command will always return a JSON with a standard structure, as can be seen below:
3074+Besides importing the Python code directly, consumers who are not writing
3075+Python may use the command line interface (CLI) to call the same functionality,
3076+using the `pro api` command. This command will always return a JSON with a
3077+standard structure, as can be seen below:
3078
3079 ```json
3080 {
3081@@ -25,6 +31,51 @@ Besides importing the Python code directly, consumers who are not writing Python
3082 }
3083 ```
3084
3085+## Version dependencies
3086+The package name of Ubuntu Pro Client is `ubuntu-advantage-tools`.
3087+
3088+The documentation for each endpoint below states the first version to include that endpoint.
3089+
3090+If you depend on these endpoints, we recommend using a standard dependency version requirement to ensure that a sufficiently up-to-date version of the Pro Client is installed before trying to use it.
3091+
3092+```{important}
3093+The `~` at the end of the version is important to ensure that dpkg version comparison works as expected.
3094+```
3095+
3096+For example, if your software is packaged as a deb, then you can add the following to your `Depends` list in your `control` file to ensure the installed version is at least 27.11~:
3097+```
3098+ubuntu-advantage-tools (>= 27.11~)
3099+```
3100+
3101+### Runtime version detection
3102+If you need to detect the current version at runtime, the most reliable way is to query `dpkg`.
3103+```
3104+dpkg-query --showformat='${Version}' --show ubuntu-advantage-tools
3105+```
3106+
3107+If you need to compare versions at runtime, make sure you use the `dpkg` version comparison algorithm.
3108+For example, the following will exit 0 if the currently installed version of Pro Client is at least 27.11~:
3109+```
3110+dpkg --compare-versions "$(dpkg-query --showformat='${Version}' --show ubuntu-advantage-tools)" ge "27.11~"
3111+```
3112+
3113+### Runtime feature detection
3114+As an alternative to version detection, you can use feature detection. This is easier to do when importing the API in python than it is when using the `pro api` subcommand.
3115+
3116+In python, try to import the desired endpoint. If an `ImportError` is raised, then the currently installed version of Ubuntu Pro Client doesn't support that endpoint.
3117+
3118+For example:
3119+```python
3120+try:
3121+ from uaclient.api.u.pro.version.v1 import version
3122+ pro_client_api_supported = True
3123+except ImportError:
3124+ pro_client_api_supported = False
3125+```
3126+
3127+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.
3128+
3129+## Available endpoints
3130 The currently available endpoints are:
3131 - [u.pro.version.v1](#uproversionv1)
3132 - [u.pro.attach.magic.initiate.v1](#uproattachmagicinitiatev1)
3133@@ -40,13 +91,19 @@ The currently available endpoints are:
3134 - [u.security.package_manifest.v1](#usecuritypackage_manifestv1)
3135
3136 ## u.pro.version.v1
3137-Shows the installed Client version.
3138+
3139+Introduced in Ubuntu Pro Client Version: `27.11~`
3140+
3141+Shows the installed Pro Client version.
3142
3143 ### Args
3144+
3145 This endpoint takes no arguments.
3146
3147 ### Python API interaction
3148+
3149 #### Calling from Python code
3150+
3151 ```python
3152 from uaclient.api.u.pro.version.v1 import version
3153
3154@@ -54,39 +111,48 @@ result = version()
3155 ```
3156
3157 #### Expected return object:
3158+
3159 `uaclient.api.u.pro.version.v1.VersionResult`
3160
3161 |Field Name|Type|Description|
3162 |-|-|-|
3163-|installed_version|str|The current installed version|
3164+|`installed_version`|*str*|The current installed version|
3165
3166-### Raised Exceptions
3167-- `VersionError`: raised if the client cannot determine the version
3168+### Raised exceptions
3169
3170+- `VersionError`: Raised if the Client cannot determine the version.
3171
3172 ### CLI interaction
3173+
3174 #### Calling from the CLI:
3175+
3176 ```bash
3177 pro api u.pro.version.v1
3178 ```
3179
3180 #### Expected attributes in JSON structure
3181+
3182 ```json
3183 {
3184 "installed_version":"<version>"
3185 }
3186 ```
3187
3188-
3189 ## u.pro.attach.magic.initiate.v1
3190+
3191+Introduced in Ubuntu Pro Client Version: `27.11~`
3192+
3193 Initiates the Magic Attach flow, retrieving the User Code to confirm the
3194 operation and the Token used to proceed.
3195
3196 ### Args
3197+
3198 This endpoint takes no arguments.
3199
3200 ### Python API interaction
3201+
3202 #### Calling from Python code
3203+
3204 ```python
3205 from uaclient.api.u.pro.attach.magic.initiate.v1 import initiate
3206
3207@@ -94,29 +160,35 @@ result = initiate()
3208 ```
3209
3210 #### Expected return object:
3211+
3212 `uaclient.api.u.pro.attach.magic.initiate.v1.MagicAttachInitiateResult`
3213
3214 |Field Name|Type|Description|
3215 |-|-|-|
3216-|user_code|str|Code the user will see in the UI when confirming the Magic Attach|
3217-|token|str|Magic token used by the tooling to continue the operation|
3218-|expires|str|Timestamp of the Magic Attach process expiration|
3219-|expires_in|int|Seconds before the Magic Attach process expires|
3220-
3221+|`user_code`|*str*|Code the user will see in the UI when confirming the Magic Attach|
3222+|`token`|*str*|Magic Token used by the tooling to continue the operation|
3223+|`expires`|*str*|Timestamp of the Magic Attach process expiration|
3224+|`expires_in`|*int*|Seconds before the Magic Attach process expires|
3225
3226-### Raised Exceptions
3227+### Raised exceptions
3228
3229-- `ConnectivityError`: raised if it is not possible to connect to the Contracts Server
3230-- `ContractAPIError`: raised if there is an unexpected error in the Contracts Server interaction
3231-- `MagicAttachUnavailable`: raised if the Magic Attach service is busy or unavailable at the moment
3232+- `ConnectivityError`: Raised if it is not possible to connect to the Contracts
3233+ Server.
3234+- `ContractAPIError`: Raised if there is an unexpected error in the Contracts
3235+ Server interaction.
3236+- `MagicAttachUnavailable`: Raised if the Magic Attach service is busy or
3237+ unavailable at the moment.
3238
3239 ### CLI interaction
3240+
3241 #### Calling from the CLI:
3242+
3243 ```bash
3244 pro api u.pro.attach.magic.initiate.v1
3245 ```
3246
3247 #### Expected attributes in JSON structure
3248+
3249 ```json
3250 {
3251 "user_code":"<UI_code>",
3252@@ -126,16 +198,20 @@ pro api u.pro.attach.magic.initiate.v1
3253 }
3254 ```
3255
3256+## u.pro.attach.magic.wait.v1
3257
3258+Introduced in Ubuntu Pro Client Version: `27.11~`
3259
3260-## u.pro.attach.magic.wait.v1
3261 Polls the contract server waiting for the user to confirm the Magic Attach.
3262
3263 ### Args
3264-- `magic_token`: The token provided by the initiate endpoint
3265+
3266+- `magic_token`: The Token provided by the initiate endpoint.
3267
3268 ### Python API interaction
3269+
3270 #### Calling from Python code
3271+
3272 ```python
3273 from uaclient.api.u.pro.attach.magic.wait.v1 import MagicAttachWaitOptions, wait
3274
3275@@ -144,33 +220,38 @@ result = wait(options)
3276 ```
3277
3278 #### Expected return object:
3279+
3280 `uaclient.api.u.pro.attach.magic.wait.v1.MagicAttachWaitResult`
3281
3282 |Field Name|Type|Description|
3283 |-|-|-|
3284-|user_code|str|Code the user will see in the UI when confirming the Magic Attach|
3285-|token|str|Magic token used by the tooling to continue the operation|
3286-|expires|str|Timestamp of the Magic Attach process expiration|
3287-|expires_in|int|Seconds before the Magic Attach process expires|
3288-|contract_id|str|ID of the contract the machine will be attached to|
3289-|contract_token|str|The contract token to attach the machine|
3290-
3291-
3292-### Raised Exceptions
3293-
3294-- `ConnectivityError`: raised if it is not possible to connect to the Contracts Server
3295-- `ContractAPIError`: raised if there is an unexpected error in the Contracts Server interaction
3296-- `MagicAttachTokenError`: raised when an invalid/expired token is sent
3297-- `MagicAttachUnavailable`: raised if the Magic Attach service is busy or unavailable at the moment
3298-
3299+|`user_code`|*str*|Code the user will see in the UI when confirming the Magic Attach|
3300+|`token`|*str*|Magic Token used by the tooling to continue the operation|
3301+|`expires`|*str*|Timestamp of the Magic Attach process expiration|
3302+|`expires_in`|*int*|Seconds before the Magic Attach process expires|
3303+|`contract_id`|*str*|ID of the contract the machine will be attached to|
3304+|`contract_token`|*str*|The contract Token to attach the machine|
3305+
3306+### Raised exceptions
3307+
3308+- `ConnectivityError`: Raised if it is not possible to connect to the Contracts
3309+ Server.
3310+- `ContractAPIError`: Raised if there is an unexpected error in the Contracts
3311+ Server interaction.
3312+- `MagicAttachTokenError`: Raised when an invalid/expired Token is sent.
3313+- `MagicAttachUnavailable`: Raised if the Magic Attach service is busy or
3314+ unavailable at the moment.
3315
3316 ### CLI interaction
3317+
3318 #### Calling from the CLI:
3319+
3320 ```bash
3321 pro api u.pro.attach.magic.wait.v1 --args magic_token=<magic_token>
3322 ```
3323
3324 #### Expected attributes in JSON structure
3325+
3326 ```json
3327 {
3328 "user_code":"<UI_code>",
3329@@ -182,15 +263,20 @@ pro api u.pro.attach.magic.wait.v1 --args magic_token=<magic_token>
3330 }
3331 ```
3332
3333-
3334 ## u.pro.attach.magic.revoke.v1
3335-Revokes a magic attach token.
3336+
3337+Introduced in Ubuntu Pro Client Version: `27.11~`
3338+
3339+Revokes a Magic Attach Token.
3340
3341 ### Args
3342-- `magic_token`: The token provided by the initiate endpoint
3343+
3344+- `magic_token`: The Token provided by the initiate endpoint.
3345
3346 ### Python API interaction
3347+
3348 #### Calling from Python code
3349+
3350 ```python
3351 from uaclient.api.u.pro.attach.magic.revoke.v1 import MagicAttachRevokeOptions, revoke
3352
3353@@ -199,40 +285,51 @@ result = revoke(options)
3354 ```
3355
3356 #### Expected return object:
3357+
3358 `uaclient.api.u.pro.attach.magic.wait.v1.MagicAttachRevokeResult`
3359
3360 No data present in the result.
3361
3362+### Raised exceptions
3363
3364-### Raised Exceptions
3365-
3366-- `ConnectivityError`: raised if it is not possible to connect to the Contracts Server
3367-- `ContractAPIError`: raised if there is an unexpected error in the Contracts Server interaction
3368-- `MagicAttachTokenAlreadyActivated`: raised when trying to revoke a token which was already activated through the UI
3369-- `MagicAttachTokenError`: raised when an invalid/expired token is sent
3370-- `MagicAttachUnavailable`: raised if the Magic Attach service is busy or unavailable at the moment
3371-
3372+- `ConnectivityError`: Raised if it is not possible to connect to the Contracts
3373+ Server.
3374+- `ContractAPIError`: Raised if there is an unexpected error in the Contracts
3375+ Server interaction.
3376+- `MagicAttachTokenAlreadyActivated`: Raised when trying to revoke a Token
3377+ which was already activated through the UI.
3378+- `MagicAttachTokenError`: Raised when an invalid/expired Token is sent.
3379+- `MagicAttachUnavailable`: Raised if the Magic Attach service is busy or
3380+ unavailable at the moment.
3381
3382 ### CLI interaction
3383+
3384 #### Calling from the CLI:
3385+
3386 ```bash
3387 pro api u.pro.attach.magic.revoke.v1 --args magic_token=<token>
3388 ```
3389
3390 #### Expected attributes in JSON structure
3391+
3392 ```json
3393 {}
3394 ```
3395
3396-
3397 ## u.pro.attach.auto.should_auto_attach.v1
3398+
3399+Introduced in Ubuntu Pro Client Version: `27.11~`
3400+
3401 Checks if a given system should run auto-attach on boot.
3402
3403 ### Args
3404+
3405 This endpoint takes no arguments.
3406
3407 ### Python API interaction
3408+
3409 #### Calling from Python code
3410+
3411 ```python
3412 from uaclient.api.u.pro.attach.auto.should_auto_attach.v1 import should_auto_attach
3413
3414@@ -240,40 +337,53 @@ result = should_auto_attach()
3415 ```
3416
3417 #### Expected return object:
3418+
3419 `uaclient.api.u.pro.attach.auto.should_auto_attach.v1.ShouldAutoAttachResult`
3420
3421 |Field Name|Type|Description|
3422 |-|-|-|
3423-|should_auto_attach|bool|True if the system should run auto-attach on boot|
3424+|`should_auto_attach`|*bool*|True if the system should run auto-attach on boot|
3425+
3426+### Raised exceptions
3427
3428-### Raised Exceptions
3429 No exceptions raised by this endpoint.
3430
3431 ### CLI interaction
3432+
3433 #### Calling from the CLI:
3434+
3435 ```bash
3436 pro api u.pro.attach.auto.should_auto_attach.v1
3437 ```
3438
3439 #### Expected attributes in JSON structure
3440+
3441 ```json
3442 {
3443 "should_auto_attach": false
3444 }
3445 ```
3446
3447-
3448 ## u.pro.attach.auto.full_auto_attach.v1
3449+
3450+Introduced in Ubuntu Pro Client Version: `27.11~`
3451+
3452 Runs the whole auto-attach process on the system.
3453
3454 ### Args
3455-- `enable`: optional list of services to enable after auto-attaching
3456-- `enable_beta`: optional list of beta services to enable after auto-attaching
3457
3458-> If none of the lists are set, the services will be enabled based on the contract definitions.
3459+- `enable`: Optional list of services to enable after auto-attaching.
3460+- `enable_beta`: Optional list of beta services to enable after auto-attaching.
3461+
3462+```{note}
3463+If none of the lists are set, the services will be enabled based on the
3464+contract definitions.
3465+```
3466
3467 ### Python API interaction
3468+
3469 #### Calling from Python code
3470+
3471 ```python
3472 from uaclient.api.u.pro.attach.auto.full_auto_attach.v1 import full_auto_attach, FullAutoAttachOptions
3473
3474@@ -282,46 +392,70 @@ result = full_auto_attach(options)
3475 ```
3476
3477 #### Expected return object:
3478+
3479 `uaclient.api.u.pro.attach.auto.full_auto_attach.v1.FullAutoAttachResult`
3480
3481 No data present in the result.
3482
3483-### Raised Exceptions
3484-
3485-- `AlreadyAttachedError`: raised if running on a machine which is already attached to a Pro subscription
3486-- `AutoAttachDisabledError`: raised if `disable_auto_attach: true` in uaclient.conf
3487-- `ConnectivityError`: raised if it is not possible to connect to the Contracts Server
3488-- `ContractAPIError`: raised if there is an unexpected error in the Contracts Server interaction
3489-- `EntitlementsNotEnabledError`: raised if the client fails to enable any of the entitlements
3490- (whether present in any of the lists or listed in the contract)
3491-- `LockHeldError`: raised if another Client process is holding the lock on the machine
3492-- `NonAutoAttachImageError`: raised if the cloud where the system is running does not support auto-attach
3493-- `UserFacingError`: raised if:
3494- - the client is unable to determine on which cloud the system is running
3495- - the image where the client is running does not support auto-attach
3496-
3497+### Raised exceptions
3498+
3499+- `AlreadyAttachedError`: Raised if running on a machine which is already
3500+ attached to a Pro subscription.
3501+- `AutoAttachDisabledError`: Raised if `disable_auto_attach: true` in
3502+ `uaclient.conf`.
3503+- `ConnectivityError`: Raised if it is not possible to connect to the Contracts
3504+ Server.
3505+- `ContractAPIError`: Raised if there is an unexpected error in the Contracts
3506+ Server interaction.
3507+- `EntitlementsNotEnabledError`: Raised if the Client fails to enable any of
3508+ the entitlements (whether present in any of the lists or listed in the
3509+ contract).
3510+- `LockHeldError`: Raised if another Client process is holding the lock on the
3511+ machine.
3512+- `NonAutoAttachImageError`: Raised if the cloud where the system is running
3513+ does not support auto-attach.
3514+- `UserFacingError`: Raised if:
3515+ - The Client is unable to determine which cloud the system is running on.
3516+ - The image where the Client is running does not support auto-attach.
3517
3518 ### CLI interaction
3519+
3520 #### Calling from the CLI:
3521-This endpoint currently has no CLI support. Only the Python-based version is available.
3522
3523+This endpoint currently has no CLI support. Only the Python-based version is
3524+available.
3525
3526 ## u.pro.attach.auto.configure_retry_service.v1
3527-Configures options for the retry auto attach functionality and create file that will activate the retry auto attach functionality if `ubuntu-advantage.service` runs.
3528
3529-Note that this does not start `ubuntu-advantage.service`. This makes it useful for calling during the boot process `Before: ubuntu-advantage.service` so that when `ubuntu-advantage.service` starts, its ConditionPathExists check passes and executes the retry auto attach function.
3530+Introduced in Ubuntu Pro Client Version: `27.12~`
3531
3532-If you call this function outside of the boot process and would like the retry auto attach functionality to actually start, you'll need to call something like `systemctl start ubuntu-advantage.service`.
3533+Configures options for the retry auto-attach functionality, and creates files
3534+that will activate the retry auto-attach functionality if
3535+`ubuntu-advantage.service` runs.
3536
3537+Note that this does not start `ubuntu-advantage.service`. This makes it useful
3538+for calling during the boot process `Before: ubuntu-advantage.service` so that
3539+when `ubuntu-advantage.service` starts, its `ConditionPathExists` check passes
3540+and activates the retry auto-attach function.
3541+
3542+If you call this function outside of the boot process and would like the retry
3543+auto-attach functionality to actually start, you'll need to call something
3544+like `systemctl start ubuntu-advantage.service`.
3545
3546 ### Args
3547-- `enable`: optional list of services to enable after auto-attaching
3548-- `enable_beta`: optional list of beta services to enable after auto-attaching
3549
3550-> If none of the lists are set, the services will be enabled based on the contract definitions.
3551+- `enable`: Optional list of services to enable after auto-attaching.
3552+- `enable_beta`: Optional list of beta services to enable after auto-attaching.
3553+
3554+```{note}
3555+If none of the lists are set, the services will be enabled based on the
3556+contract definitions.
3557+```
3558
3559 ### Python API interaction
3560+
3561 #### Calling from Python code
3562+
3563 ```python
3564 from uaclient.api.u.pro.attach.auto.configure_retry_service.v1 import configure_retry_service, ConfigureRetryServiceOptions
3565
3566@@ -330,26 +464,36 @@ result = configure_retry_service(options)
3567 ```
3568
3569 #### Expected return object:
3570+
3571 `uaclient.api.u.pro.attach.auto.configure_retry_service.v1.ConfigureRetryServiceResult`
3572
3573 No data present in the result.
3574
3575-### Raised Exceptions
3576+### Raised exceptions
3577+
3578 No exceptions raised by this endpoint.
3579
3580 ### CLI interaction
3581+
3582 #### Calling from the CLI:
3583-This endpoint currently has no CLI support. Only the Python-based version is available.
3584
3585+This endpoint currently has no CLI support. Only the Python-based version is
3586+available.
3587
3588 ## u.pro.security.status.livepatch_cves.v1
3589-Lists Livepatch patches for the current running kernel.
3590+
3591+Introduced in Ubuntu Pro Client Version: `27.12~`
3592+
3593+Lists Livepatch patches for the currently-running kernel.
3594
3595 ### Args
3596+
3597 This endpoint takes no arguments.
3598
3599 ### Python API interaction
3600+
3601 #### Calling from Python code
3602+
3603 ```python
3604 from uaclient.api.u.pro.security.status.livepatch_cves.v1 import livepatch_cves
3605
3606@@ -357,30 +501,33 @@ result = livepatch_cves()
3607 ```
3608
3609 #### Expected return object:
3610+
3611 `uaclient.api.u.pro.security.status.livepatch_cves.v1.LivepatchCVEsResult`
3612
3613 |Field Name|Type|Description|
3614 |-|-|-|
3615-|fixed_cves|list(LivepatchCVEObject)|List of Livepatch patches for the given system|
3616+|`fixed_cves`|*list(LivepatchCVEObject)*|List of Livepatch patches for the given system|
3617
3618 `uaclient.api.u.pro.security.status.livepatch_cves.v1.LivepatchCVEObject`
3619 |Field Name|Type|Description|
3620 |-|-|-|
3621-|name|str|Name (ID) of the CVE|
3622-|patched|bool|Livepatch has patched the CVE|
3623+|`name`|*str*|Name (ID) of the CVE|
3624+|`patched`|*bool*|Livepatch has patched the CVE|
3625
3626+### Raised exceptions
3627
3628-### Raised Exceptions
3629 No exceptions raised by this endpoint.
3630
3631-
3632 ### CLI interaction
3633+
3634 #### Calling from the CLI:
3635+
3636 ```bash
3637 pro api u.pro.security.status.livepatch_cves.v1
3638 ```
3639
3640 #### Expected attributes in JSON structure
3641+
3642 ```json
3643 {
3644 "fixed_cves":[
3645@@ -396,19 +543,25 @@ pro api u.pro.security.status.livepatch_cves.v1
3646 }
3647 ```
3648
3649-
3650 ## u.pro.security.status.reboot_required.v1
3651-Informs if the system should be rebooted or not.
3652-Possible outputs are:
3653-- yes: the system should be rebooted
3654-- no: there is no need to reboot the system
3655-- yes-kernel-livepatches-applied: there are livepatch patches applied to the current kernel, but a reboot is required for an update to take place. This reboot can wait until the next maintenance window.
3656+
3657+Introduced in Ubuntu Pro Client Version: `27.12~`
3658+
3659+Informs if the system should be rebooted or not. Possible outputs are:
3660+- `yes`: The system should be rebooted.
3661+- `no`: There is no need to reboot the system.
3662+- `yes-kernel-livepatches-applied`: There are Livepatch patches applied to the
3663+ current kernel, but a reboot is required for an update to take place. This
3664+ reboot can wait until the next maintenance window.
3665
3666 ### Args
3667+
3668 This endpoint takes no arguments.
3669
3670 ### Python API interaction
3671+
3672 #### Calling from Python code
3673+
3674 ```python
3675 from uaclient.api.u.pro.security.status.reboot_required.v1 import reboot_required
3676
3677@@ -416,38 +569,47 @@ result = reboot_required()
3678 ```
3679
3680 #### Expected return object:
3681+
3682 `uaclient.api.u.pro.security.status.reboot_required.v1.RebootRequiredResult`
3683
3684 |Field Name|Type|Description|
3685 |-|-|-|
3686-|reboot_required|str|One of the descriptive strings indicating if the system should be rebooted|
3687+|`reboot_required`|*str*|One of the descriptive strings indicating if the system should be rebooted|
3688
3689-### Raised Exceptions
3690-No exceptions raised by this endpoint.
3691+### Raised exceptions
3692
3693+No exceptions raised by this endpoint.
3694
3695 ### CLI interaction
3696+
3697 #### Calling from the CLI:
3698+
3699 ```bash
3700 pro api u.pro.security.status.reboot_required.v1
3701 ```
3702
3703 #### Expected attributes in JSON structure
3704+
3705 ```json
3706 {
3707 "reboot_required": "yes|no|yes-kernel-livepatches-applied"
3708 }
3709 ```
3710
3711-
3712 ## u.pro.packages.summary.v1
3713+
3714+Introduced in Ubuntu Pro Client Version: `27.12~`
3715+
3716 Shows a summary of installed packages in the system, categorized by origin.
3717
3718 ### Args
3719+
3720 This endpoint takes no arguments.
3721
3722 ### Python API interaction
3723+
3724 #### Calling from Python code
3725+
3726 ```python
3727 from uaclient.api.u.pro.packages.summary.v1 import summary
3728
3729@@ -455,37 +617,40 @@ result = summary()
3730 ```
3731
3732 #### Expected return object:
3733+
3734 `uaclient.api.u.pro.packages.summary.v1.PackageSummaryResult`
3735
3736 |Field Name|Type|Description|
3737 |-|-|-|
3738-|summary|PackageSummary|Summary of all installed packages|
3739+|`summary`|*PackageSummary*|Summary of all installed packages|
3740
3741 `uaclient.api.u.pro.packages.summary.v1.PackageSummary`
3742 |Field Name|Type|Description|
3743 |-|-|-|
3744-|num_installed_packages|int|Total count of installed packages|
3745-|num_esm_apps_packages|int|Count of packages installed from esm-apps|
3746-|num_esm_infra_packages|int|Count of packages installed from esm-infra|
3747-|num_main_packages|int|Count of packages installed from main|
3748-|num_multiverse_packages|int|Count of packages installed from multiverse|
3749-|num_restricted_packages|int|Count of packages installed from restricted|
3750-|num_third_party_packages|int|Count of packages installed from third party sources|
3751-|num_universe_packages|int|Count of packages installed from universe|
3752-|num_unknown_packages|int|Count of packages installed from unknown sources|
3753-
3754-
3755-### Raised Exceptions
3756-No exceptions raised by this endpoint.
3757+|`num_installed_packages`|*int*|Total count of installed packages|
3758+|`num_esm_apps_packages`|*int*|Count of packages installed from `esm-apps`|
3759+|`num_esm_infra_packages`|*int*|Count of packages installed from `esm-infra`|
3760+|`num_main_packages`|*int*|Count of packages installed from `main`|
3761+|`num_multiverse_packages`|*int*|Count of packages installed from `multiverse`|
3762+|`num_restricted_packages`|*int*|Count of packages installed from `restricted`|
3763+|`num_third_party_packages`|*int*|Count of packages installed from third party sources|
3764+|`num_universe_packages`|*int*|Count of packages installed from `universe`|
3765+|`num_unknown_packages`|*int*|Count of packages installed from unknown sources|
3766+
3767+### Raised exceptions
3768
3769+No exceptions raised by this endpoint.
3770
3771 ### CLI interaction
3772+
3773 #### Calling from the CLI:
3774+
3775 ```bash
3776 pro api u.pro.packages.summary.v1
3777 ```
3778
3779 #### Expected attributes in JSON structure
3780+
3781 ```json
3782 {
3783 "summary":{
3784@@ -502,15 +667,21 @@ pro api u.pro.packages.summary.v1
3785 }
3786 ```
3787
3788-
3789 ## u.pro.packages.updates.v1
3790-Shows available updates for packages in a system, categorized by where they can be obtained.
3791+
3792+Introduced in Ubuntu Pro Client Version: `27.12~`
3793+
3794+Shows available updates for packages in a system, categorized by where they
3795+can be obtained.
3796
3797 ### Args
3798+
3799 This endpoint takes no arguments.
3800
3801 ### Python API interaction
3802+
3803 #### Calling from Python code
3804+
3805 ```python
3806 from uaclient.api.u.pro.packages.updates.v1 import updates
3807
3808@@ -518,44 +689,48 @@ result = updates()
3809 ```
3810
3811 #### Expected return object:
3812+
3813 `uaclient.api.u.pro.packages.updates.v1.PackageUpdatesResult`
3814
3815 |Field Name|Type|Description|
3816 |-|-|-|
3817-|summary|UpdateSummary|Summary of all available updates|
3818-|updates|list(UpdateInfo)|Detailed list of all available updates|
3819+|`summary`|*UpdateSummary*|Summary of all available updates|
3820+|`updates`|*list(UpdateInfo)*|Detailed list of all available updates|
3821
3822 `uaclient.api.u.pro.packages.updates.v1.UpdateSummary`
3823
3824 |Field Name|Type|Description|
3825 |-|-|-|
3826-|num_updates|int|Total count of available updates|
3827-|num_esm_apps_updates|int|Count of available updates from esm-apps|
3828-|num_esm_infra_updates|int|Count of available updates from esm-infra|
3829-|num_standard_security_updates|int|Count of available updates from the -security pocket|
3830-|num_standard_updates|int|Count of available updates from the -updates pocket|
3831+|`num_updates`|*int*|Total count of available updates|
3832+|`num_esm_apps_updates`|*int*|Count of available updates from `esm-apps`|
3833+|`num_esm_infra_updates`|*int*|Count of available updates from `esm-infra`|
3834+|`num_standard_security_updates`|*int*|Count of available updates from the `-security` pocket|
3835+|`num_standard_updates`|*int*|Count of available updates from the `-updates` pocket|
3836
3837 `uaclient.api.u.pro.packages.updates.v1.UpdateInfo`
3838 |Field Name|Type|Description|
3839 |-|-|-|
3840-|download_size|int|Download size for the update in bytes|
3841-|origin|str|Where the update is downloaded from|
3842-|package|str|Name of the package to be updated|
3843-|provided_by|str|Service which provides the update|
3844-|status|str|Whether this update is ready for download or not|
3845-|version|str|Version of the update|
3846-
3847-### Raised Exceptions
3848-No exceptions raised by this endpoint.
3849+|`download_size`|*int*|Download size for the update in bytes|
3850+|`origin`|*str*|Where the update is downloaded from|
3851+|`package`|*str*|Name of the package to be updated|
3852+|`provided_by`|*str*|Service which provides the update|
3853+|`status`|*str*|Whether this update is ready for download or not|
3854+|`version`|*str*|Version of the update|
3855
3856+### Raised exceptions
3857+
3858+No exceptions raised by this endpoint.
3859
3860 ### CLI interaction
3861+
3862 #### Calling from the CLI:
3863+
3864 ```bash
3865 pro api u.pro.packages.updates.v1
3866 ```
3867
3868 #### Expected attributes in JSON structure
3869+
3870 ```json
3871 {
3872 "summary":{
3873@@ -578,16 +753,21 @@ pro api u.pro.packages.updates.v1
3874 }
3875 ```
3876
3877-
3878 ## u.security.package_manifest.v1
3879-Returns the status of installed packages (apt and snap), formatted as a
3880-manifest file (i.e. `package_name\tversion`)
3881+
3882+Introduced in Ubuntu Pro Client Version: `27.12~`
3883+
3884+Returns the status of installed packages (`apt` and `snap`), formatted as a
3885+manifest file (i.e. `package_name\tversion`).
3886
3887 ### Args
3888+
3889 This endpoint takes no arguments.
3890
3891 ### Python API interaction
3892+
3893 #### Calling from Python code
3894+
3895 ```python
3896 from uaclient.api.u.security.package_manifest.v1 import package_manifest
3897
3898@@ -595,23 +775,27 @@ result = package_manifest()
3899 ```
3900
3901 #### Expected return object:
3902+
3903 `uaclient.api.u.security.package_manifest.v1.PackageManifestResult`
3904
3905 |Field Name|Type|Description|
3906 |-|-|-|
3907-|manifest_data|str|Manifest of apt and snap packages installed on the system|
3908+|`manifest_data`|*str*|Manifest of `apt` and `snap` packages installed on the system|
3909
3910-### Raised Exceptions
3911-No exceptions raised by this endpoint.
3912+### Raised exceptions
3913
3914+No exceptions raised by this endpoint.
3915
3916 ### CLI interaction
3917+
3918 #### Calling from the CLI:
3919+
3920 ```bash
3921 pro api u.security.package_manifest.v1
3922 ```
3923
3924 #### Expected attributes in JSON structure
3925+
3926 ```json
3927 {
3928 "package_manifest":"package1\t1.0\npackage2\t2.3\n"
3929diff --git a/docs/references/network_requirements.md b/docs/references/network_requirements.md
3930index 505f081..cb25256 100644
3931--- a/docs/references/network_requirements.md
3932+++ b/docs/references/network_requirements.md
3933@@ -1,18 +1,35 @@
3934-# Ubuntu Pro Client Network Requirements
3935+# Ubuntu Pro Client network requirements
3936
3937-Using the Ubuntu Pro Client to enable support services will rely on network access to obtain updated service
3938-credentials, add APT repositories to install deb packages and install [snap packages](https://snapcraft.io/about) when
3939-Livepatch is enabled. Also see the Proxy Configuration explanation to inform Ubuntu Pro Client of HTTP(S)/APT proxies.
3940+Using the Ubuntu Pro Client to enable support services will rely on network
3941+access to:
3942
3943-Ensure the managed system has access to the following port:urls if in a network-limited environment:
3944+- Obtain updated service credentials
3945+- Add APT repositories to install `deb` packages
3946+- Install [`snap` packages](https://snapcraft.io/about) when Livepatch is
3947+ enabled.
3948
3949-* 443:https://contracts.canonical.com/ - HTTP PUTs, GETs and POSTs for Ubuntu Pro Client interaction
3950-* 443:https://esm.ubuntu.com/\* - APT repository access for most services
3951+```{seealso}
3952
3953-Enabling kernel Livepatch require additional network egress:
3954+You can also refer to our [Proxy Configuration guide](/../howtoguides/configure_proxies.md)
3955+to learn how to inform Ubuntu Pro Client of HTTP(S)/APT proxies.
3956+```
3957
3958-* snap endpoints required in order to install and run snaps as defined in [snap forum network-requirements post](https://forum.snapcraft.io/t/network-requirements/5147)
3959-* 443:api.snapcraft.io
3960-* 443:dashboard.snapcraft.io
3961-* 443:login.ubuntu.com
3962-* 443:\*.snapcraftcontent.com - Download CDNs
3963+## Network-limited
3964+
3965+Ensure the managed system has access to the following port:urls if in a
3966+network-limited environment:
3967+
3968+* `443:https://contracts.canonical.com/`: HTTP PUTs, GETs and POSTs for Ubuntu
3969+ Pro Client interaction.
3970+* `443:https://esm.ubuntu.com/\*`: APT repository access for most services.
3971+
3972+## Enable kernel Livepatch
3973+
3974+Enabling kernel Livepatch requires additional network egress:
3975+
3976+* `snap` endpoints required in order to install and run snaps as defined in
3977+ [snap forum network-requirements post](https://forum.snapcraft.io/t/network-requirements/5147)
3978+* `443:api.snapcraft.io`
3979+* `443:dashboard.snapcraft.io`
3980+* `443:login.ubuntu.com`
3981+* `443:\*.snapcraftcontent.com` - Download CDNs
3982diff --git a/docs/references/ppas.md b/docs/references/ppas.md
3983index 0642714..05f99ec 100644
3984--- a/docs/references/ppas.md
3985+++ b/docs/references/ppas.md
3986@@ -1,9 +1,30 @@
3987-# Available PPAs with different version of Ubuntu Pro Client
3988-There are 3 PPAs with different release channels of the Ubuntu Pro Client:
3989-
3990-1. Stable: This contains stable builds only which have been verified for release into Ubuntu stable releases or Ubuntu Pro images.
3991- - add with `sudo add-apt-repository ppa:ua-client/stable`
3992-2. Staging: This contains builds under validation for release to stable Ubuntu releases and images
3993- - add with `sudo add-apt-repository ppa:ua-client/staging`
3994-3. Daily: This PPA is updated every day with the latest changes.
3995- - add with `sudo add-apt-repository ppa:ua-client/daily`
3996+# Ubuntu Pro Client PPAs
3997+
3998+There are three Personal Package Archives (PPAs) with different release
3999+channels in the Ubuntu Pro Client: *Stable*, *Staging*, and *Daily*.
4000+
4001+## Stable
4002+
4003+This contains stable builds only, which have been verified for release into
4004+Ubuntu stable releases or Ubuntu Pro images. You can add it with:
4005+
4006+```
4007+sudo add-apt-repository ppa:ua-client/stable
4008+```
4009+
4010+## Staging
4011+
4012+This contains builds *under validation* for release to stable Ubuntu releases
4013+and images. You can add it with:
4014+
4015+```
4016+sudo add-apt-repository ppa:ua-client/staging
4017+```
4018+
4019+## Daily
4020+
4021+This PPA is updated every day with the latest changes. You can add it with:
4022+
4023+```
4024+sudo add-apt-repository ppa:ua-client/daily
4025+```
4026diff --git a/docs/references/support_matrix.md b/docs/references/support_matrix.md
4027index 0f35f70..09cfa6d 100644
4028--- a/docs/references/support_matrix.md
4029+++ b/docs/references/support_matrix.md
4030@@ -1,19 +1,19 @@
4031-# Support Matrix for the client
4032+# Support matrix for the Ubuntu Pro Client
4033
4034-Ubuntu Pro services are only available on Ubuntu Long Term Support (LTS) releases.
4035+Ubuntu Pro services are only available on Ubuntu Long Term Support (LTS)
4036+releases.
4037
4038-On interim Ubuntu releases, `pro status` will report most of the services as 'n/a' and disallow enabling those services.
4039+On interim Ubuntu releases, `pro status` will report most of the services as
4040+"n/a" (not applicable), and disallow enabling those services.
4041
4042-Below is a list of platforms and releases ubuntu-advantage-tools supports
4043+Here is a list of platforms and releases that `ubuntu-advantage-tools` supports.
4044
4045-| Ubuntu Release | Build Architectures | Support Level |
4046-| -------------- | -------------------------------------------------- | -------------------------- |
4047-| Trusty | amd64, arm64, armhf, i386, powerpc, ppc64el | Last release 19.6 |
4048-| Xenial | amd64, arm64, armhf, i386, powerpc, ppc64el, s390x | Active SRU of all features |
4049-| Bionic | amd64, arm64, armhf, i386, ppc64el, s390x | Active SRU of all features |
4050-| Focal | amd64, arm64, armhf, ppc64el, riscv64, s390x | Active SRU of all features |
4051-| Groovy | amd64, arm64, armhf, ppc64el, riscv64, s390x | Last release 27.1 |
4052-| Hirsute | amd64, arm64, armhf, ppc64el, riscv64, s390x | Last release 27.5 |
4053-| Impish | amd64, arm64, armhf, ppc64el, riscv64, s390x | Last release 27.9 |
4054-| Jammy | amd64, arm64, armhf, ppc64el, riscv64, s390x | Active SRU of all features |
4055-| Kinetic | amd64, arm64, armhf, ppc64el, riscv64, s390x | Active SRU of all features |
4056+| Ubuntu Release | Build Architectures | Initial Release | Final Release |
4057+| -------------- | -------------------------------------------------- | --------------- | -------------------------- |
4058+| Trusty | amd64, arm64, armhf, i386, powerpc, ppc64el | None | 19.6 |
4059+| Xenial | amd64, arm64, armhf, i386, powerpc, ppc64el, s390x | None | Active SRU of all features |
4060+| Bionic | amd64, arm64, armhf, i386, ppc64el, s390x | 17 | Active SRU of all features |
4061+| Focal | amd64, arm64, armhf, ppc64el, riscv64, s390x | 20.3 | Active SRU of all features |
4062+| Jammy | amd64, arm64, armhf, ppc64el, riscv64, s390x | 27.7 | Active SRU of all features |
4063+| Kinetic | amd64, arm64, armhf, ppc64el, riscv64, s390x | 27.11.2 | Active SRU of all features |
4064+| Lunar | amd64, arm64, armhf, ppc64el, riscv64, s390x | TBD | Active SRU of all features |
4065diff --git a/features/_version.feature b/features/_version.feature
4066index 8d1cea5..2a575d8 100644
4067--- a/features/_version.feature
4068+++ b/features/_version.feature
4069@@ -25,6 +25,14 @@ Feature: Pro is expected version
4070 """
4071 $behave_var{version}
4072 """
4073+ # The following doesn't actually assert anything. It merely ensures that the output of
4074+ # apt-cache policy ubuntu-advantage-tools on the test machine is included in our test output.
4075+ # This is useful to manually verify the package is installed from the correct source e.g. -proposed.
4076+ When I check the apt-cache policy of ubuntu-advantage-tools
4077+ Then the apt-cache policy of ubuntu-advantage-tools is
4078+ """
4079+ THIS GETS REPLACED AT RUNTIME VIA A HACK IN steps/ubuntu_advantage_tools.py
4080+ """
4081 Examples: version
4082 | release |
4083 | xenial |
4084@@ -50,6 +58,14 @@ Feature: Pro is expected version
4085 """
4086 $behave_var{version}
4087 """
4088+ # The following doesn't actually assert anything. It merely ensures that the output of
4089+ # apt-cache policy ubuntu-advantage-tools on the test machine is included in our test output.
4090+ # This is useful to manually verify the package is installed from the correct source e.g. -proposed.
4091+ When I check the apt-cache policy of ubuntu-advantage-tools
4092+ Then the apt-cache policy of ubuntu-advantage-tools is
4093+ """
4094+ THIS GETS REPLACED AT RUNTIME VIA A HACK IN steps/ubuntu_advantage_tools.py
4095+ """
4096 Examples: version
4097 | release |
4098 | xenial |
4099diff --git a/features/api_packages.feature b/features/api_packages.feature
4100index 82d6b99..e22798b 100644
4101--- a/features/api_packages.feature
4102+++ b/features/api_packages.feature
4103@@ -21,16 +21,18 @@ Feature: Package related API endpoints
4104 # Install some outdated package
4105 And I run `apt install <package>=<outdated_version> -y --allow-downgrades` with sudo
4106 # See the update there
4107- When I run `pro api u.pro.packages.updates.v1` as non-root
4108+ When I store candidate version of package `<package>`
4109+ And I regexify `candidate` stored var
4110+ And I run `pro api u.pro.packages.updates.v1` as non-root
4111 Then stdout matches regexp:
4112 """
4113- {"download_size": \d+, "origin": ".+", "package": "<package>", "provided_by": "<provided_by>", "status": "upgrade_available", "version": "<candidate_version>"}
4114+ {"download_size": \d+, "origin": ".+", "package": "<package>", "provided_by": "<provided_by>", "status": "upgrade_available", "version": "$behave_var{stored_var candidate}"}
4115 """
4116
4117 Examples: ubuntu release
4118- | release | package | outdated_version | candidate_version | provided_by |
4119- | xenial | libcurl3-gnutls | 7.47.0-1ubuntu2 | 7.47.0-1ubuntu2.19\+esm6 | esm-infra |
4120- | bionic | libcurl4 | 7.58.0-2ubuntu3 | 7.58.0-2ubuntu3.22 | standard-security |
4121- | focal | libcurl4 | 7.68.0-1ubuntu2 | 7.68.0-1ubuntu2.15 | standard-security |
4122- | jammy | libcurl4 | 7.81.0-1 | 7.81.0-1ubuntu1.7 | standard-security |
4123- | kinetic | libcurl4 | 7.85.0-1 | 7.85.0-1ubuntu0.2 | standard-security |
4124+ | release | package | outdated_version | provided_by |
4125+ | xenial | libcurl3-gnutls | 7.47.0-1ubuntu2 | esm-infra |
4126+ | bionic | libcurl4 | 7.58.0-2ubuntu3 | standard-security |
4127+ | focal | libcurl4 | 7.68.0-1ubuntu2 | standard-security |
4128+ | jammy | libcurl4 | 7.81.0-1 | standard-security |
4129+ | kinetic | libcurl4 | 7.85.0-1 | standard-security |
4130diff --git a/features/api_security.feature b/features/api_security.feature
4131index 9d4c74d..85e8ae8 100644
4132--- a/features/api_security.feature
4133+++ b/features/api_security.feature
4134@@ -29,7 +29,17 @@ Feature: API security/security status tests
4135 """
4136 When I run `apt update` with sudo
4137 And I run `apt upgrade -y` with sudo
4138- And I run `apt install jq bzip2 libopenscap8 -y` with sudo
4139+ And I run `apt install jq bzip2 -y` with sudo
4140+ # Install the oscap version 1.3.7 which solved the epoch error message issue
4141+ And I run `apt-get install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev g++ libapt-pkg-dev libyaml-dev libxmlsec1-dev libxmlsec1-openssl` with sudo
4142+ And I run `wget https://github.com/OpenSCAP/openscap/releases/download/1.3.7/openscap-1.3.7.tar.gz` as non-root
4143+ And I run `tar xzf openscap-1.3.7.tar.gz` as non-root
4144+ And I run shell command `mkdir -p openscap-1.3.7/build` as non-root
4145+ And I run shell command `cd openscap-1.3.7/build/ && cmake ..` with sudo
4146+ And I run shell command `cd openscap-1.3.7/build/ && make` with sudo
4147+ And I run shell command `cd openscap-1.3.7/build/ && make install` with sudo
4148+ # Installs its shared libs in /usr/local/lib/
4149+ And I run `ldconfig` with sudo
4150 And I run shell command `pro api u.security.package_manifest.v1 | jq -r '.data.attributes.manifest_data' > manifest` as non-root
4151 And I run shell command `wget https://security-metadata.canonical.com/oval/oci.com.ubuntu.<release>.usn.oval.xml.bz2` as non-root
4152 And I run `bunzip2 oci.com.ubuntu.<release>.usn.oval.xml.bz2` as non-root
4153diff --git a/features/api_unattended_upgrades.feature b/features/api_unattended_upgrades.feature
4154new file mode 100644
4155index 0000000..43f0ef6
4156--- /dev/null
4157+++ b/features/api_unattended_upgrades.feature
4158@@ -0,0 +1,207 @@
4159+Feature: api.u.unattended_upgrades.status.v1
4160+
4161+ @series.all
4162+ @uses.config.machine_type.lxd.container
4163+ Scenario Outline: v1 unattended upgrades status
4164+ Given a `<release>` machine with ubuntu-advantage-tools installed
4165+ When I run `pro api u.unattended_upgrades.status.v1` as non-root
4166+ Then stdout matches regexp:
4167+ """
4168+ {"_schema_version": "v1", "data": {"attributes": {"apt_periodic_job_enabled": true, "package_lists_refresh_frequency_days": 1, "systemd_apt_timer_enabled": true, "unattended_upgrades_allowed_origins": \["\$\{distro_id\}:\$\{distro_codename\}", "\$\{distro_id\}:\$\{distro_codename\}\-security", "\$\{distro_id\}ESMApps:\$\{distro_codename\}\-apps-security", "\$\{distro_id\}ESM:\$\{distro_codename\}\-infra-security"\], "unattended_upgrades_disabled_reason": null, "unattended_upgrades_frequency_days": 1, "unattended_upgrades_last_run": null, "unattended_upgrades_running": true}, "meta": {"environment_vars": \[\], "raw_config": {"APT::Periodic::Enable": "1", "APT::Periodic::Unattended-Upgrade": "1", "APT::Periodic::Update-Package-Lists": "1", "Unattended-Upgrade::Allowed-Origins": \["\$\{distro_id\}:\$\{distro_codename\}", "\$\{distro_id\}:\$\{distro_codename\}\-security", "\$\{distro_id\}ESMApps:\$\{distro_codename\}\-apps-security", "\$\{distro_id\}ESM:\$\{distro_codename\}\-infra-security"\][,]?\s*<extra_field>}}, "type": "UnattendedUpgradesStatus"}, "errors": \[\], "result": "success", "version": ".*", "warnings": \[\]}
4169+ """
4170+ When I create the file `/etc/apt/apt.conf.d/99test` with the following:
4171+ """
4172+ APT::Periodic::Enable "0";
4173+ """
4174+ And I run `apt-get update` with sudo
4175+ And I run `apt-get install jq -y` with sudo
4176+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.apt_periodic_job_enabled` as non-root
4177+ Then I will see the following on stdout:
4178+ """
4179+ false
4180+ """
4181+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_running` as non-root
4182+ Then I will see the following on stdout:
4183+ """
4184+ false
4185+ """
4186+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.msg` as non-root
4187+ Then I will see the following on stdout:
4188+ """
4189+ "APT::Periodic::Enable is turned off"
4190+ """
4191+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.code` as non-root
4192+ Then I will see the following on stdout:
4193+ """
4194+ "unattended-upgrades-cfg-value-turned-off"
4195+ """
4196+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"APT::Periodic::Enable\"'` as non-root
4197+ Then I will see the following on stdout:
4198+ """
4199+ "0"
4200+ """
4201+ When I create the file `/etc/apt/apt.conf.d/99test` with the following:
4202+ """
4203+ APT::Periodic::Update-Package-Lists "0";
4204+ """
4205+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.apt_periodic_job_enabled` as non-root
4206+ Then I will see the following on stdout:
4207+ """
4208+ true
4209+ """
4210+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.package_lists_refresh_frequency_days` as non-root
4211+ Then I will see the following on stdout:
4212+ """
4213+ 0
4214+ """
4215+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_running` as non-root
4216+ Then I will see the following on stdout:
4217+ """
4218+ false
4219+ """
4220+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.msg` as non-root
4221+ Then I will see the following on stdout:
4222+ """
4223+ "APT::Periodic::Update-Package-Lists is turned off"
4224+ """
4225+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.code` as non-root
4226+ Then I will see the following on stdout:
4227+ """
4228+ "unattended-upgrades-cfg-value-turned-off"
4229+ """
4230+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"APT::Periodic::Update-Package-Lists\"'` as non-root
4231+ Then I will see the following on stdout:
4232+ """
4233+ "0"
4234+ """
4235+ When I create the file `/etc/apt/apt.conf.d/99test` with the following:
4236+ """
4237+ APT::Periodic::Unattended-Upgrade "0";
4238+ """
4239+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_frequency_days` as non-root
4240+ Then I will see the following on stdout:
4241+ """
4242+ 0
4243+ """
4244+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.package_lists_refresh_frequency_days` as non-root
4245+ Then I will see the following on stdout:
4246+ """
4247+ 1
4248+ """
4249+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_running` as non-root
4250+ Then I will see the following on stdout:
4251+ """
4252+ false
4253+ """
4254+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.msg` as non-root
4255+ Then I will see the following on stdout:
4256+ """
4257+ "APT::Periodic::Unattended-Upgrade is turned off"
4258+ """
4259+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.code` as non-root
4260+ Then I will see the following on stdout:
4261+ """
4262+ "unattended-upgrades-cfg-value-turned-off"
4263+ """
4264+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"APT::Periodic::Unattended-Upgrade\"'` as non-root
4265+ Then I will see the following on stdout:
4266+ """
4267+ "0"
4268+ """
4269+ When I run `systemctl stop apt-daily.timer` with sudo
4270+ And I run `rm /etc/apt/apt.conf.d/99test` with sudo
4271+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.systemd_apt_timer_enabled` as non-root
4272+ Then I will see the following on stdout:
4273+ """
4274+ false
4275+ """
4276+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_running` as non-root
4277+ Then I will see the following on stdout:
4278+ """
4279+ false
4280+ """
4281+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.msg` as non-root
4282+ Then I will see the following on stdout:
4283+ """
4284+ "apt-daily.timer jobs are not running"
4285+ """
4286+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.code` as non-root
4287+ Then I will see the following on stdout:
4288+ """
4289+ "unattended-upgrades-systemd-job-disabled"
4290+ """
4291+ When I create the file `/etc/apt/apt.conf.d/50unattended-upgrades` with the following:
4292+ """
4293+ APT::Periodic::Unattended-Upgrade "1";
4294+ """
4295+ And I run `systemctl start apt-daily.timer` with sudo
4296+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_frequency_days` as non-root
4297+ Then I will see the following on stdout:
4298+ """
4299+ 1
4300+ """
4301+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.systemd_apt_timer_enabled` as non-root
4302+ Then I will see the following on stdout:
4303+ """
4304+ true
4305+ """
4306+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_allowed_origins` as non-root
4307+ Then I will see the following on stdout:
4308+ """
4309+ []
4310+ """
4311+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_running` as non-root
4312+ Then I will see the following on stdout:
4313+ """
4314+ false
4315+ """
4316+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.msg` as non-root
4317+ Then I will see the following on stdout:
4318+ """
4319+ "Unattended-Upgrade::Allowed-Origins is empty"
4320+ """
4321+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_disabled_reason.code` as non-root
4322+ Then I will see the following on stdout:
4323+ """
4324+ "unattended-upgrades-cfg-list-value-empty"
4325+ """
4326+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"Unattended-Upgrade::Allowed-Origins\"'` as non-root
4327+ Then I will see the following on stdout:
4328+ """
4329+ null
4330+ """
4331+ When I run `/usr/lib/apt/apt.systemd.daily update` with sudo
4332+ And I run `/usr/lib/apt/apt.systemd.daily install` with sudo
4333+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq .data.attributes.unattended_upgrades_last_run` as non-root
4334+ Then stdout matches regexp:
4335+ """
4336+ "(?!null).*"
4337+ """
4338+ When I create the file `/etc/apt/apt.conf.d/99test` with the following:
4339+ """
4340+ Unattended-Upgrade::Mail "mail";
4341+ Unattended-Upgrade::Package-Blacklist {
4342+ "vim";
4343+ };
4344+ """
4345+ And I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"Unattended-Upgrade::Mail\"'` as non-root
4346+ Then I will see the following on stdout:
4347+ """
4348+ "mail"
4349+ """
4350+ When I run shell command `pro api u.unattended_upgrades.status.v1 | jq '.data.meta.raw_config.\"Unattended-Upgrade::Package-Blacklist\"'` as non-root
4351+ Then I will see the following on stdout:
4352+ """
4353+ [
4354+ "vim"
4355+ ]
4356+ """
4357+
4358+ Examples: ubuntu release
4359+ | release | extra_field |
4360+ | xenial | |
4361+ | bionic | "Unattended-Upgrade::DevRelease": "false" |
4362+ | focal | "Unattended-Upgrade::DevRelease": "auto" |
4363+ | jammy | "Unattended-Upgrade::DevRelease": "auto" |
4364+ | kinetic | "Unattended-Upgrade::DevRelease": "auto" |
4365+ | lunar | "Unattended-Upgrade::DevRelease": "auto" |
4366diff --git a/features/apt_messages.feature b/features/apt_messages.feature
4367index acbbe92..401360d 100644
4368--- a/features/apt_messages.feature
4369+++ b/features/apt_messages.feature
4370@@ -216,12 +216,14 @@ Feature: APT Messages
4371 | focal | hello |
4372 | jammy | hello |
4373
4374- @series.lts
4375+ @series.all
4376 @uses.config.machine_type.lxd.container
4377 Scenario Outline: APT News
4378 Given a `<release>` machine with ubuntu-advantage-tools installed
4379 When I attach `contract_token` with sudo
4380- When I run `apt-get -o APT::Get::Always-Include-Phased-Updates=true upgrade -y` with sudo
4381+ # On interim releases we will not enable any service, so we need a manual apt-get update
4382+ When I run `apt-get update` with sudo
4383+ When I run `DEBIAN_FRONTEND=noninteractive apt-get -o APT::Get::Always-Include-Phased-Updates=true upgrade -y` with sudo
4384 When I run `apt-get autoremove -y` with sudo
4385 When I run `pro detach --assume-yes` with sudo
4386
4387@@ -246,12 +248,7 @@ Feature: APT Messages
4388 ]
4389 }
4390 """
4391- # test is too fast and systemd doesn't like triggering motd-news.service
4392- # (during pro refresh messages) too frequently
4393- # So there are "wait"s before each pro refresh messages call
4394- When I wait `1` seconds
4395 When I run `pro refresh messages` with sudo
4396- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4397 When I run `apt upgrade` with sudo
4398 Then I will see the following on stdout
4399 """
4400@@ -293,7 +290,6 @@ Feature: APT Messages
4401
4402 # apt update stamp will prevent a apt_news refresh
4403 When I run `apt-get update` with sudo
4404- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4405 When I run `apt upgrade` with sudo
4406 Then I will see the following on stdout
4407 """
4408@@ -306,11 +302,9 @@ Feature: APT Messages
4409 #
4410 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4411 """
4412-
4413+
4414 # manual refresh gets new message
4415- When I wait `1` seconds
4416 When I run `pro refresh messages` with sudo
4417- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4418 When I run `apt upgrade` with sudo
4419 Then I will see the following on stdout
4420 """
4421@@ -325,13 +319,12 @@ Feature: APT Messages
4422 #
4423 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4424 """
4425-
4426+
4427 # creates /run/ubuntu-advantage and /var/lib/ubuntu-advantage/messages if not there
4428 When I run `rm -rf /run/ubuntu-advantage` with sudo
4429 When I run `rm -rf /var/lib/ubuntu-advantage/messages` with sudo
4430 When I run `rm /var/lib/apt/periodic/update-success-stamp` with sudo
4431 When I run `apt-get update` with sudo
4432- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4433 When I run `apt upgrade` with sudo
4434 Then I will see the following on stdout
4435 """
4436@@ -346,7 +339,7 @@ Feature: APT Messages
4437 #
4438 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4439 """
4440-
4441+
4442 # more than 3 lines ignored
4443 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4444 """
4445@@ -364,9 +357,7 @@ Feature: APT Messages
4446 ]
4447 }
4448 """
4449- When I wait `1` seconds
4450 When I run `pro refresh messages` with sudo
4451- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4452 When I run `apt upgrade` with sudo
4453 Then I will see the following on stdout
4454 """
4455@@ -376,7 +367,7 @@ Feature: APT Messages
4456 Calculating upgrade...
4457 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4458 """
4459-
4460+
4461 # more than 77 chars ignored
4462 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4463 """
4464@@ -391,9 +382,7 @@ Feature: APT Messages
4465 ]
4466 }
4467 """
4468- When I wait `1` seconds
4469 When I run `pro refresh messages` with sudo
4470- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4471 When I run `apt upgrade` with sudo
4472 Then I will see the following on stdout
4473 """
4474@@ -403,7 +392,7 @@ Feature: APT Messages
4475 Calculating upgrade...
4476 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4477 """
4478-
4479+
4480 # end is respected
4481 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4482 """
4483@@ -419,9 +408,7 @@ Feature: APT Messages
4484 ]
4485 }
4486 """
4487- When I wait `1` seconds
4488 When I run `pro refresh messages` with sudo
4489- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4490 When I run `apt upgrade` with sudo
4491 Then I will see the following on stdout
4492 """
4493@@ -445,9 +432,7 @@ Feature: APT Messages
4494 ]
4495 }
4496 """
4497- When I wait `1` seconds
4498 When I run `pro refresh messages` with sudo
4499- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4500 When I run `apt upgrade` with sudo
4501 Then I will see the following on stdout
4502 """
4503@@ -460,7 +445,7 @@ Feature: APT Messages
4504 #
4505 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4506 """
4507-
4508+
4509 # begin >30 days ago ignored, even if end is set to future
4510 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4511 """
4512@@ -476,9 +461,7 @@ Feature: APT Messages
4513 ]
4514 }
4515 """
4516- When I wait `1` seconds
4517 When I run `pro refresh messages` with sudo
4518- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4519 When I run `apt upgrade` with sudo
4520 Then I will see the following on stdout
4521 """
4522@@ -488,7 +471,7 @@ Feature: APT Messages
4523 Calculating upgrade...
4524 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4525 """
4526-
4527+
4528 # begin in future
4529 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4530 """
4531@@ -503,9 +486,7 @@ Feature: APT Messages
4532 ]
4533 }
4534 """
4535- When I wait `1` seconds
4536 When I run `pro refresh messages` with sudo
4537- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4538 When I run `apt upgrade` with sudo
4539 Then I will see the following on stdout
4540 """
4541@@ -515,7 +496,7 @@ Feature: APT Messages
4542 Calculating upgrade...
4543 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4544 """
4545-
4546+
4547 # local apt news overrides for contract expiry notices
4548 When I create the file `/var/www/html/aptnews.json` on the `apt-news-server` machine with the following:
4549 """
4550@@ -532,25 +513,15 @@ Feature: APT Messages
4551 """
4552 When I attach `contract_token` with sudo
4553 When I run `apt upgrade -y` with sudo
4554- When I create the file `/tmp/machine-token-overlay.json` with the following:
4555- """
4556- {
4557- "machineTokenInfo": {
4558- "contractInfo": {
4559- "effectiveTo": "$behave_var{today +2}"
4560- }
4561- }
4562- }
4563- """
4564- And I append the following on uaclient config:
4565+ When I set the machine token overlay to the following yaml
4566 """
4567- features:
4568- machine_token_overlay: "/tmp/machine-token-overlay.json"
4569+ machineTokenInfo:
4570+ contractInfo:
4571+ effectiveTo: $behave_var{today +2}
4572 """
4573 # test that apt update will trigger hook to update apt_news for local override
4574 When I run shell command `rm -f /var/lib/apt/periodic/update-success-stamp` with sudo
4575 When I run `apt-get update` with sudo
4576- When I run shell command `rm -f /var/lib/ubuntu-advantage/messages/apt-pre*` with sudo
4577 When I run `apt upgrade` with sudo
4578 Then I will see the following on stdout
4579 """
4580@@ -565,17 +536,12 @@ Feature: APT Messages
4581 #
4582 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4583 """
4584- When I create the file `/tmp/machine-token-overlay.json` with the following:
4585+ When I set the machine token overlay to the following yaml
4586 """
4587- {
4588- "machineTokenInfo": {
4589- "contractInfo": {
4590- "effectiveTo": "$behave_var{today -3}"
4591- }
4592- }
4593- }
4594+ machineTokenInfo:
4595+ contractInfo:
4596+ effectiveTo: $behave_var{today -3}
4597 """
4598- When I wait `1` seconds
4599 When I run `pro refresh messages` with sudo
4600 When I run `apt upgrade` with sudo
4601 Then stdout matches regexp:
4602@@ -592,17 +558,12 @@ Feature: APT Messages
4603 #
4604 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4605 """
4606- When I create the file `/tmp/machine-token-overlay.json` with the following:
4607+ When I set the machine token overlay to the following yaml
4608 """
4609- {
4610- "machineTokenInfo": {
4611- "contractInfo": {
4612- "effectiveTo": "$behave_var{today -20}"
4613- }
4614- }
4615- }
4616+ machineTokenInfo:
4617+ contractInfo:
4618+ effectiveTo: $behave_var{today -20}
4619 """
4620- When I wait `1` seconds
4621 When I run `pro refresh messages` with sudo
4622 When I run `apt upgrade` with sudo
4623 Then I will see the following on stdout
4624@@ -648,6 +609,7 @@ Feature: APT Messages
4625 | bionic |
4626 | focal |
4627 | jammy |
4628+ | kinetic |
4629
4630 @series.xenial
4631 @series.bionic
4632@@ -655,7 +617,8 @@ Feature: APT Messages
4633 Scenario Outline: AWS URLs
4634 Given a `<release>` machine with ubuntu-advantage-tools installed
4635 When I run `apt-get update` with sudo
4636- When I run `pro refresh messages` with sudo
4637+ When I run `apt-get install ansible -y` with sudo
4638+ When I run `apt-get update` with sudo
4639 When I run `apt upgrade --dry-run` with sudo
4640 Then stdout matches regexp:
4641 """
4642@@ -672,7 +635,8 @@ Feature: APT Messages
4643 Scenario Outline: Azure URLs
4644 Given a `<release>` machine with ubuntu-advantage-tools installed
4645 When I run `apt-get update` with sudo
4646- When I run `pro refresh messages` with sudo
4647+ When I run `apt-get install ansible -y` with sudo
4648+ When I run `apt-get update` with sudo
4649 When I run `apt upgrade --dry-run` with sudo
4650 Then stdout matches regexp:
4651 """
4652@@ -689,7 +653,8 @@ Feature: APT Messages
4653 Scenario Outline: GCP URLs
4654 Given a `<release>` machine with ubuntu-advantage-tools installed
4655 When I run `apt-get update` with sudo
4656- When I run `pro refresh messages` with sudo
4657+ When I run `apt-get install ansible -y` with sudo
4658+ When I run `apt-get update` with sudo
4659 When I run `apt upgrade --dry-run` with sudo
4660 Then stdout matches regexp:
4661 """
4662@@ -699,3 +664,53 @@ Feature: APT Messages
4663 | release | msg |
4664 | xenial | Learn more about Ubuntu Pro for 16\.04 at https:\/\/ubuntu\.com\/16-04 |
4665 | bionic | Learn more about Ubuntu Pro on GCP at https:\/\/ubuntu\.com\/gcp\/pro |
4666+
4667+ @series.kinetic
4668+ @uses.config.machine_type.lxd.container
4669+ Scenario Outline: APT Hook do not advertises esm-apps on upgrade for interim releases
4670+ Given a `<release>` machine with ubuntu-advantage-tools installed
4671+ When I run `apt-get update` with sudo
4672+ When I run `apt-get -o APT::Get::Always-Include-Phased-Updates=true upgrade -y` with sudo
4673+ When I run `apt-get -y autoremove` with sudo
4674+ When I run `apt-get install hello -y` with sudo
4675+ When I run `pro config set apt_news=false` with sudo
4676+ When I run `pro refresh messages` with sudo
4677+ When I run `apt upgrade` with sudo
4678+ Then stdout does not match regexp:
4679+ """
4680+ Get more security updates through Ubuntu Pro with 'esm-apps' enabled:
4681+ """
4682+ When I run `apt-get upgrade` with sudo
4683+ Then I will see the following on stdout:
4684+ """
4685+ Reading package lists...
4686+ Building dependency tree...
4687+ Reading state information...
4688+ Calculating upgrade...
4689+ 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
4690+ """
4691+ When I attach `contract_token` with sudo
4692+ When I run `apt upgrade --dry-run` with sudo
4693+ Then stdout matches regexp:
4694+ """
4695+ Reading package lists...
4696+ Building dependency tree...
4697+ Reading state information...
4698+ Calculating upgrade...
4699+ 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded\.
4700+ """
4701+ When I run `apt-get upgrade -y` with sudo
4702+ When I run `pro detach --assume-yes` with sudo
4703+ When I run `pro refresh messages` with sudo
4704+ When I run `apt upgrade` with sudo
4705+ Then stdout matches regexp:
4706+ """
4707+ Reading package lists...
4708+ Building dependency tree...
4709+ Reading state information...
4710+ Calculating upgrade...
4711+ 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded\.
4712+ """
4713+ Examples: ubuntu release
4714+ | release |
4715+ | kinetic |
4716diff --git a/features/attach_validtoken.feature b/features/attach_validtoken.feature
4717index a85b968..da04c06 100644
4718--- a/features/attach_validtoken.feature
4719+++ b/features/attach_validtoken.feature
4720@@ -198,25 +198,13 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
4721 @uses.config.machine_type.aws.generic
4722 Scenario Outline: Attach command in an generic AWS Ubuntu VM
4723 Given a `<release>` machine with ubuntu-advantage-tools installed
4724- When I create the file `/tmp/machine-token-overlay.json` with the following:
4725- """
4726- {
4727- "machineTokenInfo": {
4728- "contractInfo": {
4729- "resourceEntitlements": [
4730- {
4731- "type": "esm-apps",
4732- "entitled": false
4733- }
4734- ]
4735- }
4736- }
4737- }
4738- """
4739- And I append the following on uaclient config:
4740- """
4741- features:
4742- machine_token_overlay: "/tmp/machine-token-overlay.json"
4743+ When I set the machine token overlay to the following yaml
4744+ """
4745+ machineTokenInfo:
4746+ contractInfo:
4747+ resourceEntitlements:
4748+ - type: esm-apps
4749+ entitled: false
4750 """
4751 And I attach `contract_token` with sudo
4752 Then stdout matches regexp:
4753@@ -247,25 +235,13 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
4754 @uses.config.machine_type.azure.generic
4755 Scenario Outline: Attach command in an generic Azure Ubuntu VM
4756 Given a `<release>` machine with ubuntu-advantage-tools installed
4757- When I create the file `/tmp/machine-token-overlay.json` with the following:
4758- """
4759- {
4760- "machineTokenInfo": {
4761- "contractInfo": {
4762- "resourceEntitlements": [
4763- {
4764- "type": "esm-apps",
4765- "entitled": false
4766- }
4767- ]
4768- }
4769- }
4770- }
4771- """
4772- And I append the following on uaclient config:
4773- """
4774- features:
4775- machine_token_overlay: "/tmp/machine-token-overlay.json"
4776+ When I set the machine token overlay to the following yaml
4777+ """
4778+ machineTokenInfo:
4779+ contractInfo:
4780+ resourceEntitlements:
4781+ - type: esm-apps
4782+ entitled: false
4783 """
4784 And I attach `contract_token` with sudo
4785 Then stdout matches regexp:
4786@@ -296,25 +272,13 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
4787 @uses.config.machine_type.gcp.generic
4788 Scenario Outline: Attach command in an generic GCP Ubuntu VM
4789 Given a `<release>` machine with ubuntu-advantage-tools installed
4790- When I create the file `/tmp/machine-token-overlay.json` with the following:
4791- """
4792- {
4793- "machineTokenInfo": {
4794- "contractInfo": {
4795- "resourceEntitlements": [
4796- {
4797- "type": "esm-apps",
4798- "entitled": false
4799- }
4800- ]
4801- }
4802- }
4803- }
4804- """
4805- And I append the following on uaclient config:
4806- """
4807- features:
4808- machine_token_overlay: "/tmp/machine-token-overlay.json"
4809+ When I set the machine token overlay to the following yaml
4810+ """
4811+ machineTokenInfo:
4812+ contractInfo:
4813+ resourceEntitlements:
4814+ - type: esm-apps
4815+ entitled: false
4816 """
4817 And I attach `contract_token` with sudo
4818 Then stdout matches regexp:
4819@@ -386,22 +350,15 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
4820 """
4821 esm-infra +yes +enabled +Expanded Security Maintenance for Infrastructure
4822 """
4823- When I create the file `/tmp/machine-token-overlay.json` with the following:
4824+ When I set the machine token overlay to the following yaml
4825 """
4826- {
4827- "machineTokenInfo": {
4828- "contractInfo": {
4829- "effectiveTo": "2000-01-02T03:04:05Z"
4830- }
4831- }
4832- }
4833+ machineTokenInfo:
4834+ contractInfo:
4835+ effectiveTo: 2000-01-02T03:04:05Z
4836 """
4837- And I append the following on uaclient config:
4838- """
4839- features:
4840- machine_token_overlay: "/tmp/machine-token-overlay.json"
4841- """
4842- When I run `pro status` with sudo
4843+ And I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
4844+ And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4845+ And I run `pro status` with sudo
4846 Then stdout matches regexp:
4847 """
4848 A change has been detected in your contract.
4849@@ -412,7 +369,8 @@ Feature: Command behaviour when attaching a machine to an Ubuntu Pro
4850 """
4851 Successfully refreshed your subscription.
4852 """
4853- When I run `sed -i '/^.*machine_token_overlay:/d' /etc/ubuntu-advantage/uaclient.conf` with sudo
4854+ # remove machine token overlay
4855+ When I change config key `features` to use value `{}`
4856 And I run `pro status` with sudo
4857 Then stdout does not match regexp:
4858 """
4859diff --git a/features/attached_commands.feature b/features/attached_commands.feature
4860index 0b3e95e..524e4e0 100644
4861--- a/features/attached_commands.feature
4862+++ b/features/attached_commands.feature
4863@@ -249,7 +249,7 @@ Feature: Command behaviour when attached to an Ubuntu Pro subscription
4864 esm-infra +yes +Expanded Security Maintenance for Infrastructure
4865 fips +<fips> +NIST-certified core packages
4866 fips-updates +<fips> +NIST-certified core packages with priority security updates
4867- livepatch +(yes|no) +Canonical Livepatch service
4868+ livepatch +(yes|no) +(Canonical Livepatch service|Current kernel is not supported)
4869 realtime-kernel +<realtime-kernel> +Ubuntu kernel with PREEMPT_RT patches integrated
4870 ros +<ros> +Security Updates for the Robot Operating System
4871 ros-updates +<ros> +All Updates for the Robot Operating System
4872@@ -766,7 +766,7 @@ Feature: Command behaviour when attached to an Ubuntu Pro subscription
4873 When I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4874 And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
4875 Then stdout matches regexp:
4876- """"
4877+ """
4878 "update_messaging":
4879 """
4880 When I run `pro config show` with sudo
4881@@ -779,50 +779,27 @@ Feature: Command behaviour when attached to an Ubuntu Pro subscription
4882 And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4883 And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
4884 Then stdout matches regexp:
4885- """"
4886+ """
4887 "update_messaging": null
4888 """
4889 When I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
4890- And I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
4891- """
4892- contract_url: https://contracts.canonical.com
4893- data_dir: /var/lib/ubuntu-advantage
4894- log_file: /var/log/ubuntu-advantage.log
4895- log_level: debug
4896- security_url: https://ubuntu.com/security
4897- ua_config:
4898- apt_http_proxy: null
4899- apt_https_proxy: null
4900- http_proxy: null
4901- https_proxy: null
4902- update_messaging_timer: 14400
4903- metering_timer: 0
4904+ And I create the file `/var/lib/ubuntu-advantage/user-config.json` with the following:
4905+ """
4906+ { "metering_timer": 0 }
4907 """
4908 And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4909 And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
4910 Then stdout matches regexp:
4911- """"
4912+ """
4913 "metering": null
4914 """
4915 When I delete the file `/var/lib/ubuntu-advantage/jobs-status.json`
4916- And I create the file `/etc/ubuntu-advantage/uaclient.conf` with the following:
4917- """
4918- contract_url: https://contracts.canonical.com
4919- data_dir: /var/lib/ubuntu-advantage
4920- log_file: /var/log/ubuntu-advantage.log
4921- log_level: debug
4922- security_url: https://ubuntu.com/security
4923- ua_config:
4924- apt_http_proxy: null
4925- apt_https_proxy: null
4926- http_proxy: null
4927- https_proxy: null
4928- update_messaging_timer: -10
4929- metering_timer: notanumber
4930+ And I create the file `/var/lib/ubuntu-advantage/user-config.json` with the following:
4931+ """
4932+ { "metering_timer": "notanumber", "update_messaging_timer": -10 }
4933 """
4934 And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4935 Then I verify that running `grep "Invalid value for update_messaging interval found in config." /var/log/ubuntu-advantage-timer.log` `with sudo` exits `0`
4936- And I verify that running `grep "Invalid value for metering interval found in config." /var/log/ubuntu-advantage-timer.log` `with sudo` exits `0`
4937 And I verify that the timer interval for `update_messaging` is `21600`
4938 And I verify that the timer interval for `metering` is `14400`
4939 When I create the file `/var/lib/ubuntu-advantage/jobs-status.json` with the following:
4940@@ -832,15 +809,15 @@ Feature: Command behaviour when attached to an Ubuntu Pro subscription
4941 And I run `python3 /usr/lib/ubuntu-advantage/timer.py` with sudo
4942 And I run `cat /var/lib/ubuntu-advantage/jobs-status.json` with sudo
4943 Then stdout does not match regexp:
4944- """"
4945+ """
4946 "update_status"
4947 """
4948 And stdout matches regexp:
4949- """"
4950+ """
4951 "metering"
4952 """
4953 And stdout matches regexp:
4954- """"
4955+ """
4956 "update_messaging"
4957 """
4958
4959diff --git a/features/attached_enable.feature b/features/attached_enable.feature
4960index 7dc71a2..e833c54 100644
4961--- a/features/attached_enable.feature
4962+++ b/features/attached_enable.feature
4963@@ -79,27 +79,14 @@ Feature: Enable command behaviour when attached to an Ubuntu Pro subscription
4964 Scenario Outline: Empty series affordance means no series, null means all series
4965 Given a `<release>` machine with ubuntu-advantage-tools installed
4966 When I attach `contract_token` with sudo and options `--no-auto-enable`
4967- When I create the file `/tmp/machine-token-overlay.json` with the following:
4968- """
4969- {
4970- "machineTokenInfo": {
4971- "contractInfo": {
4972- "resourceEntitlements": [
4973- {
4974- "type": "esm-infra",
4975- "affordances": {
4976- "series": []
4977- }
4978- }
4979- ]
4980- }
4981- }
4982- }
4983+ When I set the machine token overlay to the following yaml
4984 """
4985- And I append the following on uaclient config:
4986- """
4987- features:
4988- machine_token_overlay: "/tmp/machine-token-overlay.json"
4989+ machineTokenInfo:
4990+ contractInfo:
4991+ resourceEntitlements:
4992+ - type: esm-infra
4993+ affordances:
4994+ series: []
4995 """
4996 When I verify that running `pro enable esm-infra` `with sudo` exits `1`
4997 Then stdout matches regexp:
4998@@ -344,25 +331,13 @@ Feature: Enable command behaviour when attached to an Ubuntu Pro subscription
4999 @uses.config.machine_type.lxd.container
5000 Scenario Outline: Attached enable not entitled service in a ubuntu machine
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: