Skip to content

Commit

Permalink
Change: autoinstall is enable is any of the supported key is provided
Browse files Browse the repository at this point in the history
  • Loading branch information
p-gentili committed Aug 9, 2024
1 parent 75dc625 commit 581686f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import base64
import binascii
import contextlib
import logging
import os
import subprocess
Expand All @@ -39,7 +40,7 @@ class DeviceConnector(ZapperConnector):

PROVISION_METHOD = "ProvisioningKVM"

def _validate_user_data(self, encoded_user_data: str):
def _validate_base_user_data(self, encoded_user_data: str):
"""
Assert `base_user_data` argument is a valid base64 encoded YAML.
"""
Expand All @@ -56,20 +57,28 @@ def _validate_user_data(self, encoded_user_data: str):
) from exc

def _get_autoinstall_conf(self) -> Optional[Dict[str, Any]]:
"""Prepare autoinstall-related configuration."""
provision = self.job_data["provision_data"]
"""
Autoinstall-related keys are pre-fixed with `autoinstall_`.
if "storage_layout" not in provision:
return None
If any of those arguments are provided and valid, the function
returns an autoinstall_conf dictionary, including the agent
SSH public key.
"""

autoinstall_conf = {
"storage_layout": provision["storage_layout"],
"oem": provision.get("autoinstall_oem", False),
}
autoinstall_conf = {}
for key, value in self.job_data["provision_data"].items():
if "autoinstall_" not in key:
continue

if "base_user_data" in provision:
self._validate_user_data(provision["base_user_data"])
autoinstall_conf["base_user_data"] = provision["base_user_data"]
key = key.replace("autoinstall_", "")
with contextlib.suppress(AttributeError):
getattr(self, f"_validate_{key}")(value)

autoinstall_conf[key] = value

if not autoinstall_conf:
logger.info("Autoinstall-related keys were not provided.")
return None

with open(os.path.expanduser("~/.ssh/id_rsa.pub")) as pub:
autoinstall_conf["authorized_keys"] = [pub.read()]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def test_validate_configuration_w_opt(self):
"job.robot",
"another.robot",
],
"storage_layout": "lvm",
"autoinstall_storage_layout": "lvm",
"robot_retries": 3,
"cmdline_append": "more arguments",
"skip_download": True,
Expand Down Expand Up @@ -145,7 +145,7 @@ def test_validate_configuration_alloem(self):
"job.robot",
"another.robot",
],
"storage_layout": "lvm",
"autoinstall_storage_layout": "lvm",
},
"test_data": {
"test_username": "username",
Expand All @@ -172,7 +172,8 @@ def test_validate_configuration_alloem(self):
def test_get_autoinstall_none(self):
"""
Test whether the get_autoinstall_conf function returns
None in case the storage_layout is not specified.
None in case none of the autoinstall-related keys are
provided.
"""

connector = DeviceConnector()
Expand Down Expand Up @@ -212,7 +213,7 @@ def test_get_autoinstall_conf(self):
"job.robot",
"another.robot",
],
"storage_layout": "lvm",
"autoinstall_storage_layout": "lvm",
},
"test_data": {
"test_username": "username",
Expand All @@ -226,7 +227,6 @@ def test_get_autoinstall_conf(self):
expected = {
"storage_layout": "lvm",
"authorized_keys": ["mykey"],
"oem": False,
}
self.assertDictEqual(conf, expected)

Expand All @@ -246,8 +246,8 @@ def test_get_autoinstall_conf_full(self):
"job.robot",
"another.robot",
],
"storage_layout": "lvm",
"base_user_data": "content",
"autoinstall_storage_layout": "lvm",
"autoinstall_base_user_data": "content",
"autoinstall_oem": True,
},
"test_data": {
Expand All @@ -256,11 +256,11 @@ def test_get_autoinstall_conf_full(self):
},
}

connector._validate_user_data = Mock()
connector._validate_base_user_data = Mock()
with patch("builtins.open", mock_open(read_data="mykey")):
conf = connector._get_autoinstall_conf()

connector._validate_user_data.assert_called_once_with("content")
connector._validate_base_user_data.assert_called_once_with("content")
expected = {
"storage_layout": "lvm",
"base_user_data": "content",
Expand All @@ -269,26 +269,26 @@ def test_get_autoinstall_conf_full(self):
}
self.assertDictEqual(conf, expected)

def test_validate_user_data(self):
def test_validate_base_user_data(self):
"""
Test whether the function returns without errors in case of a
sane base64 encoded YAML.
"""
connector = DeviceConnector()
user_data_base = yaml.safe_dump({"key1": 1, "key2": [1, 2, 3]})
encoded = base64.b64encode(user_data_base.encode()).decode()
connector._validate_user_data(encoded)
connector._validate_base_user_data(encoded)

def test_validate_user_data_raises_decode(self):
def test_validate_base_user_data_raises_decode(self):
"""
Test whether the function raises an exception if the input
is not correctly encoded.
"""
connector = DeviceConnector()
with self.assertRaises(ProvisioningError):
connector._validate_user_data("notbase64")
connector._validate_base_user_data("notbase64")

def test_validate_user_data_raises_load(self):
def test_validate_base_user_data_raises_load(self):
"""
Test whether the function raises an exception if the input
is not a valid YAML.
Expand All @@ -297,7 +297,7 @@ def test_validate_user_data_raises_load(self):
user_data_base = "not: a: correctly: formatted: yaml"
encoded = base64.b64encode(user_data_base.encode()).decode()
with self.assertRaises(ProvisioningError):
connector._validate_user_data(encoded)
connector._validate_base_user_data(encoded)

def test_run_oem_no_url(self):
"""
Expand Down
10 changes: 5 additions & 5 deletions docs/reference/device-connector-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -282,19 +282,19 @@ The ``zapper_kvm`` device connector, depending on the target image, supports the
- List of Zapper/Robot snippets to run in sequence after the USB storage device
is plugged into the DUT and the system restarted. The snippet ID is the relative
path from the ``robot/snippets`` path in the Zapper repository.
* - ``storage_layout``
* - ``autoinstall_storage_layout``
- When provisioning an image supporting *autoinstall*, the storage_layout can
be either ``lvm`` (default), ``direct``, ``zfs`` or ``hybrid`` (Desktop 23.10+, UC24)
* - ``cmdline_append``
- (Optional) When provisioning an image supporting *autoinstall*, the cmdline_append can
be used to append Kernel parameters to the standard GRUB entry.
* - ``base_user_data``
* - ``autoinstall_base_user_data``
- (Optional) A string containing base64 encoded user-data to use as base for autoinstall-driven provisioning.
For more information, see
`Autoinstall Reference <https://canonical-subiquity.readthedocs-hosted.com/en/latest/reference/autoinstall-reference.html>`_.
on this topic
* - ``autoinstall_oem``:
- (Optional) Set to "true" to install OEM meta-packages and the reset partition (Desktop 24.04+).
* - ``cmdline_append``
- (Optional) When provisioning an image supporting *autoinstall*, the cmdline_append can
be used to append Kernel parameters to the standard GRUB entry.
* - ``ubuntu_sso_email``:
- (Optional) A valid Ubuntu SSO email to which the DUT provisioned with a non-dangerous grade UC image will be linked (UC24). Please make sure to provide the corresponding *username* in the *test_data.test_username* field.
.
Expand Down

0 comments on commit 581686f

Please sign in to comment.