Update the recovery grub boot config to allow all system labels that are
considered valid by snapd, which are typically just numbers based on date, eg.
20210706 but follow the same rules as model names so hyphen separated
numbers/letters are allowed.
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
had to make the comment in wrappers/services_test.go a one-liner
otherwise half of it is lost
last set of files needing changing (as per current master)
Introduce a structure for passing components of kernel command line. Extend the
structure with a field to carry the full set of arguments. Introduce support in
grub.
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Add support for snapd_full_cmdline_args variable that carries a set of command
line arguments that shall be used in place of the static and extra ones. Thus
the contents of the new variable effectively become the list of arguments that
directly follows `snapd_recovery_mode=.. snapd_recovery_system=...` in the
kernel command line passed by grub.
The boot config edition is not bumped yet, thus it will not trigger an automatic
boot config update when a new snapd gets installed.
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Add try_recovery_system and recovery_system_status to the boot variables tracked
inside little kernel bootloader's environment.
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Add support for injecting bootloader assets and corresponding snippets in test
builds of snapd. The code is only picked up when building with
withbootassetstesting tag.
The snippets are injected only when a specific marker file is present in the
same directory as the snapd binary. This way it is possible to control when a
snapd snap update will trigger an update of boot config assets of the grub
bootloader.
Signed-off-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
This commit adds support for the UC20 LittleKernel bootloader to snapd.
The big changes for using V2 are that we now use a secure bootloader set kernel
command line parameter to identify what disk to look for bootloader environment
structures, and that we use different lkenv structs for different role
bootloaders.
Eventually we should make V1 also use a secure bootloader set kernel command
line parameter to identify what disk to look for bootloader environment
structures on too, as using the partition label like this is vulnerable to
attack by attaching a USB disk with the same partition label to the system.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk{,env}: use xerrors to make Load() err observable as ErrNotExist
Previously we would never continue in SetBootVars if the file doesn't exist
because we used fmt.Errorf which does not preserve the error type such that
os.IsNotExist would return true.
Now, we can continue to provide a customized error message from Load(), as well
as make SetBootVars continue and just write out a new file even if we can't read
the lkenv file in Load().
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* many: rename disks.FindMatching... to FindMatching...WithFsLabel and err types
This is to accommodate a future FindMatching...WithPartLabel. Additionally, an
internal refactor to support storing additional properties for partitions when
we search a disk is implemented to allow for the additional future method.
The error type now is also more versatile to allow specifying what part failed,
searching for a partition by filesystem label or by partition label.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks: add FindMatchingPartitionUUIDFromPartLabel to Disk iface
This will enable searching for a partition with a given label on the provided
disk.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: search for partition labels on the bootloader disk, not fs labels
The partitions with the bootloader structures we care about do not have
filesystems on them, and as such they will not have filesystem labels. Instead,
they will have partition labels, and as such we should search using the
partition label instead.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: rename inRuntimeMode to prepareImageTime
This simplifies numerous functions to be more clear with the simpler
prepare-image time implementation happening first, then the complex runtime
cases happening afterwards are not indented as much.
Thanks to @bboozzoo for the suggestion.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: rename var
Thanks to @bboozzoo for the suggestion.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: fix handling of os.ErrNotExist everywhere, add comments
We should be using xerrors.Is() everywhere here, since the error returned is
wrapped.
However, for specifically RemoveKernelAssets, it's not a bug that we would skip
over os.ErrNotExist, but it would result in a more confusing error message - we
should try to give better error messages, and returning early with
os.ErrNotExist is more useful to the user than the existing error around not
being able to find the specified kernel blob.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: move prepare-image check earlier in ExtractRecoveryKernelAssets
Thanks to @bboozzoo for the recommendation.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks/disks_linux.go: adjust comment about optional partition labels
Thanks to @bboozzoo for clarifying this for me. Partition labels are optional on
GPT partitions.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks/disks.go: fix typo
Thanks to @bboozzoo for catching this.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks/disks_linux.go: add some TODOs about things to cleanup/simplify
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks/disks_linux.go: add comments about the encoding of the udev props
Thanks to @bboozzoo for the suggestion.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks/mockdisk.go: fix typo
Thanks to @bboozzoo again for spotting all my typos :-)
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* osutil/disks: add FindMatchingPartitionUUIDFromPartLabel to Disk iface
This will enable searching for a partition with a given label on the provided
disk.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* many: fix rename of disks pkg function name from rebase
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: don't use l.rootdir for the returned partition file
Using l.rootdir here was wrong in that it would produce for RoleRunMode
bootloaders paths like /run/mnt/ubuntu-boot/dev/disk/by-partuuid/1234, instead
of the correct path of /dev/disk/by-partuuid/... at runtime.
We didn't catch this in tests because we pass in the same rootdir as what we
test for, we didn't test passing in boot.InitramfsUbuntuBootDir for example, so
change the tests to account for this.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lkenv: add compatibility error impl for Go 1.9
Go 1.9 os.PathError does not implement Unwrap(), so using
xerrors.Is(err,os.ErrNotExist) does not work, as Is() calls Unwrap() in a loop,
waiting for either the error returned to be equal to the target error or to be
nil, and in the case of Go 1.9, where os.PathError does not implement Unwrap(),
then nil is returned and Is() returns false.
We can work around this by implementing Unwrap() on our own error type and
specifically returning os.ErrNotExist on Go 1.9 when we know the error is
actually os.ErrNotExist.
This will make the unit tests with Go 1.9 pass.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: use specific backup file for lkenv
For UC20 runtime, the backup file will be a different partition, and since we
are using partition uuid symlinks instead of partition labels, we can't just
append "bak" to the primary env file, and instead need to manually provide the
backup file.
Also add a test which validates that the backup env file for run mode on uc20 is
handled appropriately and updated.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: add test scaffolding and TODO about recovery system add/remove
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: adjust comments
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lkenv/lkenv.go: change XXX to TODO
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lkenv/lkenv.go: inspect the err in compatErrNotExist for Unwrap()
Instead of checking the version of Go we were compiled with which is weird, we
can instead just check for the exact thing we know doesn't work, which is that
os.PathError doesn't implement Unwrap(), so if it doesn't implement Unwrap(), we
know we are in a legacy version of Go and thus should do the manual unwrapping
to return ErrNotExist directly.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: refactor helper methods
This refactors some helper methods to be more clear, namely that envFile becomes
envBackstore, and it takes an argument for whether or not it is returning the
primary or the backup, and eliminating the specific method for getting the
backup file, as well as combining some codepaths in the other helpers to be more
easily readable if slightly redundant in terms of actual code execution.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: move some function definitions around for conventions' sake
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: adjust comment to explain we should try to use kernel cmdline
It might not be there on older gadget bootloaders which don't set that kernel
command line value and as such we will have to fallback to our current behavior.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lkenv/lkenv.go: fix for gofmt 1.9
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk: update handling of os.ErrNotExist for various cases
The only case where we can really proceed without having an initial env file is
at prepare image time when the bootloader env file doesn't exist, as we could be
writing an empty/new one. All other cases we need the file to exist as a
pre-requisite, if only for accurate error reporting.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: rename variable, simplify return statement
Thanks to @pedronis for the suggestion.
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: implement TODO about checking the backup file in Present()
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk.go: re-word awkwardly phrased TODO about using kernel cmdline
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
* bootloader/lk_test.go: add unit test for Present() RoleSole checking backup
Signed-off-by: Ian Johnson <ian.johnson@canonical.com>
Co-authored-by: Maciej Borzecki <maciej.zenon.borzecki@canonical.com>
Merge pull request #9729 from anonymouse64/feature/uc20-lk-bootloader-7
To simplify existing code, use "" as the backup file to mean path+"bak".
Also add tests that when specifying a non-empty string as the backup file that
we don't use the legacy backup file handling logic.
This will resolve the issue we have in #9695 around passing in /dev/disk/by-partuuid/1234 as the primary file and then getting /dev/disk/by-partuuid/1234bak as the backup file.