sled - System Loader for Ephemeral Devices
Sled is a system software loader designed to run in the u-root initramfs.
Sled is designed to support loading systems onto devices that are ephemeral, generally with
a limited lifetime, and the need to reprovision the device often.
The sled software consists of a client (sledc), server (sledd), API, and controller (sledctl).
The goal of sled is to allow large environments of dynamic devices to be quickly provisioned
based on a centralized controller.
sledc
The sled client supports the following functionalities:
- device wiping (clean state)
- device writing (filesystem, kernel, initramfs)
- device loading (via kexec - into new kernel, initramfs, filesystem)
The process for a client imaging itself is as follows:
- client dhcps for an IP address (cmds/init/*/init/main.go)
-- It is assumed that the dhcp lease will provide all necessary options,
current sled supports: 5,6,15,66,67,119
- client sends a sledd gRPC request out on all interfaces to the destination
sled-server
-- This can be overwritten in cmds/init/*/init/main.go
with the sledc -server
option
- server requests from api (to database) the sled response based on mac address
- server responds to client with the tasks to complete.
- client starts with wipe requests, then write requests, and finally, kexec
-- It is required that a write and kexec request are bundled
More info on requests:
CommandRequests
sledd
Sledd issues commands to clients. Commands are issued to clients as a set.
A set of commands can consist of any one of the following.
- wipe(device [string])
- write(image, kernel, initramfs, device [string])
- kexec(kernel, initrd, kernel-append-cmdline [string])
Sledd is the middleman in the sled protocol.
It is responsible for responding to client requests, requesting the data from the API/database,
then serving the data (stored locally) to the client.
Images are stored at the /var/img
prefix on the sledd service.
More info on the set of commands (CommandSet):
CommandSet
Example CommandSet:
cs := &sled.CommandSet{
Wipe: &sled.Wipe{
Device: "sda",
},
Write: &sled.Write{
ImageName: "ubuntu18.04", // as stored in etcd
Device: "sda",
KernelName: "linux-4.17", // as stored in etcd
InitrdName: "initrd-4.17", // as stored in etcd
},
Kexec: &sled.Kexec{
Append: fmt.Sprintf("root=/dev/sda1 rootfstype=ext4 rw"),
Kernel: "/tmp/kernel",
Initrd: "/tmp/initrd",
},
}
Building a custom sledc
git submodule update --init --recursive
The base of sled is built off of u-root.
If you would like to add additional linux commands you can do so in the
Makefile.
If you would like to modify the linux kernel version, you can do so with the
build kernel script.
Many auxiliary scripts can be found in the utils directory. Currently we pull linux 4.19.20
.
If you would like to add new modules, you can use the build_kernel.sh
above, but modify the
kernel configuration files in kconfig
before building the new kernel.
For specific environments the cmds/init/*/init/main.go
is a good place to start, which defines
the init script.
If you have any questions, please feel free to ask or put in an issue.
Testing
We currently have a minimal testing environment which supports unit and integration tests.
These tests have minimal coverage. Additional information on integration tests can be found
in the test/integration
directory.
Currently, we use the raven framework for integration tests.
Tests:
- dogfood (uses kernel & initram build by make)
Please create a github issue or PR request!