From 6eb74b2f2bd99eef987df61c6ce3ee19261c6e3f Mon Sep 17 00:00:00 2001 From: Justin Cormack Date: Tue, 18 Jul 2017 13:55:52 +0100 Subject: [PATCH] Add support for onshutdown This is a list of images to run on a clean shutdown. Note that you must not rely on these being run at all, as machines may be be powered off or shut down without having time to run these scripts. If you add anything here you should test both in the case where they are run and when they are not. Most systems are likely to be "crash only" and not have any setup here, but you can attempt to deregister cleanly from a network service here, rather than relying on timeouts, for example. Fix https://github.com/linuxkit/linuxkit/issues/1988 Signed-off-by: Justin Cormack --- docs/yaml.md | 13 +++++++++++-- src/moby/build.go | 22 ++++++++++++++++++++++ src/moby/config.go | 14 ++++++++------ src/moby/schema.go | 1 + test/test.yml | 4 ++++ 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/docs/yaml.md b/docs/yaml.md index 396106931..1980e38c3 100644 --- a/docs/yaml.md +++ b/docs/yaml.md @@ -10,8 +10,8 @@ The yaml configuration specifies the components used to build up an image . All are downloaded at build time to create an image. The image is self-contained and immutable, so it can be tested reliably for continuous delivery. -The configuration file is processed in the order `kernel`, `init`, `onboot`, `services`, `files`. -Each section adds file to the root file system. Sections may be omitted. +The configuration file is processed in the order `kernel`, `init`, `onboot`, `onshutdown`, +`services`, `files`. Each section adds files to the root file system. Sections may be omitted. Each container that is specified is allocated a unique `uid` and `gid` that it may use if it wishes to run as an isolated user (or user namespace). Anywhere you specify a `uid` or `gid` @@ -62,6 +62,15 @@ images. They are run sequentially and each must exit before the next one is run. These images can be used to configure one shot settings. See [Image specification](#image-specification) for a list of supported fields. +## `onshutdown` + +This is a list of images to run on a clean shutdown. Note that you must not rely on these +being run at all, as machines may be be powered off or shut down without having time to run +these scripts. If you add anything here you should test both in the case where they are +run and when they are not. Most systems are likely to be "crash only" and not have any setup here, +but you can attempt to deregister cleanly from a network service here, rather than relying +on timeouts, for example. + ## `services` The `services` section is a list of images for long running services which are diff --git a/src/moby/build.go b/src/moby/build.go index 9312733ed..15f0ec04d 100644 --- a/src/moby/build.go +++ b/src/moby/build.go @@ -133,6 +133,10 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error { idMap[image.Name] = id id++ } + for _, image := range m.Onshutdown { + idMap[image.Name] = id + id++ + } for _, image := range m.Services { idMap[image.Name] = id id++ @@ -182,6 +186,24 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error { } } + if len(m.Onshutdown) != 0 { + log.Infof("Add onshutdown containers:") + } + for i, image := range m.Onshutdown { + log.Infof(" Create OCI config for %s", image.Image) + useTrust := enforceContentTrust(image.Image, &m.Trust) + config, err := ConfigToOCI(image, useTrust, idMap) + if err != nil { + return fmt.Errorf("Failed to create config.json for %s: %v", image.Image, err) + } + so := fmt.Sprintf("%03d", i) + path := "containers/onshutdown/" + so + "-" + image.Name + err = ImageBundle(path, image.Image, config, iw, useTrust, pull) + if err != nil { + return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err) + } + } + if len(m.Services) != 0 { log.Infof("Add service containers:") } diff --git a/src/moby/config.go b/src/moby/config.go index be23975d5..1f1caa2a2 100644 --- a/src/moby/config.go +++ b/src/moby/config.go @@ -19,12 +19,13 @@ import ( // Moby is the type of a Moby config file type Moby struct { - Kernel KernelConfig `kernel:"cmdline" json:"kernel,omitempty"` - Init []string `init:"cmdline" json:"init"` - Onboot []Image `yaml:"onboot" json:"onboot"` - Services []Image `yaml:"services" json:"services"` - Trust TrustConfig `yaml:"trust" json:"trust,omitempty"` - Files []File `yaml:"files" json:"files"` + Kernel KernelConfig `kernel:"cmdline" json:"kernel,omitempty"` + Init []string `init:"cmdline" json:"init"` + Onboot []Image `yaml:"onboot" json:"onboot"` + Onshutdown []Image `yaml:"onshutdown" json:"onshutdown"` + Services []Image `yaml:"services" json:"services"` + Trust TrustConfig `yaml:"trust" json:"trust,omitempty"` + Files []File `yaml:"files" json:"files"` } // KernelConfig is the type of the config for a kernel @@ -182,6 +183,7 @@ func AppendConfig(m0, m1 Moby) (Moby, error) { } moby.Init = append(moby.Init, m1.Init...) moby.Onboot = append(moby.Onboot, m1.Onboot...) + moby.Onshutdown = append(moby.Onshutdown, m1.Onshutdown...) moby.Services = append(moby.Services, m1.Services...) moby.Files = append(moby.Files, m1.Files...) moby.Trust.Image = append(moby.Trust.Image, m1.Trust.Image...) diff --git a/src/moby/schema.go b/src/moby/schema.go index 700ba936a..16a81208f 100644 --- a/src/moby/schema.go +++ b/src/moby/schema.go @@ -128,6 +128,7 @@ var schema = string(` "kernel": { "$ref": "#/definitions/kernel" }, "init": { "$ref": "#/definitions/strings" }, "onboot": { "$ref": "#/definitions/images" }, + "onshutdown": { "$ref": "#/definitions/images" }, "services": { "$ref": "#/definitions/images" }, "trust": { "$ref": "#/definitions/trust" }, "files": { "$ref": "#/definitions/files" } diff --git a/test/test.yml b/test/test.yml index fadf86e9f..d2d210f36 100644 --- a/test/test.yml +++ b/test/test.yml @@ -14,6 +14,10 @@ onboot: - name: dhcpcd image: "linuxkit/dhcpcd:7d2f17a0e5d1ef9a75a527821a9ab0d753b22e7e" command: ["/sbin/dhcpcd", "--nobackground", "-f", "/dhcpcd.conf", "-1"] +onshutdown: + - name: shutdown + image: busybox:latest + command: ["/bin/echo", "so long and thanks for all the fish"] services: - name: rngd image: "linuxkit/rngd:b67c3151a52b05db50e6207b40876900f2208d14"