srvfb icon indicating copy to clipboard operation
srvfb copied to clipboard

Autoupdates

Open Merovius opened this issue 7 years ago • 1 comments

We should optionally support auto-updates. This isn't entirely trivial and needs some design work, to make it work reliably and securely.

/cc @warpfork because he'd never speak to me again if I screw this up ^^

Merovius avatar Dec 04 '18 13:12 Merovius

After talking a bit offline, we've arrived at this design:

Requirements

  • The root signing key should stay offline and delegate to specific signing keys.
  • No need to host our own infrastructure.
  • Flexibility: Installing a bunch of files to different directories (service files etc), with a potential to add a postinst-hook.
  • Robustness: A broken release should not brick the software. It should at least get fixed by the next release.

Design

Creating a release

Pre-release, the master signing key creates and signs a separate signing key for releasing. The signing key is then uploaded to the PKI. To actually gut a release, we:

  • Create a draft-release via the github API, semantically versioned. Beta-releases are tagged as a prerelease.
  • All files of the release (binaries, unit-files, configs…) are packaged into a tarball, as a complete /-tree and attached to the draft-release
  • A detached signature with the signing key is made and attached to the draft-released
  • The draft-release is marked as non-draft.
  • When a beta release should be promoted to stable, its prerelease status is disabled.

Updating

A separate srvfb-updater is running periodically as a systemd timer and after boot, taking roughly these steps:

  • Check if /var/lib/srvfb.update-in-progress exists. If so, read the required version from there and restart a previously aborted update.
  • Currently installed version is in /var/lib/srvfb.version. If it doesn't exist, assume 0.
  • On each run, look for new releases (in the same major series) via the github API. If there are none, we are done.
  • Download the release and the detached signature for the release to a temporary directory and verify the signature (downloading and verifying the signing key as necessary). The root key is compiled in.
  • Unpack to a temporary directory (e.g. /tmp/srvfb.update)
  • echo $new_version > /var/lib/srvfb.update-in-progress; sync /var/lib (we need to detect crashes after we start modifying the currently installed version)
  • systemctl stop srvfb.service
  • mv /tmp/srvfb.update /
  • systemctl start srvfb.service
  • sync() - flush the changes to disk, before marking the update complete
  • mv /var/lib/srvfb.update-in-progress /var/lib/srvfb.version - mark the update complete

Installing

Once this is in place, we can use srvfb-update to make the installation easier:

  • Have an install_to_remarkable.go, with // +build ignore to do the initial installation to the reMarkable. Needs only to be run once
  • GOARCH=arm go build cmd/srvfb-update
  • scp srvfb-update [email protected]:/usr/bin/srvfb-update
  • ssh [email protected]:/usr/bin/srvfb-update

This should automatically pull the latest version of srvfb and install it via above update-process.

Merovius avatar Dec 15 '18 19:12 Merovius