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 <justin.cormack@docker.com>
This commit is contained in:
Justin Cormack 2017-07-18 13:55:52 +01:00
parent 43bd663816
commit 6eb74b2f2b
5 changed files with 46 additions and 8 deletions

View File

@ -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

View File

@ -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:")
}

View File

@ -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...)

View File

@ -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" }

View File

@ -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"