srvfb
srvfb copied to clipboard
Autoupdates
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 ^^
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.servicemv /tmp/srvfb.update /systemctl start srvfb.servicesync()- flush the changes to disk, before marking the update completemv /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 ignoreto do the initial installation to the reMarkable. Needs only to be run once GOARCH=arm go build cmd/srvfb-updatescp srvfb-update [email protected]:/usr/bin/srvfb-updatessh [email protected]:/usr/bin/srvfb-update
This should automatically pull the latest version of srvfb and install it via above update-process.