The drivers controller used to mark the model configured automatically
if no drivers were found. This is okay in most cases but sometimes, we
want to query again the list of drivers (after the client_variant gets
set for instance) and we don't want the model to remain configured.
Let's leave this up to the client to decide if the model should be
configured.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The data passed to on-volumes needs to indicate, for each "structure"
(partition) defined by the gadget the path to the underlying device. The
current code attempts to this by tracking the partition for each role
but this doesn't work: there maybe be more than one partition with no
role. So refactor to have the controller convert the "volume" structure
to an "on-volume" structure early and update the device fields after
curtin runs.
I'm like 99% sure that all call paths to here align the size properly,
apart from the one in apply_system, which I want to be able to create
improperly sized partitions.
If and when the desktop installer adds a snaps screen, we should
probably fetch information for a different set of snaps for a desktop
install. But for now this is OK.
Upon reaching the Ubuntu Pro screen that shows the user-code, we need to
initiate a contract selection. If we are navigating to the screen a
second time though, we need to cancel existing contract selections
before initiating a new one.
Failing to do so results in a UPCSAlreadyInitiatedError.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
In dry-run mode, instead of reading the uacontracts environment URL from
/etc/ubuntu-advantage/uaclient.conf, we can now override this variable
by specifying the 'pro_ua_contracts_url' dry-run parameter.
In conjunction with 'pro_magic_attach_run_locally', this allows us to
test Subiquity against testing environments. By default it will use the
staging environment (i.e., https://contracts.staging.canonical.com).
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
In dry-run mode, the 'magic_attach_run_locally' variable can now be used
to execute uaclient on the host (against the uacontracts environment
specified in /etc/ubuntu-advantage/uaclient.conf) instead of relying on
a mock mechanism.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The "$source"/var/lib/snapd/seed/systems directory only exists in certain
scenarios related to TPM-backed FDE. When the directory does not exist,
attempting to bind-mount it to /var/lib/snapd/seed/systems crashes the
install with a CalledProcessError.
We now make sure the directory exists before trying to mount it. For
dry-run test cases, we added a configuration item that simulates the
presence (or the non-presence) of the systems directory on the source.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Oftentimes, we want to simulate a specific behavior of the application
when running in dry-run mode. To do so, we use either command line
parameters or environment variables.
This patch introduces a configuration object for dry-run executions
only. The object can be automatically loaded from a JSON file specified
via the --dry-run-config CLI argument.
Such a configuration object should help us cover way more test cases.
Going forward, I would like to use this object for things like:
* drivers - to instruct Subiquity what third-party drivers it should
suggest ; or if Subiquity should run ubuntu-drivers on the host
instead.
* ubuntu-pro - to specify the ua-contracts test environment URL - or
predefined automatic replies for the server
* to assume that /var/lib/snapd/seed/systems directory exists on the
source (or not).
* to specify the Ubuntu release that is returned by lsb_release ; can
be used to test behavior on LTS vs non LTS releases.
*
* ...
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The test_api.py is not meant to be used as en entry point. There is no
shebang so executing the script from a sh-compatible shell can be pretty
messy.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
ssh-keygen -l supports an input file that has multiple keys. As a
result, it will output multiple key fingerprints.
That being said, ssh-keygen will ignore empty newlines from the input
(and maybe other things?).
It makes it slightly challenging to associate each key with its
fingerprint because the number of lines in the input and output can
differ, e.g.:
input | output
-----------------------------------------------------------------------
ssh-rsa AA[...] user@host ◀-▶ 256 SHA256:[...] user@host (RSA)
<empty line> ┌▶ 3072 SHA256:[...] user@host (ED25519)
ssh-ed25519 AA[...] user@host ◀┘
To simplify this process, we will do one call to ssh-keygen -l for each
key from the input.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
When fetching SSH keys, the proxy settings specified by the user were
not used. This resulted in the inability to import keys in networks where
a HTTP proxy is mandatory.
We now explicitly set the https_proxy environment variable when calling
ssh-import-id if a proxy was configured by the user.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Instead of fetching SSH keys on the client side, we now make the client
consume an API and have the implementation on the server.
The main benefit is that it gives us more control over the environment
where the ssh-import-id command is executed.
This should allow us to set HTTP proxy environment variables (and
optionally locale-related variables such as LC_MESSAGES) according to
the user's selection.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
ssh-import-id will include empty lines when multiple keys get imported.
These empty lines end up included in the array of authorized keys that
Subiquity manages and subsequently get passed to cloud-init and get
stored in autoinstall-user-data:
authorized_keys = [
'ssh-rsa AAAA[...] user@hostname',
'',
'ssh-ed255129 AAAA[...] user@hostname2',
]
Although cloud-init successfully ignores empty lines, it seems cleaner
to filter those out in Subiquity.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
When executing a command via arun_command with check=True, we forge
and then raise a CalledProcessError exception if the command exits
abnormally (i.e., exit code != 0).
When doing so, we only instantiate the exception with the exit code and
the command executed. This means that we lose access to any output
captured so far. This is usually fine for stdout but stderr oftentimes
contains invaluable information to understand what caused the command to
exit abnormally.
Back in Python 3.5, stdout and stderr were introduced as new attributes
for CalledProcessError.
We now also include stdout and stderr in the CalledProcessError
instances that we forge. This allows us to access stderr (if any) when
catching the exception with:
try:
...
except CalledProcessError as exc:
print(exc.stderr)
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
This kind of change is a bit of a problem with the current approach to
talking to snapd I guess -- deserialization will fail if we encounter a
new value for one of these fields.