Files
iconograph/README.md

251 lines
9.6 KiB
Markdown
Raw Permalink Normal View History

2016-04-01 13:48:58 -07:00
# Iconograph
2016-04-01 21:07:23 -07:00
Iconograph ("icon") is a system for building and deploying Ubuntu system images.
2016-04-01 13:48:58 -07:00
It allows you to distribute your software intended to run on real hardware or
inside a container as a single unit with its system dependencies, and to roll
2016-04-01 20:46:20 -07:00
forward and backward in a secure, repeatable, staged manner.
2016-04-01 13:48:58 -07:00
2016-04-02 13:44:54 -07:00
## Overview
2016-04-02 13:45:15 -07:00
```
2016-04-02 13:44:54 -07:00
+-------------------------------------------------------------+
| Physical disk |
| +-----------------------------------------+ +-------------+ |
| | /boot | | /persistent | |
| | +-----------------+ +-----------------+ | | | |
| | | 1459629471.iso | | 1459629717.iso | | | | |
| | | | | | | | | |
| | | kernel | | kernel | | | | |
| | | initrd | | initrd | | | | |
| | | | | | | | | |
| | | +-------------+ | | +-------------+ | | | | |
| | | | squashfs | | | | squashfs | | | | | |
| | | | / (root) fs | | | | / (root) fs | | | | | |
| | | +-------------+ | | +-------------+ | | | | |
| | +-----------------+ +-----------------+ | | | |
| +-----------------------------------------+ +-------------+ |
+-------------------------------------------------------------+
2016-04-02 13:45:15 -07:00
```
2016-04-02 13:44:54 -07:00
2016-04-02 13:52:22 -07:00
Icon supports multiple image options at boot time by building Live CD-style ISO
images. It writes multiple ISO images to a /boot partition, and uses grub to
select between them at boot time (with hotkeys for headless selection). A second
grub instance runs inside the ISO to allow further customization (e.g. running
and upgrading memtest86).
2016-04-02 13:50:48 -07:00
Images utilize a tmpfs overlay filesystem, so by default filesystem changes
are discarded on reboot or upgrade. An optional /persistent filesystem allows
data storage across reboots and upgrades/downgrades.
Images optionally self-upgrade by fetching new images from an HTTP(S) source
and updating the configuration of the outer grub instance. This removes the
need for a separate OS instance to perform upgrades (and avoids figuring out
how to upgrade that instance).
2016-04-01 13:48:58 -07:00
## Setup
```bash
sudo apt-get install --assume-yes git grub-pc xorriso squashfs-tools openssl python3-openssl debootstrap
git clone https://github.com/robot-tools/iconograph.git
cd iconograph
```
2016-04-01 20:46:20 -07:00
## Image creation
2016-04-02 13:44:54 -07:00
### Image composition
2016-04-01 20:46:20 -07:00
Icon creates images by merging the kernel and boot system of a desktop live CD
with a server/custom filesystem. You'll need to download the desktop live CD
2016-04-01 21:03:57 -07:00
ISO for the version that you're building. You can get them [here](http://mirror.pnl.gov/releases/).
2016-04-01 20:46:20 -07:00
### Serving
Images are fetched via HTTP. You should write images to a directory accessible
2016-04-01 21:03:57 -07:00
via HTTP. Install apache2 if need be.
2016-04-01 20:46:20 -07:00
### Simple image build
2016-04-02 10:54:46 -07:00
build_image.py will call debootstrap, which will fetch packages from Ubuntu
servers. You may want to
[set up caching](https://medium.com/where-the-flamingcow-roams/apt-caching-for-debootstrap-bac499deebd5#.dvevbcc9z)
to make this process fast on subsequent runs.
2016-04-01 20:46:20 -07:00
```bash
# Must run as sudo to mount/umount images, tmpfs, and overlayfs
sudo server/build_image.py --image-dir=/output/path --release=trusty --source-iso=path/to/ubuntu-14.04.4-desktop-amd64.iso
```
2016-04-01 21:03:57 -07:00
2016-04-02 13:32:27 -07:00
## Modules
2016-04-01 21:03:57 -07:00
2016-04-01 21:07:23 -07:00
Modules are scripts that run after the chroot has been created. They can install
packages, do configuration, etc. Icon has several stock modules, but you can
2016-04-01 21:03:57 -07:00
also create your own using them as examples. You can pass multiple --module
flags to build_image.py as long as the modules are compatible with each other.
2016-04-01 21:07:23 -07:00
Stock modules:
2016-04-06 22:59:57 -07:00
### autoimage.py
Build an image that will partition, mkfs, and install an image from a different
URL onto a target system. Used to create install USB drives, PXE boot, etc.
Use the build_image.py flag:
```bash
--module="server/modules/autoimage.py --base-url=http://yourhost/ --ca-cert=/path/to/signing/cert.pem --device=/dev/sdx --persistent-percent=50"
```
`--device` specifies the device to partition and install to on the target
system.
Optional flags:
`--persistent-percent`, if non-zero, specifies the percent of the target
device to allocate to a LABEL=PERSISTENT filesystem. If the inner image uses
persistent.py, this filesystem will be automatically mounted.
`--https-ca-cert` specifies a local path to a PEM-encoded certificate to
validate the HTTPS image server cert against. This differs from `--ca-cert`,
which is used to validate the manifest.json signature.
`--https-client-cert` and `--https-client-key` are used together to specify
local paths to a PEM-encoded certificate and key pair that will be provided
to the server over HTTPS. This can be used to limit image availability.
2016-04-06 23:06:43 -07:00
### certclient.py
Use a local master key/cert pair to authenticate to a
2016-04-06 23:07:50 -07:00
[certserver](https://github.com/robot-tools/certserver) instance and retrieve
2016-04-06 23:06:43 -07:00
a system-specific key. Mainly intended to be used with autoimage.py and
systemid.py.
Use the build_image.py flag:
```bash
2016-04-07 20:39:50 +00:00
--module="server/modules/certclient.py --server=https://certserver/ --ca-cert=/path/to/server/cert.pem --client-cert=/path/to/client/cert.pem --client-key=/path/to/client/key.pem --tag=www --subject='/C=US/ST=California/O=XXXX/OU=XXXX Test/CN=SYSTEMID'"
2016-04-06 23:06:43 -07:00
```
The new key and cert are saved to /systemid
`--tag` specifies a value added to the filename, so certclient.py can be
used more than once with different servers (e.g. once for an HTTPS client
key/cert pair, and once for an EAP-TLS key/cert pair).
2016-04-07 20:39:50 +00:00
`--subject` specifics the subject string passed to openssl. `SYSTEMID` is
2016-04-06 23:06:43 -07:00
replaced with the system hostname, possibly as set by systemid.py
2016-04-02 13:32:27 -07:00
### iconograph.py
2016-04-01 21:03:57 -07:00
Install icon inside the image. This allows the image to auto-update over HTTP.
Use the build_image.py flag:
```bash
--module="server/modules/iconograph.py --base-url=http://yourhost/ --ca-cert=/path/to/signing/cert.pem"
```
2016-04-02 13:22:24 -07:00
Optional flags:
2016-04-06 22:59:57 -07:00
`--https-ca-cert` specifies a local path to a PEM-encoded certificate to
validate the HTTPS image server cert against. This differs from `--ca-cert`,
which is used to validate the manifest.json signature.
2016-04-02 13:22:24 -07:00
`--max-images` sets the number of recent images to keep. Older images are
deleted. Defaults to 5. 0 means unlimited.
2016-04-02 13:32:27 -07:00
### persistent.py
2016-04-01 21:03:57 -07:00
Mount a /persistent partition from a filesystem with LABEL=PERSISTENT. Allows
data to persist across reboots, when it would normally be wiped by tmpfs.
Use the build_image.py flag:
```bash
--module="server/modules/persistent.py"
```
2016-04-06 22:59:57 -07:00
See [imager/image.py](imager/image.py)'s or
[server/module/autoimage.py](autoimage.py)'s `--persistent-percent` flag to
create this partition.
2016-04-01 21:03:57 -07:00
2016-04-06 22:59:57 -07:00
### systemid.py
Mount a /systemid partition from a filesystem with LABEL=SYSTEMID. This is
intended to a be separate device (possibly a USB flash drive, SD card, etc.)
which contains data that persists across re-images and identifies the system,
including system-specific keys and certificates.
2016-04-01 21:03:57 -07:00
2016-04-06 23:06:43 -07:00
It also sets the hostname to the value found in the systemid config on the
device.
2016-04-01 21:03:57 -07:00
```bash
2016-04-06 22:59:57 -07:00
--module="server/modules/systemid.py"
2016-04-01 21:03:57 -07:00
```
2016-04-02 13:34:02 -07:00
## Module API
Modules are passed the following long-style arguments:
`--chroot-path` specifies the absolute path to the root of the debootstrap
chroot that will become the root filesystem of the inner image.
2016-04-02 13:31:45 -07:00
## Manifests
2016-04-01 21:13:50 -07:00
Clients download a manifest file to determine available images and to verify
authenticity and integrity of the image. You'll need to generate one on the
server after each new image is built.
Manifest files are signed using OpenSSL. You should run your own CA to do this;
do NOT use a public CA cert. You can find instructions for setting up a CA
[here](https://medium.com/where-the-flamingcow-roams/elliptic-curve-certificate-authority-bbdb9c3855f7#.7v40ox70s).
To build a manifest, run:
```bash
server/publish_manifest.py --cert=/path/to/signing/cert.pem --key=/path/to/signing/key.pem --image-dir=/image/path
```
Optional flags:
`--default-rollout` specifies the percentage rollout for new images; it
defaults to zero. The units are
[basis points](https://en.wikipedia.org/wiki/Basis_point); 10000 means 100%.
2016-04-02 13:16:06 -07:00
`--max-images` sets the number of recent images to keep. Older images are
2016-04-02 13:22:24 -07:00
deleted. Defaults to 0, meaning unlimited.
2016-04-02 13:16:06 -07:00
`--other-cert` specifies a chain certificate, such as your intermediate cert.
It may be specified more than once.
2016-04-01 21:17:25 -07:00
To push a rollout to more targets, edit /image/path/manifest.json.unsigned,
and change rollout_\u2031 (u2031 is ‱, the symbol for basis point). Save,
then re-run publish_manifest.py to generate the signed version.
2016-04-02 15:55:12 -07:00
## Testing with qemu
You can boot images for testing and issue reproduction using qemu.
```base
sudo apt-get install qemu-system-x86_64
sudo kvm_ok
# The above must "KVM acceleration can be used" to be able to get reasonable performance
sudo qemu-system-x86_64 --curses --smp 2 --m 4G --netdev user,id=vmnic --device virtio-net,netdev=vmnic --enable-kvm --cdrom /path/to/image.iso
```
2016-04-02 13:31:45 -07:00
## Imaging
2016-04-01 21:13:50 -07:00
You can write created images to flash drives for installation on other systems,
or manually write them to a drive. To do so:
```bash
2016-04-01 21:21:12 -07:00
# Needs sudo to partition and mkfs devices
sudo imager/image.py --base-url=http://yourhost/ --ca-cert=/path/to/signing/cert.pem --device=/dev/sdx --persistent-percent=50
2016-04-01 21:13:50 -07:00
```
2016-04-06 22:59:57 -07:00
Optional flags:
`--https-ca-cert` specifies a local path to a PEM-encoded certificate to
validate the HTTPS image server cert against. This differs from `--ca-cert`,
which is used to validate the manifest.json signature.
`--https-client-cert` and `--https-client-key` are used together to specify
local paths to a PEM-encoded certificate and key pair that will be provided
to the server over HTTPS. This can be used to limit image availability.