updater

package module
v0.0.0-...-4ac511a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 13, 2024 License: BSD-3-Clause Imports: 14 Imported by: 6

Documentation

Overview

Package updater implements updating the different parts of a running gokrazy installation (boot/root file systems and MBR).

Example
package main

import (
	"io"
	"log"
	"net/http"

	"github.com/gokrazy/updater"
)

// obtained from elsewhere, not relevant for this example
var rootReader, bootReader, mbrReader io.Reader

func main() {
	const baseURL = "http://gokrazy:example@gokrazy/"
	target, err := updater.NewTarget(baseURL, http.DefaultClient)
	if err != nil {
		log.Fatalf("checking target partuuid support: %v", err)
	}

	// Start with the root file system because writing to the non-active
	// partition cannot break the currently running system.
	if err := target.StreamTo("root", rootReader); err != nil {
		log.Fatalf("updating root file system: %v", err)
	}

	if err := target.StreamTo("boot", bootReader); err != nil {
		log.Fatalf("updating boot file system: %v", err)
	}

	// Only relevant when running on PCs (e.g. router7), the Raspberry Pi does
	// not use an MBR.
	if err := target.StreamTo("mbr", mbrReader); err != nil {
		log.Fatalf("updating MBR: %v", err)
	}

	if err := target.Switch(); err != nil {
		log.Fatalf("switching to non-active partition: %v", err)
	}

	if err := target.Reboot(); err != nil {
		log.Fatalf("reboot: %v", err)
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrUpdateHandlerNotImplemented = errors.New("update handler not implemented")

ErrUpdateHandlerNotImplemented is returned when the requested update destination is not yet implemented on the target device. Callers can programmatically distinguish this error to print an according message and possibly proceed with the update.

Functions

This section is empty.

Types

type EEPROMVersion

type EEPROMVersion struct {
	PieepromSHA256 string // pieeprom.sig
	VL805SHA256    string // vl805.sig
}

EEPROMVersion contains the signatures of a set of Raspberry Pi EEPROM files (pieeprom.sig and vl805.sig). The signatures are sha256 sums (hexadecimal), but you should treat them as opaque strings and only compare them.

type HTTPDoer

type HTTPDoer interface {
	Do(*http.Request) (*http.Response, error)
}

A HTTPDoer is satisfied by any *http.Client, but also easy to implement in case extra middleware is desired.

type ProtocolFeature

type ProtocolFeature string

A ProtocolFeature represents an optionally available feature of the update protocol, i.e. features that might possibly be missing in older gokrazy installations.

const (
	// ProtocolFeaturePARTUUID signals that the target understands the PARTUUID=
	// Linux kernel parameter and uses it in its cmdline.txt bootloader config,
	// i.e. is ready to accept an update that is using PARTUUID, too.
	ProtocolFeaturePARTUUID ProtocolFeature = "partuuid"

	// ProtocolFeatureUpdateHash signals that the target understands the
	// X-Gokrazy-Update-Hash HTTP header and at least the “crc32” value, which
	// is significantly faster than SHA256, which is used by default.
	ProtocolFeatureUpdateHash ProtocolFeature = "updatehash"
)

type Target

type Target struct {
	// contains filtered or unexported fields
}

Target represents a gokrazy installation to be updated.

func NewTarget

func NewTarget(baseURL string, httpClient HTTPDoer) (*Target, error)

NewTarget queries the target for supported update protocol features and returns a ready-to-use updater Target.

func (*Target) Divert

func (t *Target) Divert(path, diversion string, serviceFlags, commandLineFlags []string) error

Divert makes gokrazy use the temporary binary (diversion) instead of /user/<basename>. Includes an automatic service restart.

func (*Target) InstalledEEPROM

func (t *Target) InstalledEEPROM() EEPROMVersion

InstalledEEPROM returns the Raspberry Pi EEPROM version currently installed on the target device.

func (*Target) Put

func (t *Target) Put(dest string, r io.Reader) error

Put streams a file to the specified HTTP endpoint, without verifying its hash. This is not suited for updating the system, which should be done via StreamTo() instead. This function is useful for the /uploadtemp/ handler.

func (*Target) Reboot

func (t *Target) Reboot() error

Reboot reboots the target, picking up the updated partitions.

func (*Target) RebootWithoutKexec

func (t *Target) RebootWithoutKexec() error

RebootWithoutKexec reboots the target without kexec, picking up the updated partitions. This is useful for continuous integration testing to ensure the bootloader is tested.

func (*Target) StreamTo

func (t *Target) StreamTo(dest string, r io.Reader) error

StreamTo streams from the specified io.Reader to the specified destination:

  • mbr: stream content directly onto the root block device
  • root: stream content to the currently inactive root partition
  • boot: stream content to the boot partition

When updating only the boot partition and not also the root partition (e.g. in gokrazy’s Continuous Integration), the following suffix should be used:

  • bootonly: stream content to the boot partition, then update the boot partition so that the currently active root stays active.

You can keep track of progress by passing in an io.TeeReader(r, &countingWriter{}).

func (*Target) Supports

func (t *Target) Supports(feature ProtocolFeature) bool

Supports returns whether the target is known to support the specified update protocol feature.

func (*Target) Switch

func (t *Target) Switch() error

Switch changes the active root partition from the currently running root partition to the currently inactive root partition.

func (*Target) Testboot

func (t *Target) Testboot() error

Testboot marks the inactive root partition to be tested upon the next boot, and made active if the test boot succeeds.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL