GeoIP requests used to run on the default executor thread and would
prevent the application from exiting if the GeoIP service would not
respond quickly enough. We witnessed an obvious impact during an
incident on geoip.ubuntu.com.
Move to aiohttp so that the HTTP calls are non blocking.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
We used to make real HTTP calls to geoip.ubuntu.com in dry-run mode.
This might have an impact on the service when running automatic testing.
We now provide an hardcoded value for the GeoIP information in dry-run
mode.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The u-a-c returns a set of information about each service. After
filtering out the services that we don't want using the fields
"entitled" and "available", we now only keep the name and the
description of the service.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The list of activable UA services was only retrieved from the
client-side of Subiquity (using ubuntu-advantage-tools). Therefore, the
desktop installer would need to reimplement the same logic should they
need access to the list of services ; which is inconvenient.
We now expose a new endpoint in the API that takes the token as
a parameter and returns a status (+ a list of services if the token is
valid and not expired).
$ curl \
--unix-socket .subiquity/socket \
--header 'Content-Type: application/json' \
http://a/ubuntu_advantage/check_token \
-d '"C123456"'
The token parameter is expected to be in the body of the request -
rather than in the query string - to avoid ending up in the access logs.
This new endpoint is a read-only GET endpoint. It is not designed as a
replacement for the POST to /a/ubuntu_advantage that the client must
(still) do to pass the token to the model.
We now use this new endpoint internally in Subiquity so that the
retrieval of the activable services is done on the server-side only.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Instead of only checking if a given UA service is available, we now also
check if it is entitled.
- the available field for a service refers to its availability on the
current machine (e.g. on Focal running on a amd64 CPU) ; whereas
- the entitled field tells us if the contract covers the service.
Therefore, we need to make sure that we only list the services that are
both "available" and "entitled".
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
When running an autoinstallation with no ssh: field (which is valid),
the output autoinstall-user-data file would end up with None for the
key ssh:authorized-keys, as shown below:
ssh:
authorized-keys: null
Unfortunately, null is not a valid value according to the schema (which
expects a string).
Fixed by initializing the authorized_keys variable to [] instead of None
so that it yields an empty list instead of null when no autoinstall data
is loaded.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
If no UA token is provided, the UbuntuAdvantageController will generate
autoinstall data that contains an empty string:
ubuntu-advantage:
token: ""
Unfortunately, this is not valid according to the JSON schema.
Fixed by not returning a token: key if the token is an empty string.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
The script can be used to validate autoinstall user data against the
schema. By default, it expects a #cloud-config header and the user-data
to be under the autoinstall: key.
By passing the --no-expect-cloudconfig, it validates the data directly.
We can use this option to validate the YAML files under
examples/autoinstall-*.yaml
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
When running an autoinstallation with only “network” as an interactive
section, the installation hanged after the following steps:
finalizing installation
running 'curtin hook'
curtin command hook
executing late commands
where in normal conditions, the next step is:
final system configuration
Also, querying the meta/status endpoint at this point shows that the app
is in POST_WAIT state.
The problem is:
the network model is declared as both an “install” model and a
“postinstall” model (it is the only one we have AFAIK)
when calling .configured() for a given model, we only trigger /at max/
one event. Either:
* install_event (if the model is an “install” model - and it is the
last one configured)
* postinstall_event (if the model is a “postinstall” model but not an
“install” model - and it is the last one configured)
* no event (as in most cases)
So when we call .configured() for the network model, we /can/ trigger
the install_event but can never trigger the postinstall event.
Therefore Subiquity, will wait forever until something triggers the
postinstall_event
Fixed by accepting to trigger the install_event and the
postinstall_event in a single call to .configured.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>
Passing --use-fuse to scripts/kvm-test.py allows to run as non-root.
It requires installation of the package fuseiso so the switch is
disabled by default.
Signed-off-by: Olivier Gayot <olivier.gayot@canonical.com>