Skip to content

Commit

Permalink
fix: get ubuntu pro info on snaps (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
st3v3nmw authored Aug 7, 2024
1 parent 04fed8d commit b2ce9c8
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 10 deletions.
6 changes: 6 additions & 0 deletions landscape/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@
DEFAULT_CONFIG = (
"/etc/landscape-client.conf" if IS_SNAP else "/etc/landscape/client.conf"
)

UA_DATA_DIR = (
"/var/lib/snapd/hostfs/var/lib/ubuntu-advantage"
if IS_SNAP
else "/var/lib/ubuntu-advantage"
)
43 changes: 36 additions & 7 deletions landscape/client/manager/tests/test_ubuntuproinfo.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import json
import os
import tempfile
from datetime import datetime
from unittest import mock

Expand Down Expand Up @@ -161,14 +164,40 @@ def test_persistence_reset(self):
self.assertTrue("ubuntu-pro-info" in messages[1])
self.assertEqual(messages[1]["ubuntu-pro-info"], data)

@mock.patch("landscape.client.manager.ubuntuproinfo.IS_SNAP", new=True)
def test_pro_client_not_called_for_snap(self):
"""
The snap will not currently allow calls to the pro client.
@mock.patch.multiple(
"landscape.client.manager.ubuntuproinfo",
IS_SNAP=True,
UA_DATA_DIR=tempfile.gettempdir(),
)
def test_pro_status_file_read_for_snap(self):
"""The snap should read the status file instead of calling `pro`."""
temp_file_path = os.path.join(tempfile.gettempdir(), "status.json")
with open(temp_file_path, "w") as fp:
mocked_info = {
"_schema_version": "0.1",
"account": {
"created_at": "2024-01-08T13:26:52+00:00",
"external_account_ids": [],
"id": "zYxWvU_sRqPoNmLkJiHgFeDcBa9876543210ZyXwVuTsRqPon",
"name": "[email protected]",
},
"foo": "bar"
}
json.dump(mocked_info, fp)

Ensure that get_ubuntu_pro_info returns an empty dictionary instead of
calling the subprocess for pro.
"""
ubuntu_pro_info = get_ubuntu_pro_info()
del mocked_info["foo"]
self.assertEqual(mocked_info, ubuntu_pro_info)

os.remove(temp_file_path)

@mock.patch.multiple(
"landscape.client.manager.ubuntuproinfo",
IS_SNAP=True,
UA_DATA_DIR="/i/do/not/exist",
)
def test_pro_status_file_not_found_for_snap(self):
"""The snap will return {} if the status file is not found."""
ubuntu_pro_info = get_ubuntu_pro_info()
self.assertEqual({}, ubuntu_pro_info)

Expand Down
45 changes: 42 additions & 3 deletions landscape/client/manager/ubuntuproinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from landscape.client import IS_CORE
from landscape.client import IS_SNAP
from landscape.client import UA_DATA_DIR
from landscape.client.manager.plugin import ManagerPlugin
from landscape.lib.persist import Persist

Expand Down Expand Up @@ -80,9 +81,47 @@ def get_ubuntu_pro_info() -> dict:
)

if IS_SNAP:
# Snap does not support Ubuntu Pro Info and throws an error if `pro` is
# called.
return {}
# By default, Ubuntu Advantage / Pro stores the status information
# in /var/lib/ubuntu-advantage/status.json (we have a `system-files`
# plug for this).
# This `data_dir` can however be changed in
# /etc/ubuntu-advantage/uaclient.conf which would lead to
# permission errors since we don't have a plug for arbitrary
# folders on the host fs.

try:
with open(f"{UA_DATA_DIR}/status.json") as fp:
pro_info = json.load(fp)
except (FileNotFoundError, PermissionError):
# Happens if the Ubuntu Pro client isn't installed, or
# if the `data_dir` folder setting was changed from the default
return {}

# The status file has more information than `pro status`
keys_to_keep = [
"_doc",
"_schema_version",
"account",
"attached",
"config",
"config_path",
"contract",
"effective",
"environment_vars",
"errors",
"execution_details",
"execution_status",
"expires",
"features",
"machine_id",
"notices",
"result",
"services",
"simulated",
"version",
"warnings",
]
return {k: pro_info[k] for k in keys_to_keep if k in pro_info}

try:
completed_process = subprocess.run(
Expand Down
7 changes: 7 additions & 0 deletions snap/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ environment:
LANDSCAPE_CLIENT_SNAP: 1
PYTHONPATH: $SNAP/usr/lib/python3/dist-packages:$SNAP/usr/lib/python3.10/site-packages:$PYTHONPATH

plugs:
var-lib-ubuntu-advantage-status:
interface: system-files
read:
- /var/lib/snapd/hostfs/var/lib/ubuntu-advantage/status.json

apps:
landscape-client:
daemon: simple
Expand All @@ -42,6 +48,7 @@ apps:
- process-control
- network-control
- network-manager
- var-lib-ubuntu-advantage-status
config:
command: usr/bin/landscape-config
plugs: [network]
Expand Down

0 comments on commit b2ce9c8

Please sign in to comment.