Instead of having interleaved stdout and stderr in server-output, we now
have respectively:
* stdout redirected to server-stdout
* stderr redirected to server-stderr
This will allow us to monitor for warnings / errors more efficiently.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
RFC3339 allows dates to use the Z suffix instead of a time zone offset
of 0. Unfortunately, this is not supported by Python
datetime.date.fromisoformat. Work around the issue by replacing the
optional Z character with +00:00 before parsing the date.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The ensure_cmd_exists() coroutine from ubuntu_drivers was never awaited.
Therefore, the check would always silently succeed. Taking a look in
server-output would show the warning though:
RuntimeWarning: coroutine
'UbuntuDriversHasDriversInterface.ensure_cmd_exists' was never awaited
self.ubuntu_drivers.ensure_cmd_exists(d.mountpoint)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Also, the implementation of ensure_cmd_exists() when
SUBIQUITY_DEBUG=run-drivers is set was failing because we use a shell
builtin as an executable. This was not noticed since ensure_cmd_exists()
was not executed and arun_command() does not check for errors by
default.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Per LP: #1962025, the update screen can get stuck in test automation.
Cancel the task waiting to see if there is an update, which makes sense
more broadly anyhow in that if a regular UI user has declined the
update then the check task is no longer helpful.
Instead of using systemd-cat in dry-run mode and systemd-run in normal
mode, we now use systemd-run all the time but pass the --user switch
when running as non-root.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The LoggedCommandRunner now has the option to start a command with
private mounts enabled - see mount_namespaces(7).
To use this feature, we now rely on systemd-run instead of systemd-cat.
The main benefit is that it should allow us not to worry about mounts
refusing to be un-mounted after executing a curtin in-target command.
On the downside, systemd-run requires root privileges (unless --user is
available) so we can't use it in dry-run mode. For dry-run mode, we
still need to rely on systemd-cat.
Another downside is that the commands passed to systemd-run are run in a
clean environment. Therefore, we must explicitly set the environment
variables that we want to pass to the commands to execute.
I came up with a short list of environment variables that we need but we
might need to add more later.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
We now provide implementation for different interfaces to list and
install drivers using ubuntu-drivers. The implementations are outside
the drivers controller.
We have:
* the normal interface that calls ubuntu-drivers in the root directory
specified (i.e., in /target or an overlay).
* a dry-run interface that calls the system's ubuntu-drivers for
listing the drivers available (but does not install anything).
The listing of drivers will fail if --recommended is not an available
option in the system's ubuntu-drivers implementation.
* a dry-run interface that returns an hard-coded list of drivers and
does nothing on installation.
* a dry-run interface that returns an empty list of drivers.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Using run_curtin_command, we have no way to specify the encoding or
something like universal_newlines=True. This is actually not supported
by asyncio.create_subprocess_exec(...).
We have partial support for this in Subiquity when using arun_command()
but run_curtin_command() actually relies on astart_command() + wait().
Therefore, we now decode the output at the very end, just before reading
the outout of ubuntu-drivers.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
In the reponse to the /a/drivers GET call, we now include a list of
packages / drivers instead of just storing a boolean telling if any
driver has been found.
Each element from the list corresponds to the name of a package to
install.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The drivers GET call returned only the value of "has_drivers" (when
known). In order to have the client be able to know the current value of
install/do_install, we now embed the value into the response as well:
Before, the call would return either:
true -> meaning that there are drivers available to install
false -> meaning that there are no drivers available to install
null -> retry later - we don't know yet
Now we have:
{
"has_drivers": boolean or null if we don't know yet
"install": boolean
}
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The autoinstall data for the drivers was only constituted of a boolean,
e.g.:
drivers: true
or
drivers: false
It was not immediately clear that the boolean value meant (install/don't
install the drivers).
We now store the boolean in the "install" sub-element instead, e.g.:
drivers:
- install: true
drivers:
- install: false
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>