gokrazy

package module
v0.0.0-...-8e52f71 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2020 License: BSD-3-Clause Imports: 37 Imported by: 0

README

Build Status Go Report Card

Overview

gokrazy packs your Go application(s) into an SD card image for the Raspberry Pi 3 or 4 which — aside from the Linux kernel and proprietary Raspberry Pi bootloader — only contains Go software.

The motivation is that @stapelberg spends way more time on C software and their various issues than he would like. Hence, he is going Go-only where feasible.

Usage

Installation

Install the latest Go version if you haven’t already.

Create a directory for this gokrazy instance and initialize a Go module:

INSTANCE=gokrazy/hello
mkdir -p ~/${INSTANCE?}
cd ~/${INSTANCE?}
go mod init hello

Then, install gokr-packer:

go get github.com/gokrazy/tools/cmd/gokr-packer@latest

Overwriting an SD card for the Raspberry Pi 3 or 4

To re-partition and overwrite the SD card /dev/sdx, use:

gokr-packer -overwrite=/dev/sdx github.com/gokrazy/hello

Then, put the SD card into your Raspberry Pi 3 or 4 and power it up! Once the Raspberry Pi 3 or 4 has booted (takes about 10 seconds), you should be able to reach the gokrazy web interface at the URL which gokr-packer printed.

Under the hood, gokr-packer

  1. …packed the latest firmware and kernel binaries into the boot file system.

  2. …built the specified Go packages using go install and packed all their binaries into the /user directory of the root file system.

  3. …created a minimal gokrazy init program which supervises all binaries (i.e. restarts them when they exit).

Updating your installation

To update gokrazy, including the firmware and kernel binaries, use:

go get -u github.com/gokrazy/tools/cmd/gokr-packer
go get -u github.com/gokrazy/gokrazy
go get -u github.com/gokrazy/kernel
go get -u github.com/gokrazy/firmware
go get -u github.com/gokrazy/rpi-eeprom

To update your gokrazy installation (running on a Raspberry Pi 3 or 4), use:

GOKRAZY_UPDATE=http://gokrazy:mysecretpassword@gokrazy/ gokr-packer github.com/gokrazy/hello

SD card contents

gokrazy uses the following partition table:

num size purpose file system
1 100 MB boot (kernel+firmware) FAT16B
2 500 MB root2 (gokrazy+apps) SquashFS
3 500 MB root3 (gokrazy+apps) SquashFS
4 rest permanent data ext4

The two root partitions are used alternatingly (to avoid modifying the currently active file system) when updating.

If you’d like to store permanent data (i.e. data which will not be overwritten on the next update), you’ll need to create an ext4 file system on the last partition. If your SD card is /dev/sdx, use mkfs.ext4 /dev/sdx4.

Customization

Changing program behavior for gokrazy

gokr-packer sets the “gokrazy” build tag for conditional compilation.

You can find an example commit which implements a gokrazy-specific controller that triggers the main program logic every weekday at 10:00 at https://github.com/stapelberg/zkj-nas-tools/commit/6f90ace35981f78dcd66d611269f17f37ce4b4ef

Changing init behavior

Assuming the application you’d like to create on gokrazy lives in the repository github.com/stapelberg/mediaserver, this is how you can make gokrazy dump the generated init package’s source:

mkdir -p $(go env GOPATH)/src/github.com/stapelberg/mediaserver/cmd/init
gokr-packer \
  -overwrite_init=$(go env GOPATH)/src/github.com/stapelberg/mediaserver/cmd/init/init.go \
  github.com/gokrazy/hello

(Note that the package must result in a binary called “init”.)

Then, edit the github.com/stapelberg/mediaserver package to your liking. When done, pack an image with your own init package:

gokr-packer \
  -init_pkg=github.com/stapelberg/mediaserver/cmd/init \
  -overwrite=/dev/sdx \
  github.com/gokrazy/hello

Repository structure

Documentation

Overview

gokrazy packs your Go application(s) into an SD card image for the Raspberry Pi 3 which — aside from the Linux kernel and proprietary Raspberry Pi bootloader — only contains Go software.

Boot and Supervise are called by the auto-generated init program. They are provided in case you need to implement a custom init program.

PrivateInterfaceAddrs is useful for init and other processes.

DontStartOnBoot and WaitForClock are useful for non-init processes.

Index

Constants

This section is empty.

Variables

View Source
var PrivateNetworks = []string{

	"127.0.0.0/8",

	"::1/128",

	"10.0.0.0/8",
	"172.16.0.0/12",
	"192.168.0.0/16",

	"fc00::/7",

	"169.254.0.0/16",

	"fe80::/10",
}

PrivateNetworks contains the CIDR representation of all networks which gokrazy considers private.

Functions

func Boot

func Boot(userBuildTimestamp string) error

Boot configures basic system settings. More specifically, it:

  • mounts /dev, /tmp, /proc, /sys and /perm file systems
  • mounts and populate /etc tmpfs overlay
  • sets hostname from the /etc/hostname file
  • sets HTTP password from the gokr-pw.txt file
  • configures the loopback network interface

Boot should always be called to transition the machine into a useful state, even in custom init process implementations or single-process applications.

userBuildTimestamp will be exposed on the HTTP status handlers that are set up by Supervise.

func DontStartOnBoot

func DontStartOnBoot()

DontStartOnBoot informs the gokrazy init process to not supervise the process and exits. The user can manually start supervision, which turns DontStartOnBoot into a no-op.

func IsInPrivateNet

func IsInPrivateNet(ip net.IP) bool

IsInPrivateNet reports whether ip is in PrivateNetworks.

func Model

func Model() string

Model returns a human readable description of the current device model, e.g. “Raspberry Pi 4 Model B Rev 1.1” or “PC Engines apu2”.

func PrivateInterfaceAddrs

func PrivateInterfaceAddrs() ([]string, error)

PrivateInterfaceAddrs returns all private (as per RFC1918, RFC4193, RFC3330, RFC3513, RFC3927, RFC4291) host addresses of all active interfaces, suitable to be passed to net.JoinHostPort.

func PublicInterfaceAddrs

func PublicInterfaceAddrs() ([]string, error)

PublicInterfaceAddrs returns all public (excluding RFC1918, RFC4193, RFC3330, RFC3513, RFC3927, RFC4291) host addresses of all active interfaces, suitable to be passed to net.JoinHostPort.

func Supervise

func Supervise(commands []*exec.Cmd) error

Supervise continuously restarts the processes specified in commands unless they run DontStartOnBoot.

Password-protected HTTP handlers are installed, allowing to inspect the supervised services and update the gokrazy installation over the network.

HTTP is served on PrivateInterfaceAddrs(). New IP addresses will be picked up upon receiving SIGHUP.

func WaitForClock

func WaitForClock()

WaitForClock returns once the system clock appears to have been set. Assumes that the system boots with a clock value of January 1, 1970 UTC (UNIX epoch), as is the case on the Raspberry Pi 3.

Types

This section is empty.

Directories

Path Synopsis
cmd
dhcp
dhcp is a minimal DHCP client for gokrazy.
dhcp is a minimal DHCP client for gokrazy.
ntp
ntp is a minimal NTP client for gokrazy.
ntp is a minimal NTP client for gokrazy.
randomd
Binary randomd carries entropy across restarts.
Binary randomd carries entropy across restarts.
Package empty is pulled in only for the side-effect of checking out the gokrazy git repository.
Package empty is pulled in only for the side-effect of checking out the gokrazy git repository.
internal
teelogger
Package teelogger provides loggers which send their output to multiple writers, like the tee(1) command.
Package teelogger provides loggers which send their output to multiple writers, like the tee(1) command.

Jump to

Keyboard shortcuts

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