Skip to content

Tools to manage swupdate images for armadillo

License

Notifications You must be signed in to change notification settings

atmark-techno/mkswu

Repository files navigation

## mkswu

Helper to generate swupdate image.

Options can be set with swdesc_option.
Multiple options can be passed in same command as separate arguments.

swdesc_option PUBKEY=<path>
    path to certificate for signing, if multiple are given the later
    are added to device's /etc/swupdate.pem if UPDATE_CERTS is set.
swdesc_option UPDATE_CERTS=<value>
    whether to update swupdate.pem on device with certificates defined in
    PUBKEY. Unset is no.
swdesc_option PRIVKEY=<path>
    path to key for signing
swdesc_option PRIVKEY_PASS=<value>
    passphrase for private key, see openssl(1) "Pass Phrase Options" for
    examples (e.g. file:pathname)
swdesc_option ENCRYPT_KEYFILE=<path>
    encrypt input files if set, generated if does not exist on first use
swdesc_option DESCRIPTION=<value>
    arbitrary description string. Displayed in verbose swupdate run.
swdesc_option BOOT_SIZE=<size>
    pad boot image with zeros up to this size (clear env)
    set to blank to keep original file size.
swdesc_option POST_ACTION=<value>
    control behaviour post install. <value> must be one of:
    - empty or reboot (default): reboot into new system after updating
    - poweroff: shut system down after install (useful for provisioning)
    - container: if the update has no system component, restart only
                 containers without rebooting the system.
                 If system files were updated reboot normally.
    - wait: wait forever after update for an external reboot signal.
            Note further updates will not be installed in this mode:
            the system MUST reboot before installing the next update.
swdesc_option NOTIFY_STARTING_CMD=<cmd>
swdesc_option NOTIFY_FAIL_CMD=<cmd>
swdesc_option NOTIFY_SUCCESS_CMD=<cmd>
    Commands to run when the update starts installing something,
    finished on an error, or installed successfully (success is
    mostly useful for POST_ACTION=wait)
    Note none of these commands run if the signature was not verified
    successfully (arbitrary execution of untrusted file is bad), nor
    if the update is considered already installed or somehow fails before
    the version check.
swdesc_option FORCE_VERSION
    allow building image with no explicit version set.
    (components with no versions will always be installed)
    Note that to avoid install loops with USB drive install,
    updates with FORCE_VERSION set will be renamed to
    <original_name>.swu.installed after successful install
    unless POST_ACTION=poweroff
swdesc_option CONTAINER_CLEAR
    if set, swupdate will kill running containers and
    remove any running containers from appfs and
    /etc/atmark/containers/*.conf before continuing install.
    /!\ if install fails this will leave your system
        with no application, usage is discouraged /!\
swdesc_option NO_PRESERVE_FILES
    if set, swupdate will not copy files listed in
    /etc/swupdate_preserve_files when base_os is updated
    This option is deprecated until a proper way of running
    'first boot'-style scripts is available.
swdesc_option ROOTFS_FSTYPE={ext4,btrfs}
    filesystem to use for /
    By default the same as current fs is reused.
swdesc_option SKIP_APP_SUBVOL_SYNC
    (for test only) skip btrfs subvolume sync command that
    slows down tests
swdesc_option ALLOW_EMPTY_LOGIN
    (for test only) allow update to install if user passwords have not been set
swdesc_option ALLOW_PUBLIC_CERT
    (for test only) allow update to install if no user certificate has been
    installed, in which case public cert is left enabled


Common options for all helpers:

--version <component> <version>
  We define arbitrary components for swupdate to only install update
  if required.
  - Updates are installed only if version is higher than what is on
    the system, or if not present on the system, except for "boot"
    which is installed if different
  - Components can be defined freely for updates referring to
    containers (container image or files within volumes);
    if an update writes to rootfs then it must be named "base_os"
    (in which case OS is wiped first) or extra_os* (in which case
    the OS is copied over first)
  - In most case component/version can be skipped, then "$component"
    and "$version" variables will be used. component defaults to the
    desc file's basename (e.g. 'foo.desc' would be 'foo'), but version
    has no default and must explicitly be set unless FORCE_VERSION
    is set in which case file will always be reinstalled.

--extra-os
  prefix component with 'extra_os.' to get root filesystem mounted
  read-write. This is not required if version is set explicitly,
  and has no effect if set before version.

--base-os
  set component to 'base_os'. This is intended for OS updates only.

--install-if <mode>
  mode can be one of higher or different.
  Can also set the "install_if" environment variable.
  This can be used to override the behaviour described above and
  force either mode, in particular hawkbit only supports different
  mode so one might want to enable this globally.

--version-ignore
  Explicitly do not set any version for this command. It will be installed
  every time if and only if the swu would be installed.
  See the FORCE_VERSION global option or --version-force if you would like
  to install the SWU again every time.

--version-force
  This is the same as --version-ignore, except that it also enforce the
  SWU installation like `swdesc_option FORCE_VERSION` would.

--main-version
  Tag this component's name/version as image's main version.
  Only used for image managements (e.g. around hawkbit) which will
  normally only consider the first one to be set

--description
  Alternate text that will be printed when swu is installing this step


Additionally, these options can be used on "command-running commands"
(e.g. swdesc_command, swdesc_script and swdesc_exec):

--stdout-info
  Redirect command stdout to info fd if available; this allows displaying
  command outputs more easily

--container
  Run the command in given container image instead of install target chroot.
  In this case the install target is mounted as /target

Images are then built progressively by calling the following helpers:

swdesc_boot <bootfile>
  Include boot file, version is automatically set from file if not set

swdesc_tar <tar file> [--dest <dest>] [--preserve-attributes]
  Extract <tar file> at <path> within new system.
  Destination path must be within /var/app/(rollback/)?volumes
  unless rootfs is targeted (see <component> in Glossary), and defaults
  to / for os versions and /var/app/rollback/volumes otherwise
  (relative paths for non-os versions are assumed relative to
   /var/app/rollback/volumes)
  Owner and mode are lost (except execute) unless --preserve-attributes
  is set

swdesc_files [--basedir <basedir>] [--dest <dest>] <file> [<more files>]
  Copy files into <dest> (same defaults as swdesc_tar), as they
  are relative to <basedir>
  basedir defaults to the first argument if it is a directory (assumes
  single argument: all the directory content will be extracted to <dest>),
  or the first argument's parent otherwise.

swdesc_command "<cmd>"
  Run command inside new root

swdesc_script <script>
  Run script inside new root

swdesc_exec <file> <command>
  Run command with <file> available as $1 inside the new root
  Note that this is run in the order swdesc is built, so adding
  a swdesc_exec before e.g. base_os will run before the target
  OS is setup and likely not work
  In doubt use swdesc_script unless you need to send data this way.

swdesc_command_nochroot, swdesc_script_nochroot, swdesc_exec_nochroot
  Same as the above but from the currently running os point of view.
  You probably do not need this.

swdesc_embed_container <image archive>
  Include image and load it into storage

swdesc_usb_container <image archive>
  Sign image archive and will look for it on USB drive to
  install with USB update. The image and .sig must be copied
  to the root of the USB drive together with the swu
  Note that podman cannot handle compressed image without storing
  an extra uncompressed copy, so it is best to keep that image
  uncompressed (not a problem for embedding as swupdate does
  the decompressing step)

swdesc_pull_container <image url>
  Pull container from network into storage


## podman_partial_image

Generate image file from tags or image ids.
If a base image/tag is given, remove objects from image file that
were used in base image.


## genkey.sh

Generate a private/public key pair to use for rsa pss signing of files.
generated files:
 - swupdate.key is the private signing key that should be kept private.
 - swupdate.pem should be installed to /etc/swupdate.pem and is used
for verification of sw-description and container images if side-loaded.

Note that encryption does not use this key.

Only here for compatibility, please use mkswu --genkey instead


## docs

Extra documentation files e.g. common error patterns


## examples

Sample config files, try from git root:

 ./mkswu -o foo.swu examples/foo.conf

read each .conf file for their requirements (files to pre-create)
all examples expect keys to have been generated before (./genkey.sh),
in default path, and public key must be installed on device to use.


## bash completion

Bash completion is available for some commands, if you use bash
just source it or copy to /etc/bash_completion.d:

 . bash_completion.sh
 sudo cp bash_completion.sh /etc/bash_completion.d/swupdate-mkimage

## tests

conf files in the test directory will use internal variables to
disable part or all the scripts, allowing to test specific components
of the system.
Please do not rely on these and ask for supporting features you need!