215 lines
9.1 KiB
Go
215 lines
9.1 KiB
Go
// Package spec defines a normalized, JSON-serializable description of a Docker
|
|
// container and everything it needs to be recreated on another host.
|
|
//
|
|
// The spec is deliberately independent of the Docker SDK types: it is produced
|
|
// on the source host, travels over SSH or inside an offline migration package,
|
|
// and is consumed either by the SSH engine or by a generated shell script that
|
|
// only has the docker CLI available.
|
|
package spec
|
|
|
|
// MountKind classifies a data location attached to a container.
|
|
type MountKind string
|
|
|
|
const (
|
|
MountVolume MountKind = "volume" // named volume
|
|
MountAnonymous MountKind = "anonymous" // volume with a generated name
|
|
MountBind MountKind = "bind" // host directory or file
|
|
MountTmpfs MountKind = "tmpfs" // in-memory, never carries data
|
|
)
|
|
|
|
// Mount is one data location attached to a container.
|
|
type Mount struct {
|
|
Kind MountKind `json:"kind"`
|
|
Name string `json:"name,omitempty"` // volume name (volume kind only)
|
|
Source string `json:"source,omitempty"` // host path (bind kind only)
|
|
Destination string `json:"destination"` // path inside the container
|
|
ReadOnly bool `json:"readOnly"`
|
|
Propagation string `json:"propagation,omitempty"`
|
|
TmpfsOpts string `json:"tmpfsOpts,omitempty"`
|
|
|
|
// SizeBytes is a best-effort measurement of the data at this location,
|
|
// used to show progress and to warn about very large transfers. -1 = unknown.
|
|
SizeBytes int64 `json:"sizeBytes"`
|
|
}
|
|
|
|
// HasData reports whether this mount is worth copying. tmpfs never is.
|
|
func (m Mount) HasData() bool { return m.Kind != MountTmpfs }
|
|
|
|
// Volume describes a named volume so it can be recreated with the same driver,
|
|
// options and labels rather than falling back to a plain local volume.
|
|
type Volume struct {
|
|
Name string `json:"name"`
|
|
Driver string `json:"driver"`
|
|
DriverOpts map[string]string `json:"driverOpts,omitempty"`
|
|
Labels map[string]string `json:"labels,omitempty"`
|
|
}
|
|
|
|
// IPAMPool is one subnet definition of a user-defined network.
|
|
type IPAMPool struct {
|
|
Subnet string `json:"subnet,omitempty"`
|
|
IPRange string `json:"ipRange,omitempty"`
|
|
Gateway string `json:"gateway,omitempty"`
|
|
AuxAddress map[string]string `json:"auxAddress,omitempty"`
|
|
}
|
|
|
|
// Network describes a user-defined network to recreate on the target.
|
|
type Network struct {
|
|
Name string `json:"name"`
|
|
Driver string `json:"driver"`
|
|
Scope string `json:"scope,omitempty"`
|
|
EnableIPv6 bool `json:"enableIPv6,omitempty"`
|
|
Internal bool `json:"internal,omitempty"`
|
|
Attachable bool `json:"attachable,omitempty"`
|
|
Ingress bool `json:"ingress,omitempty"`
|
|
IPAMDriver string `json:"ipamDriver,omitempty"`
|
|
IPAMPools []IPAMPool `json:"ipamPools,omitempty"`
|
|
Options map[string]string `json:"options,omitempty"`
|
|
Labels map[string]string `json:"labels,omitempty"`
|
|
}
|
|
|
|
// Endpoint is a container's attachment to one network.
|
|
type Endpoint struct {
|
|
Network string `json:"network"`
|
|
Aliases []string `json:"aliases,omitempty"`
|
|
IPv4Address string `json:"ipv4Address,omitempty"`
|
|
IPv6Address string `json:"ipv6Address,omitempty"`
|
|
MacAddress string `json:"macAddress,omitempty"`
|
|
Links []string `json:"links,omitempty"`
|
|
DriverOpts map[string]string `json:"driverOpts,omitempty"`
|
|
}
|
|
|
|
// PortBinding maps a container port onto the host.
|
|
type PortBinding struct {
|
|
ContainerPort string `json:"containerPort"` // e.g. "80/tcp"
|
|
HostIP string `json:"hostIp,omitempty"`
|
|
HostPort string `json:"hostPort,omitempty"`
|
|
}
|
|
|
|
// Healthcheck mirrors the container health configuration when it was
|
|
// overridden at run time (an image-provided healthcheck is not re-emitted).
|
|
type Healthcheck struct {
|
|
Test []string `json:"test,omitempty"`
|
|
Interval int64 `json:"interval,omitempty"` // nanoseconds
|
|
Timeout int64 `json:"timeout,omitempty"` // nanoseconds
|
|
StartPeriod int64 `json:"startPeriod,omitempty"` // nanoseconds
|
|
Retries int `json:"retries,omitempty"`
|
|
}
|
|
|
|
// Resources holds the cgroup limits applied to the container.
|
|
type Resources struct {
|
|
Memory int64 `json:"memory,omitempty"`
|
|
MemoryReservation int64 `json:"memoryReservation,omitempty"`
|
|
MemorySwap int64 `json:"memorySwap,omitempty"`
|
|
MemorySwappiness *int64 `json:"memorySwappiness,omitempty"`
|
|
NanoCPUs int64 `json:"nanoCpus,omitempty"`
|
|
CPUShares int64 `json:"cpuShares,omitempty"`
|
|
CPUPeriod int64 `json:"cpuPeriod,omitempty"`
|
|
CPUQuota int64 `json:"cpuQuota,omitempty"`
|
|
CpusetCpus string `json:"cpusetCpus,omitempty"`
|
|
CpusetMems string `json:"cpusetMems,omitempty"`
|
|
PidsLimit *int64 `json:"pidsLimit,omitempty"`
|
|
OomKillDisable *bool `json:"oomKillDisable,omitempty"`
|
|
OomScoreAdj int `json:"oomScoreAdj,omitempty"`
|
|
ShmSize int64 `json:"shmSize,omitempty"`
|
|
}
|
|
|
|
// Ulimit is a per-container resource limit.
|
|
type Ulimit struct {
|
|
Name string `json:"name"`
|
|
Soft int64 `json:"soft"`
|
|
Hard int64 `json:"hard"`
|
|
}
|
|
|
|
// Device is a host device exposed to the container.
|
|
type Device struct {
|
|
PathOnHost string `json:"pathOnHost"`
|
|
PathInContainer string `json:"pathInContainer"`
|
|
CgroupPermissions string `json:"cgroupPermissions"`
|
|
}
|
|
|
|
// Container is the full normalized description of one container.
|
|
type Container struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"` // without the leading slash
|
|
State string `json:"state"` // running, exited, ...
|
|
|
|
Image string `json:"image"` // reference as the user wrote it, e.g. nginx:1.27
|
|
ImageID string `json:"imageId"` // sha256:...
|
|
ImageDigest string `json:"imageDigest,omitempty"`
|
|
|
|
// Compose grouping, taken from the standard compose labels. Empty when the
|
|
// container was not created by docker compose.
|
|
ComposeProject string `json:"composeProject,omitempty"`
|
|
ComposeService string `json:"composeService,omitempty"`
|
|
|
|
Hostname string `json:"hostname,omitempty"`
|
|
Domainname string `json:"domainname,omitempty"`
|
|
User string `json:"user,omitempty"`
|
|
WorkingDir string `json:"workingDir,omitempty"`
|
|
Env []string `json:"env,omitempty"`
|
|
Labels map[string]string `json:"labels,omitempty"`
|
|
Cmd []string `json:"cmd,omitempty"`
|
|
Entrypoint []string `json:"entrypoint,omitempty"`
|
|
EntrypointSet bool `json:"entrypointSet,omitempty"` // true when overridden at run time
|
|
CmdSet bool `json:"cmdSet,omitempty"`
|
|
Tty bool `json:"tty,omitempty"`
|
|
OpenStdin bool `json:"openStdin,omitempty"`
|
|
StopSignal string `json:"stopSignal,omitempty"`
|
|
StopTimeout *int `json:"stopTimeout,omitempty"`
|
|
Init *bool `json:"init,omitempty"`
|
|
|
|
RestartPolicy string `json:"restartPolicy,omitempty"`
|
|
RestartMaxRetries int `json:"restartMaxRetries,omitempty"`
|
|
AutoRemove bool `json:"autoRemove,omitempty"`
|
|
|
|
Privileged bool `json:"privileged,omitempty"`
|
|
ReadonlyRootfs bool `json:"readonlyRootfs,omitempty"`
|
|
CapAdd []string `json:"capAdd,omitempty"`
|
|
CapDrop []string `json:"capDrop,omitempty"`
|
|
SecurityOpt []string `json:"securityOpt,omitempty"`
|
|
GroupAdd []string `json:"groupAdd,omitempty"`
|
|
Sysctls map[string]string `json:"sysctls,omitempty"`
|
|
Devices []Device `json:"devices,omitempty"`
|
|
Ulimits []Ulimit `json:"ulimits,omitempty"`
|
|
Runtime string `json:"runtime,omitempty"`
|
|
|
|
PidMode string `json:"pidMode,omitempty"`
|
|
IpcMode string `json:"ipcMode,omitempty"`
|
|
UtsMode string `json:"utsMode,omitempty"`
|
|
UsernsMode string `json:"usernsMode,omitempty"`
|
|
CgroupnsMode string `json:"cgroupnsMode,omitempty"`
|
|
|
|
DNS []string `json:"dns,omitempty"`
|
|
DNSSearch []string `json:"dnsSearch,omitempty"`
|
|
DNSOptions []string `json:"dnsOptions,omitempty"`
|
|
ExtraHosts []string `json:"extraHosts,omitempty"`
|
|
|
|
NetworkMode string `json:"networkMode,omitempty"` // bridge, host, none, <name>, container:<id>
|
|
Endpoints []Endpoint `json:"endpoints,omitempty"`
|
|
Ports []PortBinding `json:"ports,omitempty"`
|
|
ExposedPorts []string `json:"exposedPorts,omitempty"`
|
|
PublishAll bool `json:"publishAll,omitempty"`
|
|
|
|
Mounts []Mount `json:"mounts,omitempty"`
|
|
|
|
LogDriver string `json:"logDriver,omitempty"`
|
|
LogOptions map[string]string `json:"logOptions,omitempty"`
|
|
|
|
Healthcheck *Healthcheck `json:"healthcheck,omitempty"`
|
|
Resources Resources `json:"resources"`
|
|
|
|
// Warnings collected while reading the container, surfaced in the UI.
|
|
Warnings []string `json:"warnings,omitempty"`
|
|
}
|
|
|
|
// DataMounts returns the mounts that actually carry data.
|
|
func (c *Container) DataMounts() []Mount {
|
|
out := make([]Mount, 0, len(c.Mounts))
|
|
for _, m := range c.Mounts {
|
|
if m.HasData() {
|
|
out = append(out, m)
|
|
}
|
|
}
|
|
return out
|
|
}
|