mirror of https://github.com/containers/podman.git
podmanv2 container inspect
add ability to inspect a container Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
parent
6a46a87d08
commit
2fa78938a9
|
@ -1,8 +1,15 @@
|
||||||
package containers
|
package containers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/containers/libpod/cmd/podmanV2/registry"
|
"github.com/containers/libpod/cmd/podmanV2/registry"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -12,31 +19,57 @@ var (
|
||||||
Use: "inspect [flags] CONTAINER",
|
Use: "inspect [flags] CONTAINER",
|
||||||
Short: "Display the configuration of a container",
|
Short: "Display the configuration of a container",
|
||||||
Long: `Displays the low-level information on a container identified by name or ID.`,
|
Long: `Displays the low-level information on a container identified by name or ID.`,
|
||||||
PreRunE: inspectPreRunE,
|
PreRunE: preRunE,
|
||||||
RunE: inspect,
|
RunE: inspect,
|
||||||
Example: `podman container inspect myCtr
|
Example: `podman container inspect myCtr
|
||||||
podman container inspect -l --format '{{.Id}} {{.Config.Labels}}'`,
|
podman container inspect -l --format '{{.Id}} {{.Config.Labels}}'`,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
inspectOptions entities.ContainerInspectOptions
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registry.Commands = append(registry.Commands, registry.CliCommand{
|
registry.Commands = append(registry.Commands, registry.CliCommand{
|
||||||
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
|
||||||
Command: inspectCmd,
|
Command: inspectCmd,
|
||||||
Parent: containerCmd,
|
Parent: containerCmd,
|
||||||
})
|
})
|
||||||
|
flags := inspectCmd.Flags()
|
||||||
|
flags.StringVarP(&inspectOptions.Format, "format", "f", "", "Change the output format to a Go template")
|
||||||
|
flags.BoolVarP(&inspectOptions.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
||||||
|
flags.BoolVarP(&inspectOptions.Size, "size", "s", false, "Display total file size")
|
||||||
|
if registry.IsRemote() {
|
||||||
|
_ = flags.MarkHidden("latest")
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspectPreRunE(cmd *cobra.Command, args []string) (err error) {
|
|
||||||
err = preRunE(cmd, args)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = registry.NewImageEngine(cmd, args)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func inspect(cmd *cobra.Command, args []string) error {
|
func inspect(cmd *cobra.Command, args []string) error {
|
||||||
|
responses, err := registry.ContainerEngine().ContainerInspect(context.Background(), args, inspectOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if inspectOptions.Format == "" {
|
||||||
|
b, err := jsoniter.MarshalIndent(responses, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(b))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
format := inspectOptions.Format
|
||||||
|
if !strings.HasSuffix(format, "\n") {
|
||||||
|
format += "\n"
|
||||||
|
}
|
||||||
|
tmpl, err := template.New("inspect").Parse(format)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, i := range responses {
|
||||||
|
if err := tmpl.Execute(os.Stdout, i); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,10 @@ package libpod
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/containers/image/v5/manifest"
|
|
||||||
"github.com/containers/libpod/libpod/define"
|
"github.com/containers/libpod/libpod/define"
|
||||||
"github.com/containers/libpod/libpod/driver"
|
"github.com/containers/libpod/libpod/driver"
|
||||||
"github.com/containers/libpod/pkg/util"
|
"github.com/containers/libpod/pkg/util"
|
||||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/opencontainers/runtime-tools/generate"
|
"github.com/opencontainers/runtime-tools/generate"
|
||||||
"github.com/opencontainers/runtime-tools/validate"
|
"github.com/opencontainers/runtime-tools/validate"
|
||||||
|
@ -85,602 +82,9 @@ const (
|
||||||
InspectResponseFalse = "FALSE"
|
InspectResponseFalse = "FALSE"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InspectContainerData provides a detailed record of a container's configuration
|
|
||||||
// and state as viewed by Libpod.
|
|
||||||
// Large portions of this structure are defined such that the output is
|
|
||||||
// compatible with `docker inspect` JSON, but additional fields have been added
|
|
||||||
// as required to share information not in the original output.
|
|
||||||
type InspectContainerData struct {
|
|
||||||
ID string `json:"Id"`
|
|
||||||
Created time.Time `json:"Created"`
|
|
||||||
Path string `json:"Path"`
|
|
||||||
Args []string `json:"Args"`
|
|
||||||
State *InspectContainerState `json:"State"`
|
|
||||||
Image string `json:"Image"`
|
|
||||||
ImageName string `json:"ImageName"`
|
|
||||||
Rootfs string `json:"Rootfs"`
|
|
||||||
Pod string `json:"Pod"`
|
|
||||||
ResolvConfPath string `json:"ResolvConfPath"`
|
|
||||||
HostnamePath string `json:"HostnamePath"`
|
|
||||||
HostsPath string `json:"HostsPath"`
|
|
||||||
StaticDir string `json:"StaticDir"`
|
|
||||||
OCIConfigPath string `json:"OCIConfigPath,omitempty"`
|
|
||||||
OCIRuntime string `json:"OCIRuntime,omitempty"`
|
|
||||||
LogPath string `json:"LogPath"`
|
|
||||||
LogTag string `json:"LogTag"`
|
|
||||||
ConmonPidFile string `json:"ConmonPidFile"`
|
|
||||||
Name string `json:"Name"`
|
|
||||||
RestartCount int32 `json:"RestartCount"`
|
|
||||||
Driver string `json:"Driver"`
|
|
||||||
MountLabel string `json:"MountLabel"`
|
|
||||||
ProcessLabel string `json:"ProcessLabel"`
|
|
||||||
AppArmorProfile string `json:"AppArmorProfile"`
|
|
||||||
EffectiveCaps []string `json:"EffectiveCaps"`
|
|
||||||
BoundingCaps []string `json:"BoundingCaps"`
|
|
||||||
ExecIDs []string `json:"ExecIDs"`
|
|
||||||
GraphDriver *driver.Data `json:"GraphDriver"`
|
|
||||||
SizeRw *int64 `json:"SizeRw,omitempty"`
|
|
||||||
SizeRootFs int64 `json:"SizeRootFs,omitempty"`
|
|
||||||
Mounts []InspectMount `json:"Mounts"`
|
|
||||||
Dependencies []string `json:"Dependencies"`
|
|
||||||
NetworkSettings *InspectNetworkSettings `json:"NetworkSettings"` //TODO
|
|
||||||
ExitCommand []string `json:"ExitCommand"`
|
|
||||||
Namespace string `json:"Namespace"`
|
|
||||||
IsInfra bool `json:"IsInfra"`
|
|
||||||
Config *InspectContainerConfig `json:"Config"`
|
|
||||||
HostConfig *InspectContainerHostConfig `json:"HostConfig"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectContainerConfig holds further data about how a container was initially
|
|
||||||
// configured.
|
|
||||||
type InspectContainerConfig struct {
|
|
||||||
// Container hostname
|
|
||||||
Hostname string `json:"Hostname"`
|
|
||||||
// Container domain name - unused at present
|
|
||||||
DomainName string `json:"Domainname"`
|
|
||||||
// User the container was launched with
|
|
||||||
User string `json:"User"`
|
|
||||||
// Unused, at present
|
|
||||||
AttachStdin bool `json:"AttachStdin"`
|
|
||||||
// Unused, at present
|
|
||||||
AttachStdout bool `json:"AttachStdout"`
|
|
||||||
// Unused, at present
|
|
||||||
AttachStderr bool `json:"AttachStderr"`
|
|
||||||
// Whether the container creates a TTY
|
|
||||||
Tty bool `json:"Tty"`
|
|
||||||
// Whether the container leaves STDIN open
|
|
||||||
OpenStdin bool `json:"OpenStdin"`
|
|
||||||
// Whether STDIN is only left open once.
|
|
||||||
// Presently not supported by Podman, unused.
|
|
||||||
StdinOnce bool `json:"StdinOnce"`
|
|
||||||
// Container environment variables
|
|
||||||
Env []string `json:"Env"`
|
|
||||||
// Container command
|
|
||||||
Cmd []string `json:"Cmd"`
|
|
||||||
// Container image
|
|
||||||
Image string `json:"Image"`
|
|
||||||
// Unused, at present. I've never seen this field populated.
|
|
||||||
Volumes map[string]struct{} `json:"Volumes"`
|
|
||||||
// Container working directory
|
|
||||||
WorkingDir string `json:"WorkingDir"`
|
|
||||||
// Container entrypoint
|
|
||||||
Entrypoint string `json:"Entrypoint"`
|
|
||||||
// On-build arguments - presently unused. More of Buildah's domain.
|
|
||||||
OnBuild *string `json:"OnBuild"`
|
|
||||||
// Container labels
|
|
||||||
Labels map[string]string `json:"Labels"`
|
|
||||||
// Container annotations
|
|
||||||
Annotations map[string]string `json:"Annotations"`
|
|
||||||
// Container stop signal
|
|
||||||
StopSignal uint `json:"StopSignal"`
|
|
||||||
// Configured healthcheck for the container
|
|
||||||
Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"`
|
|
||||||
// CreateCommand is the full command plus arguments of the process the
|
|
||||||
// container has been created with.
|
|
||||||
CreateCommand []string `json:"CreateCommand,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectContainerHostConfig holds information used when the container was
|
|
||||||
// created.
|
|
||||||
// It's very much a Docker-specific struct, retained (mostly) as-is for
|
|
||||||
// compatibility. We fill individual fields as best as we can, inferring as much
|
|
||||||
// as possible from the spec and container config.
|
|
||||||
// Some things cannot be inferred. These will be populated by spec annotations
|
|
||||||
// (if available).
|
|
||||||
// Field names are fixed for compatibility and cannot be changed.
|
|
||||||
// As such, silence lint warnings about them.
|
|
||||||
//nolint
|
|
||||||
type InspectContainerHostConfig struct {
|
|
||||||
// Binds contains an array of user-added mounts.
|
|
||||||
// Both volume mounts and named volumes are included.
|
|
||||||
// Tmpfs mounts are NOT included.
|
|
||||||
// In 'docker inspect' this is separated into 'Binds' and 'Mounts' based
|
|
||||||
// on how a mount was added. We do not make this distinction and do not
|
|
||||||
// include a Mounts field in inspect.
|
|
||||||
// Format: <src>:<destination>[:<comma-separated options>]
|
|
||||||
Binds []string `json:"Binds"`
|
|
||||||
// ContainerIDFile is a file created during container creation to hold
|
|
||||||
// the ID of the created container.
|
|
||||||
// This is not handled within libpod and is stored in an annotation.
|
|
||||||
ContainerIDFile string `json:"ContainerIDFile"`
|
|
||||||
// LogConfig contains information on the container's logging backend
|
|
||||||
LogConfig *InspectLogConfig `json:"LogConfig"`
|
|
||||||
// NetworkMode is the configuration of the container's network
|
|
||||||
// namespace.
|
|
||||||
// Populated as follows:
|
|
||||||
// default - A network namespace is being created and configured via CNI
|
|
||||||
// none - A network namespace is being created, not configured via CNI
|
|
||||||
// host - No network namespace created
|
|
||||||
// container:<id> - Using another container's network namespace
|
|
||||||
// ns:<path> - A path to a network namespace has been specified
|
|
||||||
NetworkMode string `json:"NetworkMode"`
|
|
||||||
// PortBindings contains the container's port bindings.
|
|
||||||
// It is formatted as map[string][]InspectHostPort.
|
|
||||||
// The string key here is formatted as <integer port number>/<protocol>
|
|
||||||
// and represents the container port. A single container port may be
|
|
||||||
// bound to multiple host ports (on different IPs).
|
|
||||||
PortBindings map[string][]InspectHostPort `json:"PortBindings"`
|
|
||||||
// RestartPolicy contains the container's restart policy.
|
|
||||||
RestartPolicy *InspectRestartPolicy `json:"RestartPolicy"`
|
|
||||||
// AutoRemove is whether the container will be automatically removed on
|
|
||||||
// exiting.
|
|
||||||
// It is not handled directly within libpod and is stored in an
|
|
||||||
// annotation.
|
|
||||||
AutoRemove bool `json:"AutoRemove"`
|
|
||||||
// VolumeDriver is presently unused and is retained for Docker
|
|
||||||
// compatibility.
|
|
||||||
VolumeDriver string `json:"VolumeDriver"`
|
|
||||||
// VolumesFrom is a list of containers which this container uses volumes
|
|
||||||
// from. This is not handled directly within libpod and is stored in an
|
|
||||||
// annotation.
|
|
||||||
// It is formatted as an array of container names and IDs.
|
|
||||||
VolumesFrom []string `json:"VolumesFrom"`
|
|
||||||
// CapAdd is a list of capabilities added to the container.
|
|
||||||
// It is not directly stored by Libpod, and instead computed from the
|
|
||||||
// capabilities listed in the container's spec, compared against a set
|
|
||||||
// of default capabilities.
|
|
||||||
CapAdd []string `json:"CapAdd"`
|
|
||||||
// CapDrop is a list of capabilities removed from the container.
|
|
||||||
// It is not directly stored by libpod, and instead computed from the
|
|
||||||
// capabilities listed in the container's spec, compared against a set
|
|
||||||
// of default capabilities.
|
|
||||||
CapDrop []string `json:"CapDrop"`
|
|
||||||
// Dns is a list of DNS nameservers that will be added to the
|
|
||||||
// container's resolv.conf
|
|
||||||
Dns []string `json:"Dns"`
|
|
||||||
// DnsOptions is a list of DNS options that will be set in the
|
|
||||||
// container's resolv.conf
|
|
||||||
DnsOptions []string `json:"DnsOptions"`
|
|
||||||
// DnsSearch is a list of DNS search domains that will be set in the
|
|
||||||
// container's resolv.conf
|
|
||||||
DnsSearch []string `json:"DnsSearch"`
|
|
||||||
// ExtraHosts contains hosts that will be aded to the container's
|
|
||||||
// /etc/hosts.
|
|
||||||
ExtraHosts []string `json:"ExtraHosts"`
|
|
||||||
// GroupAdd contains groups that the user inside the container will be
|
|
||||||
// added to.
|
|
||||||
GroupAdd []string `json:"GroupAdd"`
|
|
||||||
// IpcMode represents the configuration of the container's IPC
|
|
||||||
// namespace.
|
|
||||||
// Populated as follows:
|
|
||||||
// "" (empty string) - Default, an IPC namespace will be created
|
|
||||||
// host - No IPC namespace created
|
|
||||||
// container:<id> - Using another container's IPC namespace
|
|
||||||
// ns:<path> - A path to an IPC namespace has been specified
|
|
||||||
IpcMode string `json:"IpcMode"`
|
|
||||||
// Cgroup contains the container's cgroup. It is presently not
|
|
||||||
// populated.
|
|
||||||
// TODO.
|
|
||||||
Cgroup string `json:"Cgroup"`
|
|
||||||
// Cgroups contains the container's CGroup mode.
|
|
||||||
// Allowed values are "default" (container is creating CGroups) and
|
|
||||||
// "disabled" (container is not creating CGroups).
|
|
||||||
// This is Libpod-specific and not included in `docker inspect`.
|
|
||||||
Cgroups string `json:"Cgroups"`
|
|
||||||
// Links is unused, and provided purely for Docker compatibility.
|
|
||||||
Links []string `json:"Links"`
|
|
||||||
// OOMScoreAdj is an adjustment that will be made to the container's OOM
|
|
||||||
// score.
|
|
||||||
OomScoreAdj int `json:"OomScoreAdj"`
|
|
||||||
// PidMode represents the configuration of the container's PID
|
|
||||||
// namespace.
|
|
||||||
// Populated as follows:
|
|
||||||
// "" (empty string) - Default, a PID namespace will be created
|
|
||||||
// host - No PID namespace created
|
|
||||||
// container:<id> - Using another container's PID namespace
|
|
||||||
// ns:<path> - A path to a PID namespace has been specified
|
|
||||||
PidMode string `json:"PidMode"`
|
|
||||||
// Privileged indicates whether the container is running with elevated
|
|
||||||
// privileges.
|
|
||||||
// This has a very specific meaning in the Docker sense, so it's very
|
|
||||||
// difficult to decode from the spec and config, and so is stored as an
|
|
||||||
// annotation.
|
|
||||||
Privileged bool `json:"Privileged"`
|
|
||||||
// PublishAllPorts indicates whether image ports are being published.
|
|
||||||
// This is not directly stored in libpod and is saved as an annotation.
|
|
||||||
PublishAllPorts bool `json:"PublishAllPorts"`
|
|
||||||
// ReadonlyRootfs is whether the container will be mounted read-only.
|
|
||||||
ReadonlyRootfs bool `json:"ReadonlyRootfs"`
|
|
||||||
// SecurityOpt is a list of security-related options that are set in the
|
|
||||||
// container.
|
|
||||||
SecurityOpt []string `json:"SecurityOpt"`
|
|
||||||
// Tmpfs is a list of tmpfs filesystems that will be mounted into the
|
|
||||||
// container.
|
|
||||||
// It is a map of destination path to options for the mount.
|
|
||||||
Tmpfs map[string]string `json:"Tmpfs"`
|
|
||||||
// UTSMode represents the configuration of the container's UID
|
|
||||||
// namespace.
|
|
||||||
// Populated as follows:
|
|
||||||
// "" (empty string) - Default, a UTS namespace will be created
|
|
||||||
// host - no UTS namespace created
|
|
||||||
// container:<id> - Using another container's UTS namespace
|
|
||||||
// ns:<path> - A path to a UTS namespace has been specified
|
|
||||||
UTSMode string `json:"UTSMode"`
|
|
||||||
// UsernsMode represents the configuration of the container's user
|
|
||||||
// namespace.
|
|
||||||
// When running rootless, a user namespace is created outside of libpod
|
|
||||||
// to allow some privileged operations. This will not be reflected here.
|
|
||||||
// Populated as follows:
|
|
||||||
// "" (empty string) - No user namespace will be created
|
|
||||||
// private - The container will be run in a user namespace
|
|
||||||
// container:<id> - Using another container's user namespace
|
|
||||||
// ns:<path> - A path to a user namespace has been specified
|
|
||||||
// TODO Rootless has an additional 'keep-id' option, presently not
|
|
||||||
// reflected here.
|
|
||||||
UsernsMode string `json:"UsernsMode"`
|
|
||||||
// ShmSize is the size of the container's SHM device.
|
|
||||||
ShmSize int64 `json:"ShmSize"`
|
|
||||||
// Runtime is provided purely for Docker compatibility.
|
|
||||||
// It is set unconditionally to "oci" as Podman does not presently
|
|
||||||
// support non-OCI runtimes.
|
|
||||||
Runtime string `json:"Runtime"`
|
|
||||||
// ConsoleSize is an array of 2 integers showing the size of the
|
|
||||||
// container's console.
|
|
||||||
// It is only set if the container is creating a terminal.
|
|
||||||
// TODO.
|
|
||||||
ConsoleSize []uint `json:"ConsoleSize"`
|
|
||||||
// Isolation is presently unused and provided solely for Docker
|
|
||||||
// compatibility.
|
|
||||||
Isolation string `json:"Isolation"`
|
|
||||||
// CpuShares indicates the CPU resources allocated to the container.
|
|
||||||
// It is a relative weight in the scheduler for assigning CPU time
|
|
||||||
// versus other CGroups.
|
|
||||||
CpuShares uint64 `json:"CpuShares"`
|
|
||||||
// Memory indicates the memory resources allocated to the container.
|
|
||||||
// This is the limit (in bytes) of RAM the container may use.
|
|
||||||
Memory int64 `json:"Memory"`
|
|
||||||
// NanoCpus indicates number of CPUs allocated to the container.
|
|
||||||
// It is an integer where one full CPU is indicated by 1000000000 (one
|
|
||||||
// billion).
|
|
||||||
// Thus, 2.5 CPUs (fractional portions of CPUs are allowed) would be
|
|
||||||
// 2500000000 (2.5 billion).
|
|
||||||
// In 'docker inspect' this is set exclusively of two further options in
|
|
||||||
// the output (CpuPeriod and CpuQuota) which are both used to implement
|
|
||||||
// this functionality.
|
|
||||||
// We can't distinguish here, so if CpuQuota is set to the default of
|
|
||||||
// 100000, we will set both CpuQuota, CpuPeriod, and NanoCpus. If
|
|
||||||
// CpuQuota is not the default, we will not set NanoCpus.
|
|
||||||
NanoCpus int64 `json:"NanoCpus"`
|
|
||||||
// CgroupParent is the CGroup parent of the container.
|
|
||||||
// Only set if not default.
|
|
||||||
CgroupParent string `json:"CgroupParent"`
|
|
||||||
// BlkioWeight indicates the I/O resources allocated to the container.
|
|
||||||
// It is a relative weight in the scheduler for assigning I/O time
|
|
||||||
// versus other CGroups.
|
|
||||||
BlkioWeight uint16 `json:"BlkioWeight"`
|
|
||||||
// BlkioWeightDevice is an array of I/O resource priorities for
|
|
||||||
// individual device nodes.
|
|
||||||
// Unfortunately, the spec only stores the device's Major/Minor numbers
|
|
||||||
// and not the path, which is used here.
|
|
||||||
// Fortunately, the kernel provides an interface for retrieving the path
|
|
||||||
// of a given node by major:minor at /sys/dev/. However, the exact path
|
|
||||||
// in use may not be what was used in the original CLI invocation -
|
|
||||||
// though it is guaranteed that the device node will be the same, and
|
|
||||||
// using the given path will be functionally identical.
|
|
||||||
BlkioWeightDevice []InspectBlkioWeightDevice `json:"BlkioWeightDevice"`
|
|
||||||
// BlkioDeviceReadBps is an array of I/O throttle parameters for
|
|
||||||
// individual device nodes.
|
|
||||||
// This specifically sets read rate cap in bytes per second for device
|
|
||||||
// nodes.
|
|
||||||
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
|
||||||
// don't guarantee the path will be identical to the original (though
|
|
||||||
// the node will be).
|
|
||||||
BlkioDeviceReadBps []InspectBlkioThrottleDevice `json:"BlkioDeviceReadBps"`
|
|
||||||
// BlkioDeviceWriteBps is an array of I/O throttle parameters for
|
|
||||||
// individual device nodes.
|
|
||||||
// this specifically sets write rate cap in bytes per second for device
|
|
||||||
// nodes.
|
|
||||||
// as with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
|
||||||
// don't guarantee the path will be identical to the original (though
|
|
||||||
// the node will be).
|
|
||||||
BlkioDeviceWriteBps []InspectBlkioThrottleDevice `json:"BlkioDeviceWriteBps"`
|
|
||||||
// BlkioDeviceReadIOps is an array of I/O throttle parameters for
|
|
||||||
// individual device nodes.
|
|
||||||
// This specifically sets the read rate cap in iops per second for
|
|
||||||
// device nodes.
|
|
||||||
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
|
||||||
// don't guarantee the path will be identical to the original (though
|
|
||||||
// the node will be).
|
|
||||||
BlkioDeviceReadIOps []InspectBlkioThrottleDevice `json:"BlkioDeviceReadIOps"`
|
|
||||||
// BlkioDeviceWriteIOps is an array of I/O throttle parameters for
|
|
||||||
// individual device nodes.
|
|
||||||
// This specifically sets the write rate cap in iops per second for
|
|
||||||
// device nodes.
|
|
||||||
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
|
||||||
// don't guarantee the path will be identical to the original (though
|
|
||||||
// the node will be).
|
|
||||||
BlkioDeviceWriteIOps []InspectBlkioThrottleDevice `json:"BlkioDeviceWriteIOps"`
|
|
||||||
// CpuPeriod is the length of a CPU period in microseconds.
|
|
||||||
// It relates directly to CpuQuota.
|
|
||||||
CpuPeriod uint64 `json:"CpuPeriod"`
|
|
||||||
// CpuPeriod is the amount of time (in microseconds) that a container
|
|
||||||
// can use the CPU in every CpuPeriod.
|
|
||||||
CpuQuota int64 `json:"CpuQuota"`
|
|
||||||
// CpuRealtimePeriod is the length of time (in microseconds) of the CPU
|
|
||||||
// realtime period. If set to 0, no time will be allocated to realtime
|
|
||||||
// tasks.
|
|
||||||
CpuRealtimePeriod uint64 `json:"CpuRealtimePeriod"`
|
|
||||||
// CpuRealtimeRuntime is the length of time (in microseconds) allocated
|
|
||||||
// for realtime tasks within every CpuRealtimePeriod.
|
|
||||||
CpuRealtimeRuntime int64 `json:"CpuRealtimeRuntime"`
|
|
||||||
// CpusetCpus is the is the set of CPUs that the container will execute
|
|
||||||
// on. Formatted as `0-3` or `0,2`. Default (if unset) is all CPUs.
|
|
||||||
CpusetCpus string `json:"CpusetCpus"`
|
|
||||||
// CpusetMems is the set of memory nodes the container will use.
|
|
||||||
// Formatted as `0-3` or `0,2`. Default (if unset) is all memory nodes.
|
|
||||||
CpusetMems string `json:"CpusetMems"`
|
|
||||||
// Devices is a list of device nodes that will be added to the
|
|
||||||
// container.
|
|
||||||
// These are stored in the OCI spec only as type, major, minor while we
|
|
||||||
// display the host path. We convert this with /sys/dev, but we cannot
|
|
||||||
// guarantee that the host path will be identical - only that the actual
|
|
||||||
// device will be.
|
|
||||||
Devices []InspectDevice `json:"Devices"`
|
|
||||||
// DiskQuota is the maximum amount of disk space the container may use
|
|
||||||
// (in bytes).
|
|
||||||
// Presently not populated.
|
|
||||||
// TODO.
|
|
||||||
DiskQuota uint64 `json:"DiskQuota"`
|
|
||||||
// KernelMemory is the maximum amount of memory the kernel will devote
|
|
||||||
// to the container.
|
|
||||||
KernelMemory int64 `json:"KernelMemory"`
|
|
||||||
// MemoryReservation is the reservation (soft limit) of memory available
|
|
||||||
// to the container. Soft limits are warnings only and can be exceeded.
|
|
||||||
MemoryReservation int64 `json:"MemoryReservation"`
|
|
||||||
// MemorySwap is the total limit for all memory available to the
|
|
||||||
// container, including swap. 0 indicates that there is no limit to the
|
|
||||||
// amount of memory available.
|
|
||||||
MemorySwap int64 `json:"MemorySwap"`
|
|
||||||
// MemorySwappiness is the willingness of the kernel to page container
|
|
||||||
// memory to swap. It is an integer from 0 to 100, with low numbers
|
|
||||||
// being more likely to be put into swap.
|
|
||||||
// -1, the default, will not set swappiness and use the system defaults.
|
|
||||||
MemorySwappiness int64 `json:"MemorySwappiness"`
|
|
||||||
// OomKillDisable indicates whether the kernel OOM killer is disabled
|
|
||||||
// for the container.
|
|
||||||
OomKillDisable bool `json:"OomKillDisable"`
|
|
||||||
// Init indicates whether the container has an init mounted into it.
|
|
||||||
Init bool `json:"Init,omitempty"`
|
|
||||||
// PidsLimit is the maximum number of PIDs what may be created within
|
|
||||||
// the container. 0, the default, indicates no limit.
|
|
||||||
PidsLimit int64 `json:"PidsLimit"`
|
|
||||||
// Ulimits is a set of ulimits that will be set within the container.
|
|
||||||
Ulimits []InspectUlimit `json:"Ulimits"`
|
|
||||||
// CpuCount is Windows-only and not presently implemented.
|
|
||||||
CpuCount uint64 `json:"CpuCount"`
|
|
||||||
// CpuPercent is Windows-only and not presently implemented.
|
|
||||||
CpuPercent uint64 `json:"CpuPercent"`
|
|
||||||
// IOMaximumIOps is Windows-only and not presently implemented.
|
|
||||||
IOMaximumIOps uint64 `json:"IOMaximumIOps"`
|
|
||||||
// IOMaximumBandwidth is Windows-only and not presently implemented.
|
|
||||||
IOMaximumBandwidth uint64 `json:"IOMaximumBandwidth"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectLogConfig holds information about a container's configured log driver
|
|
||||||
// and is presently unused. It is retained for Docker compatibility.
|
|
||||||
type InspectLogConfig struct {
|
|
||||||
Type string `json:"Type"`
|
|
||||||
Config map[string]string `json:"Config"` //idk type, TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectRestartPolicy holds information about the container's restart policy.
|
|
||||||
type InspectRestartPolicy struct {
|
|
||||||
// Name contains the container's restart policy.
|
|
||||||
// Allowable values are "no" or "" (take no action),
|
|
||||||
// "on-failure" (restart on non-zero exit code, with an optional max
|
|
||||||
// retry count), and "always" (always restart on container stop, unless
|
|
||||||
// explicitly requested by API).
|
|
||||||
// Note that this is NOT actually a name of any sort - the poor naming
|
|
||||||
// is for Docker compatibility.
|
|
||||||
Name string `json:"Name"`
|
|
||||||
// MaximumRetryCount is the maximum number of retries allowed if the
|
|
||||||
// "on-failure" restart policy is in use. Not used if "on-failure" is
|
|
||||||
// not set.
|
|
||||||
MaximumRetryCount uint `json:"MaximumRetryCount"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectBlkioWeightDevice holds information about the relative weight
|
|
||||||
// of an individual device node. Weights are used in the I/O scheduler to give
|
|
||||||
// relative priority to some accesses.
|
|
||||||
type InspectBlkioWeightDevice struct {
|
|
||||||
// Path is the path to the device this applies to.
|
|
||||||
Path string `json:"Path"`
|
|
||||||
// Weight is the relative weight the scheduler will use when scheduling
|
|
||||||
// I/O.
|
|
||||||
Weight uint16 `json:"Weight"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectBlkioThrottleDevice holds information about a speed cap for a device
|
|
||||||
// node. This cap applies to a specific operation (read, write, etc) on the given
|
|
||||||
// node.
|
|
||||||
type InspectBlkioThrottleDevice struct {
|
|
||||||
// Path is the path to the device this applies to.
|
|
||||||
Path string `json:"Path"`
|
|
||||||
// Rate is the maximum rate. It is in either bytes per second or iops
|
|
||||||
// per second, determined by where it is used - documentation will
|
|
||||||
// indicate which is appropriate.
|
|
||||||
Rate uint64 `json:"Rate"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectUlimit is a ulimit that will be applied to the container.
|
|
||||||
type InspectUlimit struct {
|
|
||||||
// Name is the name (type) of the ulimit.
|
|
||||||
Name string `json:"Name"`
|
|
||||||
// Soft is the soft limit that will be applied.
|
|
||||||
Soft uint64 `json:"Soft"`
|
|
||||||
// Hard is the hard limit that will be applied.
|
|
||||||
Hard uint64 `json:"Hard"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectMount provides a record of a single mount in a container. It contains
|
|
||||||
// fields for both named and normal volumes. Only user-specified volumes will be
|
|
||||||
// included, and tmpfs volumes are not included even if the user specified them.
|
|
||||||
type InspectMount struct {
|
|
||||||
// Whether the mount is a volume or bind mount. Allowed values are
|
|
||||||
// "volume" and "bind".
|
|
||||||
Type string `json:"Type"`
|
|
||||||
// The name of the volume. Empty for bind mounts.
|
|
||||||
Name string `json:"Name,omptempty"`
|
|
||||||
// The source directory for the volume.
|
|
||||||
Source string `json:"Source"`
|
|
||||||
// The destination directory for the volume. Specified as a path within
|
|
||||||
// the container, as it would be passed into the OCI runtime.
|
|
||||||
Destination string `json:"Destination"`
|
|
||||||
// The driver used for the named volume. Empty for bind mounts.
|
|
||||||
Driver string `json:"Driver"`
|
|
||||||
// Contains SELinux :z/:Z mount options. Unclear what, if anything, else
|
|
||||||
// goes in here.
|
|
||||||
Mode string `json:"Mode"`
|
|
||||||
// All remaining mount options. Additional data, not present in the
|
|
||||||
// original output.
|
|
||||||
Options []string `json:"Options"`
|
|
||||||
// Whether the volume is read-write
|
|
||||||
RW bool `json:"RW"`
|
|
||||||
// Mount propagation for the mount. Can be empty if not specified, but
|
|
||||||
// is always printed - no omitempty.
|
|
||||||
Propagation string `json:"Propagation"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectDevice is a single device that will be mounted into the container.
|
|
||||||
type InspectDevice struct {
|
|
||||||
// PathOnHost is the path of the device on the host.
|
|
||||||
PathOnHost string `json:"PathOnHost"`
|
|
||||||
// PathInContainer is the path of the device within the container.
|
|
||||||
PathInContainer string `json:"PathInContainer"`
|
|
||||||
// CgroupPermissions is the permissions of the mounted device.
|
|
||||||
// Presently not populated.
|
|
||||||
// TODO.
|
|
||||||
CgroupPermissions string `json:"CgroupPermissions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectHostPort provides information on a port on the host that a container's
|
|
||||||
// port is bound to.
|
|
||||||
type InspectHostPort struct {
|
|
||||||
// IP on the host we are bound to. "" if not specified (binding to all
|
|
||||||
// IPs).
|
|
||||||
HostIP string `json:"HostIp"`
|
|
||||||
// Port on the host we are bound to. No special formatting - just an
|
|
||||||
// integer stuffed into a string.
|
|
||||||
HostPort string `json:"HostPort"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectContainerState provides a detailed record of a container's current
|
|
||||||
// state. It is returned as part of InspectContainerData.
|
|
||||||
// As with InspectContainerData, many portions of this struct are matched to
|
|
||||||
// Docker, but here we see more fields that are unused (nonsensical in the
|
|
||||||
// context of Libpod).
|
|
||||||
type InspectContainerState struct {
|
|
||||||
OciVersion string `json:"OciVersion"`
|
|
||||||
Status string `json:"Status"`
|
|
||||||
Running bool `json:"Running"`
|
|
||||||
Paused bool `json:"Paused"`
|
|
||||||
Restarting bool `json:"Restarting"` // TODO
|
|
||||||
OOMKilled bool `json:"OOMKilled"`
|
|
||||||
Dead bool `json:"Dead"`
|
|
||||||
Pid int `json:"Pid"`
|
|
||||||
ConmonPid int `json:"ConmonPid,omitempty"`
|
|
||||||
ExitCode int32 `json:"ExitCode"`
|
|
||||||
Error string `json:"Error"` // TODO
|
|
||||||
StartedAt time.Time `json:"StartedAt"`
|
|
||||||
FinishedAt time.Time `json:"FinishedAt"`
|
|
||||||
Healthcheck HealthCheckResults `json:"Healthcheck,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectBasicNetworkConfig holds basic configuration information (e.g. IP
|
|
||||||
// addresses, MAC address, subnet masks, etc) that are common for all networks
|
|
||||||
// (both additional and main).
|
|
||||||
type InspectBasicNetworkConfig struct {
|
|
||||||
// EndpointID is unused, maintained exclusively for compatibility.
|
|
||||||
EndpointID string `json:"EndpointID"`
|
|
||||||
// Gateway is the IP address of the gateway this network will use.
|
|
||||||
Gateway string `json:"Gateway"`
|
|
||||||
// IPAddress is the IP address for this network.
|
|
||||||
IPAddress string `json:"IPAddress"`
|
|
||||||
// IPPrefixLen is the length of the subnet mask of this network.
|
|
||||||
IPPrefixLen int `json:"IPPrefixLen"`
|
|
||||||
// SecondaryIPAddresses is a list of extra IP Addresses that the
|
|
||||||
// container has been assigned in this network.
|
|
||||||
SecondaryIPAddresses []string `json:"SecondaryIPAddresses,omitempty"`
|
|
||||||
// IPv6Gateway is the IPv6 gateway this network will use.
|
|
||||||
IPv6Gateway string `json:"IPv6Gateway"`
|
|
||||||
// GlobalIPv6Address is the global-scope IPv6 Address for this network.
|
|
||||||
GlobalIPv6Address string `json:"GlobalIPv6Address"`
|
|
||||||
// GlobalIPv6PrefixLen is the length of the subnet mask of this network.
|
|
||||||
GlobalIPv6PrefixLen int `json:"GlobalIPv6PrefixLen"`
|
|
||||||
// SecondaryIPv6Addresses is a list of extra IPv6 Addresses that the
|
|
||||||
// container has been assigned in this networ.
|
|
||||||
SecondaryIPv6Addresses []string `json:"SecondaryIPv6Addresses,omitempty"`
|
|
||||||
// MacAddress is the MAC address for the interface in this network.
|
|
||||||
MacAddress string `json:"MacAddress"`
|
|
||||||
// AdditionalMacAddresses is a set of additional MAC Addresses beyond
|
|
||||||
// the first. CNI may configure more than one interface for a single
|
|
||||||
// network, which can cause this.
|
|
||||||
AdditionalMacAddresses []string `json:"AdditionalMACAddresses,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectNetworkSettings holds information about the network settings of the
|
|
||||||
// container.
|
|
||||||
// Many fields are maintained only for compatibility with `docker inspect` and
|
|
||||||
// are unused within Libpod.
|
|
||||||
type InspectNetworkSettings struct {
|
|
||||||
InspectBasicNetworkConfig
|
|
||||||
|
|
||||||
Bridge string `json:"Bridge"`
|
|
||||||
SandboxID string `json:"SandboxID"`
|
|
||||||
HairpinMode bool `json:"HairpinMode"`
|
|
||||||
LinkLocalIPv6Address string `json:"LinkLocalIPv6Address"`
|
|
||||||
LinkLocalIPv6PrefixLen int `json:"LinkLocalIPv6PrefixLen"`
|
|
||||||
Ports []ocicni.PortMapping `json:"Ports"`
|
|
||||||
SandboxKey string `json:"SandboxKey"`
|
|
||||||
// Networks contains information on non-default CNI networks this
|
|
||||||
// container has joined.
|
|
||||||
// It is a map of network name to network information.
|
|
||||||
Networks map[string]*InspectAdditionalNetwork `json:"Networks,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// InspectAdditionalNetwork holds information about non-default CNI networks the
|
|
||||||
// container has been connected to.
|
|
||||||
// As with InspectNetworkSettings, many fields are unused and maintained only
|
|
||||||
// for compatibility with Docker.
|
|
||||||
type InspectAdditionalNetwork struct {
|
|
||||||
InspectBasicNetworkConfig
|
|
||||||
|
|
||||||
// Name of the network we're connecting to.
|
|
||||||
NetworkID string `json:"NetworkID,omitempty"`
|
|
||||||
// DriverOpts is presently unused and maintained exclusively for
|
|
||||||
// compatibility.
|
|
||||||
DriverOpts map[string]string `json:"DriverOpts"`
|
|
||||||
// IPAMConfig is presently unused and maintained exclusively for
|
|
||||||
// compatibility.
|
|
||||||
IPAMConfig map[string]string `json:"IPAMConfig"`
|
|
||||||
// Links is presently unused and maintained exclusively for
|
|
||||||
// compatibility.
|
|
||||||
Links []string `json:"Links"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// inspectLocked inspects a container for low-level information.
|
// inspectLocked inspects a container for low-level information.
|
||||||
// The caller must held c.lock.
|
// The caller must held c.lock.
|
||||||
func (c *Container) inspectLocked(size bool) (*InspectContainerData, error) {
|
func (c *Container) inspectLocked(size bool) (*define.InspectContainerData, error) {
|
||||||
storeCtr, err := c.runtime.store.Container(c.ID())
|
storeCtr, err := c.runtime.store.Container(c.ID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error getting container from store %q", c.ID())
|
return nil, errors.Wrapf(err, "error getting container from store %q", c.ID())
|
||||||
|
@ -697,7 +101,7 @@ func (c *Container) inspectLocked(size bool) (*InspectContainerData, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspect a container for low-level information
|
// Inspect a container for low-level information
|
||||||
func (c *Container) Inspect(size bool) (*InspectContainerData, error) {
|
func (c *Container) Inspect(size bool) (*define.InspectContainerData, error) {
|
||||||
if !c.batched {
|
if !c.batched {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
@ -710,7 +114,7 @@ func (c *Container) Inspect(size bool) (*InspectContainerData, error) {
|
||||||
return c.inspectLocked(size)
|
return c.inspectLocked(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) (*InspectContainerData, error) {
|
func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) (*define.InspectContainerData, error) {
|
||||||
config := c.config
|
config := c.config
|
||||||
runtimeInfo := c.state
|
runtimeInfo := c.state
|
||||||
ctrSpec, err := c.specFromState()
|
ctrSpec, err := c.specFromState()
|
||||||
|
@ -757,12 +161,12 @@ func (c *Container) getContainerInspectData(size bool, driverData *driver.Data)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data := &InspectContainerData{
|
data := &define.InspectContainerData{
|
||||||
ID: config.ID,
|
ID: config.ID,
|
||||||
Created: config.CreatedTime,
|
Created: config.CreatedTime,
|
||||||
Path: path,
|
Path: path,
|
||||||
Args: args,
|
Args: args,
|
||||||
State: &InspectContainerState{
|
State: &define.InspectContainerState{
|
||||||
OciVersion: ctrSpec.Version,
|
OciVersion: ctrSpec.Version,
|
||||||
Status: runtimeInfo.State.String(),
|
Status: runtimeInfo.State.String(),
|
||||||
Running: runtimeInfo.State == define.ContainerStateRunning,
|
Running: runtimeInfo.State == define.ContainerStateRunning,
|
||||||
|
@ -857,8 +261,8 @@ func (c *Container) getContainerInspectData(size bool, driverData *driver.Data)
|
||||||
// Get inspect-formatted mounts list.
|
// Get inspect-formatted mounts list.
|
||||||
// Only includes user-specified mounts. Only includes bind mounts and named
|
// Only includes user-specified mounts. Only includes bind mounts and named
|
||||||
// volumes, not tmpfs volumes.
|
// volumes, not tmpfs volumes.
|
||||||
func (c *Container) getInspectMounts(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) ([]InspectMount, error) {
|
func (c *Container) getInspectMounts(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) ([]define.InspectMount, error) {
|
||||||
inspectMounts := []InspectMount{}
|
inspectMounts := []define.InspectMount{}
|
||||||
|
|
||||||
// No mounts, return early
|
// No mounts, return early
|
||||||
if len(c.config.UserVolumes) == 0 {
|
if len(c.config.UserVolumes) == 0 {
|
||||||
|
@ -866,7 +270,7 @@ func (c *Container) getInspectMounts(ctrSpec *spec.Spec, namedVolumes []*Contain
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, volume := range namedVolumes {
|
for _, volume := range namedVolumes {
|
||||||
mountStruct := InspectMount{}
|
mountStruct := define.InspectMount{}
|
||||||
mountStruct.Type = "volume"
|
mountStruct.Type = "volume"
|
||||||
mountStruct.Destination = volume.Dest
|
mountStruct.Destination = volume.Dest
|
||||||
mountStruct.Name = volume.Name
|
mountStruct.Name = volume.Name
|
||||||
|
@ -891,7 +295,7 @@ func (c *Container) getInspectMounts(ctrSpec *spec.Spec, namedVolumes []*Contain
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
mountStruct := InspectMount{}
|
mountStruct := define.InspectMount{}
|
||||||
mountStruct.Type = "bind"
|
mountStruct.Type = "bind"
|
||||||
mountStruct.Source = mount.Source
|
mountStruct.Source = mount.Source
|
||||||
mountStruct.Destination = mount.Destination
|
mountStruct.Destination = mount.Destination
|
||||||
|
@ -906,7 +310,7 @@ func (c *Container) getInspectMounts(ctrSpec *spec.Spec, namedVolumes []*Contain
|
||||||
|
|
||||||
// Parse mount options so we can populate them in the mount structure.
|
// Parse mount options so we can populate them in the mount structure.
|
||||||
// The mount passed in will be modified.
|
// The mount passed in will be modified.
|
||||||
func parseMountOptionsForInspect(options []string, mount *InspectMount) {
|
func parseMountOptionsForInspect(options []string, mount *define.InspectMount) {
|
||||||
isRW := true
|
isRW := true
|
||||||
mountProp := ""
|
mountProp := ""
|
||||||
zZ := ""
|
zZ := ""
|
||||||
|
@ -940,8 +344,8 @@ func parseMountOptionsForInspect(options []string, mount *InspectMount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the InspectContainerConfig struct for the Config field of Inspect.
|
// Generate the InspectContainerConfig struct for the Config field of Inspect.
|
||||||
func (c *Container) generateInspectContainerConfig(spec *spec.Spec) (*InspectContainerConfig, error) {
|
func (c *Container) generateInspectContainerConfig(spec *spec.Spec) (*define.InspectContainerConfig, error) {
|
||||||
ctrConfig := new(InspectContainerConfig)
|
ctrConfig := new(define.InspectContainerConfig)
|
||||||
|
|
||||||
ctrConfig.Hostname = c.Hostname()
|
ctrConfig.Hostname = c.Hostname()
|
||||||
ctrConfig.User = c.config.User
|
ctrConfig.User = c.config.User
|
||||||
|
@ -992,14 +396,14 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) (*InspectCon
|
||||||
|
|
||||||
// Generate the InspectContainerHostConfig struct for the HostConfig field of
|
// Generate the InspectContainerHostConfig struct for the HostConfig field of
|
||||||
// Inspect.
|
// Inspect.
|
||||||
func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) (*InspectContainerHostConfig, error) {
|
func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, namedVolumes []*ContainerNamedVolume, mounts []spec.Mount) (*define.InspectContainerHostConfig, error) {
|
||||||
hostConfig := new(InspectContainerHostConfig)
|
hostConfig := new(define.InspectContainerHostConfig)
|
||||||
|
|
||||||
logConfig := new(InspectLogConfig)
|
logConfig := new(define.InspectLogConfig)
|
||||||
logConfig.Type = c.config.LogDriver
|
logConfig.Type = c.config.LogDriver
|
||||||
hostConfig.LogConfig = logConfig
|
hostConfig.LogConfig = logConfig
|
||||||
|
|
||||||
restartPolicy := new(InspectRestartPolicy)
|
restartPolicy := new(define.InspectRestartPolicy)
|
||||||
restartPolicy.Name = c.config.RestartPolicy
|
restartPolicy.Name = c.config.RestartPolicy
|
||||||
restartPolicy.MaximumRetryCount = c.config.RestartRetries
|
restartPolicy.MaximumRetryCount = c.config.RestartRetries
|
||||||
hostConfig.RestartPolicy = restartPolicy
|
hostConfig.RestartPolicy = restartPolicy
|
||||||
|
@ -1126,7 +530,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
if ctrSpec.Linux.Resources.BlockIO.Weight != nil {
|
if ctrSpec.Linux.Resources.BlockIO.Weight != nil {
|
||||||
hostConfig.BlkioWeight = *ctrSpec.Linux.Resources.BlockIO.Weight
|
hostConfig.BlkioWeight = *ctrSpec.Linux.Resources.BlockIO.Weight
|
||||||
}
|
}
|
||||||
hostConfig.BlkioWeightDevice = []InspectBlkioWeightDevice{}
|
hostConfig.BlkioWeightDevice = []define.InspectBlkioWeightDevice{}
|
||||||
for _, dev := range ctrSpec.Linux.Resources.BlockIO.WeightDevice {
|
for _, dev := range ctrSpec.Linux.Resources.BlockIO.WeightDevice {
|
||||||
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
||||||
// TODO: how do we handle LeafWeight vs
|
// TODO: how do we handle LeafWeight vs
|
||||||
|
@ -1148,14 +552,14 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
logrus.Warnf("Could not locate weight device %s in system devices", key)
|
logrus.Warnf("Could not locate weight device %s in system devices", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
weightDev := InspectBlkioWeightDevice{}
|
weightDev := define.InspectBlkioWeightDevice{}
|
||||||
weightDev.Path = path
|
weightDev.Path = path
|
||||||
weightDev.Weight = *dev.Weight
|
weightDev.Weight = *dev.Weight
|
||||||
hostConfig.BlkioWeightDevice = append(hostConfig.BlkioWeightDevice, weightDev)
|
hostConfig.BlkioWeightDevice = append(hostConfig.BlkioWeightDevice, weightDev)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleThrottleDevice := func(devs []spec.LinuxThrottleDevice) ([]InspectBlkioThrottleDevice, error) {
|
handleThrottleDevice := func(devs []spec.LinuxThrottleDevice) ([]define.InspectBlkioThrottleDevice, error) {
|
||||||
out := []InspectBlkioThrottleDevice{}
|
out := []define.InspectBlkioThrottleDevice{}
|
||||||
for _, dev := range devs {
|
for _, dev := range devs {
|
||||||
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
||||||
if deviceNodes == nil {
|
if deviceNodes == nil {
|
||||||
|
@ -1170,7 +574,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
logrus.Warnf("Could not locate throttle device %s in system devices", key)
|
logrus.Warnf("Could not locate throttle device %s in system devices", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
throttleDev := InspectBlkioThrottleDevice{}
|
throttleDev := define.InspectBlkioThrottleDevice{}
|
||||||
throttleDev.Path = path
|
throttleDev.Path = path
|
||||||
throttleDev.Rate = dev.Rate
|
throttleDev.Rate = dev.Rate
|
||||||
out = append(out, throttleDev)
|
out = append(out, throttleDev)
|
||||||
|
@ -1272,15 +676,15 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
|
|
||||||
// Port bindings.
|
// Port bindings.
|
||||||
// Only populate if we're using CNI to configure the network.
|
// Only populate if we're using CNI to configure the network.
|
||||||
portBindings := make(map[string][]InspectHostPort)
|
portBindings := make(map[string][]define.InspectHostPort)
|
||||||
if c.config.CreateNetNS {
|
if c.config.CreateNetNS {
|
||||||
for _, port := range c.config.PortMappings {
|
for _, port := range c.config.PortMappings {
|
||||||
key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
|
key := fmt.Sprintf("%d/%s", port.ContainerPort, port.Protocol)
|
||||||
hostPorts := portBindings[key]
|
hostPorts := portBindings[key]
|
||||||
if hostPorts == nil {
|
if hostPorts == nil {
|
||||||
hostPorts = []InspectHostPort{}
|
hostPorts = []define.InspectHostPort{}
|
||||||
}
|
}
|
||||||
hostPorts = append(hostPorts, InspectHostPort{
|
hostPorts = append(hostPorts, define.InspectHostPort{
|
||||||
HostIP: port.HostIP,
|
HostIP: port.HostIP,
|
||||||
HostPort: fmt.Sprintf("%d", port.HostPort),
|
HostPort: fmt.Sprintf("%d", port.HostPort),
|
||||||
})
|
})
|
||||||
|
@ -1449,7 +853,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
// Devices
|
// Devices
|
||||||
// Do not include if privileged - assumed that all devices will be
|
// Do not include if privileged - assumed that all devices will be
|
||||||
// included.
|
// included.
|
||||||
hostConfig.Devices = []InspectDevice{}
|
hostConfig.Devices = []define.InspectDevice{}
|
||||||
if ctrSpec.Linux != nil && !hostConfig.Privileged {
|
if ctrSpec.Linux != nil && !hostConfig.Privileged {
|
||||||
for _, dev := range ctrSpec.Linux.Devices {
|
for _, dev := range ctrSpec.Linux.Devices {
|
||||||
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor)
|
||||||
|
@ -1465,7 +869,7 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
logrus.Warnf("Could not locate device %s on host", key)
|
logrus.Warnf("Could not locate device %s on host", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
newDev := InspectDevice{}
|
newDev := define.InspectDevice{}
|
||||||
newDev.PathOnHost = path
|
newDev.PathOnHost = path
|
||||||
newDev.PathInContainer = dev.Path
|
newDev.PathInContainer = dev.Path
|
||||||
hostConfig.Devices = append(hostConfig.Devices, newDev)
|
hostConfig.Devices = append(hostConfig.Devices, newDev)
|
||||||
|
@ -1473,10 +877,10 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ulimits
|
// Ulimits
|
||||||
hostConfig.Ulimits = []InspectUlimit{}
|
hostConfig.Ulimits = []define.InspectUlimit{}
|
||||||
if ctrSpec.Process != nil {
|
if ctrSpec.Process != nil {
|
||||||
for _, limit := range ctrSpec.Process.Rlimits {
|
for _, limit := range ctrSpec.Process.Rlimits {
|
||||||
newLimit := InspectUlimit{}
|
newLimit := define.InspectUlimit{}
|
||||||
newLimit.Name = limit.Type
|
newLimit.Name = limit.Type
|
||||||
newLimit.Soft = limit.Soft
|
newLimit.Soft = limit.Soft
|
||||||
newLimit.Hard = limit.Hard
|
newLimit.Hard = limit.Hard
|
||||||
|
|
|
@ -0,0 +1,624 @@
|
||||||
|
package define
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/containers/image/v5/manifest"
|
||||||
|
"github.com/containers/libpod/libpod/driver"
|
||||||
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InspectContainerConfig holds further data about how a container was initially
|
||||||
|
// configured.
|
||||||
|
type InspectContainerConfig struct {
|
||||||
|
// Container hostname
|
||||||
|
Hostname string `json:"Hostname"`
|
||||||
|
// Container domain name - unused at present
|
||||||
|
DomainName string `json:"Domainname"`
|
||||||
|
// User the container was launched with
|
||||||
|
User string `json:"User"`
|
||||||
|
// Unused, at present
|
||||||
|
AttachStdin bool `json:"AttachStdin"`
|
||||||
|
// Unused, at present
|
||||||
|
AttachStdout bool `json:"AttachStdout"`
|
||||||
|
// Unused, at present
|
||||||
|
AttachStderr bool `json:"AttachStderr"`
|
||||||
|
// Whether the container creates a TTY
|
||||||
|
Tty bool `json:"Tty"`
|
||||||
|
// Whether the container leaves STDIN open
|
||||||
|
OpenStdin bool `json:"OpenStdin"`
|
||||||
|
// Whether STDIN is only left open once.
|
||||||
|
// Presently not supported by Podman, unused.
|
||||||
|
StdinOnce bool `json:"StdinOnce"`
|
||||||
|
// Container environment variables
|
||||||
|
Env []string `json:"Env"`
|
||||||
|
// Container command
|
||||||
|
Cmd []string `json:"Cmd"`
|
||||||
|
// Container image
|
||||||
|
Image string `json:"Image"`
|
||||||
|
// Unused, at present. I've never seen this field populated.
|
||||||
|
Volumes map[string]struct{} `json:"Volumes"`
|
||||||
|
// Container working directory
|
||||||
|
WorkingDir string `json:"WorkingDir"`
|
||||||
|
// Container entrypoint
|
||||||
|
Entrypoint string `json:"Entrypoint"`
|
||||||
|
// On-build arguments - presently unused. More of Buildah's domain.
|
||||||
|
OnBuild *string `json:"OnBuild"`
|
||||||
|
// Container labels
|
||||||
|
Labels map[string]string `json:"Labels"`
|
||||||
|
// Container annotations
|
||||||
|
Annotations map[string]string `json:"Annotations"`
|
||||||
|
// Container stop signal
|
||||||
|
StopSignal uint `json:"StopSignal"`
|
||||||
|
// Configured healthcheck for the container
|
||||||
|
Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"`
|
||||||
|
// CreateCommand is the full command plus arguments of the process the
|
||||||
|
// container has been created with.
|
||||||
|
CreateCommand []string `json:"CreateCommand,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectRestartPolicy holds information about the container's restart policy.
|
||||||
|
type InspectRestartPolicy struct {
|
||||||
|
// Name contains the container's restart policy.
|
||||||
|
// Allowable values are "no" or "" (take no action),
|
||||||
|
// "on-failure" (restart on non-zero exit code, with an optional max
|
||||||
|
// retry count), and "always" (always restart on container stop, unless
|
||||||
|
// explicitly requested by API).
|
||||||
|
// Note that this is NOT actually a name of any sort - the poor naming
|
||||||
|
// is for Docker compatibility.
|
||||||
|
Name string `json:"Name"`
|
||||||
|
// MaximumRetryCount is the maximum number of retries allowed if the
|
||||||
|
// "on-failure" restart policy is in use. Not used if "on-failure" is
|
||||||
|
// not set.
|
||||||
|
MaximumRetryCount uint `json:"MaximumRetryCount"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectLogConfig holds information about a container's configured log driver
|
||||||
|
// and is presently unused. It is retained for Docker compatibility.
|
||||||
|
type InspectLogConfig struct {
|
||||||
|
Type string `json:"Type"`
|
||||||
|
Config map[string]string `json:"Config"` //idk type, TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectBlkioWeightDevice holds information about the relative weight
|
||||||
|
// of an individual device node. Weights are used in the I/O scheduler to give
|
||||||
|
// relative priority to some accesses.
|
||||||
|
type InspectBlkioWeightDevice struct {
|
||||||
|
// Path is the path to the device this applies to.
|
||||||
|
Path string `json:"Path"`
|
||||||
|
// Weight is the relative weight the scheduler will use when scheduling
|
||||||
|
// I/O.
|
||||||
|
Weight uint16 `json:"Weight"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectBlkioThrottleDevice holds information about a speed cap for a device
|
||||||
|
// node. This cap applies to a specific operation (read, write, etc) on the given
|
||||||
|
// node.
|
||||||
|
type InspectBlkioThrottleDevice struct {
|
||||||
|
// Path is the path to the device this applies to.
|
||||||
|
Path string `json:"Path"`
|
||||||
|
// Rate is the maximum rate. It is in either bytes per second or iops
|
||||||
|
// per second, determined by where it is used - documentation will
|
||||||
|
// indicate which is appropriate.
|
||||||
|
Rate uint64 `json:"Rate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectUlimit is a ulimit that will be applied to the container.
|
||||||
|
type InspectUlimit struct {
|
||||||
|
// Name is the name (type) of the ulimit.
|
||||||
|
Name string `json:"Name"`
|
||||||
|
// Soft is the soft limit that will be applied.
|
||||||
|
Soft uint64 `json:"Soft"`
|
||||||
|
// Hard is the hard limit that will be applied.
|
||||||
|
Hard uint64 `json:"Hard"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectDevice is a single device that will be mounted into the container.
|
||||||
|
type InspectDevice struct {
|
||||||
|
// PathOnHost is the path of the device on the host.
|
||||||
|
PathOnHost string `json:"PathOnHost"`
|
||||||
|
// PathInContainer is the path of the device within the container.
|
||||||
|
PathInContainer string `json:"PathInContainer"`
|
||||||
|
// CgroupPermissions is the permissions of the mounted device.
|
||||||
|
// Presently not populated.
|
||||||
|
// TODO.
|
||||||
|
CgroupPermissions string `json:"CgroupPermissions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectHostPort provides information on a port on the host that a container's
|
||||||
|
// port is bound to.
|
||||||
|
type InspectHostPort struct {
|
||||||
|
// IP on the host we are bound to. "" if not specified (binding to all
|
||||||
|
// IPs).
|
||||||
|
HostIP string `json:"HostIp"`
|
||||||
|
// Port on the host we are bound to. No special formatting - just an
|
||||||
|
// integer stuffed into a string.
|
||||||
|
HostPort string `json:"HostPort"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectMount provides a record of a single mount in a container. It contains
|
||||||
|
// fields for both named and normal volumes. Only user-specified volumes will be
|
||||||
|
// included, and tmpfs volumes are not included even if the user specified them.
|
||||||
|
type InspectMount struct {
|
||||||
|
// Whether the mount is a volume or bind mount. Allowed values are
|
||||||
|
// "volume" and "bind".
|
||||||
|
Type string `json:"Type"`
|
||||||
|
// The name of the volume. Empty for bind mounts.
|
||||||
|
Name string `json:"Name,omptempty"`
|
||||||
|
// The source directory for the volume.
|
||||||
|
Source string `json:"Source"`
|
||||||
|
// The destination directory for the volume. Specified as a path within
|
||||||
|
// the container, as it would be passed into the OCI runtime.
|
||||||
|
Destination string `json:"Destination"`
|
||||||
|
// The driver used for the named volume. Empty for bind mounts.
|
||||||
|
Driver string `json:"Driver"`
|
||||||
|
// Contains SELinux :z/:Z mount options. Unclear what, if anything, else
|
||||||
|
// goes in here.
|
||||||
|
Mode string `json:"Mode"`
|
||||||
|
// All remaining mount options. Additional data, not present in the
|
||||||
|
// original output.
|
||||||
|
Options []string `json:"Options"`
|
||||||
|
// Whether the volume is read-write
|
||||||
|
RW bool `json:"RW"`
|
||||||
|
// Mount propagation for the mount. Can be empty if not specified, but
|
||||||
|
// is always printed - no omitempty.
|
||||||
|
Propagation string `json:"Propagation"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectContainerState provides a detailed record of a container's current
|
||||||
|
// state. It is returned as part of InspectContainerData.
|
||||||
|
// As with InspectContainerData, many portions of this struct are matched to
|
||||||
|
// Docker, but here we see more fields that are unused (nonsensical in the
|
||||||
|
// context of Libpod).
|
||||||
|
type InspectContainerState struct {
|
||||||
|
OciVersion string `json:"OciVersion"`
|
||||||
|
Status string `json:"Status"`
|
||||||
|
Running bool `json:"Running"`
|
||||||
|
Paused bool `json:"Paused"`
|
||||||
|
Restarting bool `json:"Restarting"` // TODO
|
||||||
|
OOMKilled bool `json:"OOMKilled"`
|
||||||
|
Dead bool `json:"Dead"`
|
||||||
|
Pid int `json:"Pid"`
|
||||||
|
ConmonPid int `json:"ConmonPid,omitempty"`
|
||||||
|
ExitCode int32 `json:"ExitCode"`
|
||||||
|
Error string `json:"Error"` // TODO
|
||||||
|
StartedAt time.Time `json:"StartedAt"`
|
||||||
|
FinishedAt time.Time `json:"FinishedAt"`
|
||||||
|
Healthcheck HealthCheckResults `json:"Healthcheck,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HealthCheckResults describes the results/logs from a healthcheck
|
||||||
|
type HealthCheckResults struct {
|
||||||
|
// Status healthy or unhealthy
|
||||||
|
Status string `json:"Status"`
|
||||||
|
// FailingStreak is the number of consecutive failed healthchecks
|
||||||
|
FailingStreak int `json:"FailingStreak"`
|
||||||
|
// Log describes healthcheck attempts and results
|
||||||
|
Log []HealthCheckLog `json:"Log"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// HealthCheckLog describes the results of a single healthcheck
|
||||||
|
type HealthCheckLog struct {
|
||||||
|
// Start time as string
|
||||||
|
Start string `json:"Start"`
|
||||||
|
// End time as a string
|
||||||
|
End string `json:"End"`
|
||||||
|
// Exitcode is 0 or 1
|
||||||
|
ExitCode int `json:"ExitCode"`
|
||||||
|
// Output is the stdout/stderr from the healthcheck command
|
||||||
|
Output string `json:"Output"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectContainerHostConfig holds information used when the container was
|
||||||
|
// created.
|
||||||
|
// It's very much a Docker-specific struct, retained (mostly) as-is for
|
||||||
|
// compatibility. We fill individual fields as best as we can, inferring as much
|
||||||
|
// as possible from the spec and container config.
|
||||||
|
// Some things cannot be inferred. These will be populated by spec annotations
|
||||||
|
// (if available).
|
||||||
|
// Field names are fixed for compatibility and cannot be changed.
|
||||||
|
// As such, silence lint warnings about them.
|
||||||
|
//nolint
|
||||||
|
type InspectContainerHostConfig struct {
|
||||||
|
// Binds contains an array of user-added mounts.
|
||||||
|
// Both volume mounts and named volumes are included.
|
||||||
|
// Tmpfs mounts are NOT included.
|
||||||
|
// In 'docker inspect' this is separated into 'Binds' and 'Mounts' based
|
||||||
|
// on how a mount was added. We do not make this distinction and do not
|
||||||
|
// include a Mounts field in inspect.
|
||||||
|
// Format: <src>:<destination>[:<comma-separated options>]
|
||||||
|
Binds []string `json:"Binds"`
|
||||||
|
// ContainerIDFile is a file created during container creation to hold
|
||||||
|
// the ID of the created container.
|
||||||
|
// This is not handled within libpod and is stored in an annotation.
|
||||||
|
ContainerIDFile string `json:"ContainerIDFile"`
|
||||||
|
// LogConfig contains information on the container's logging backend
|
||||||
|
LogConfig *InspectLogConfig `json:"LogConfig"`
|
||||||
|
// NetworkMode is the configuration of the container's network
|
||||||
|
// namespace.
|
||||||
|
// Populated as follows:
|
||||||
|
// default - A network namespace is being created and configured via CNI
|
||||||
|
// none - A network namespace is being created, not configured via CNI
|
||||||
|
// host - No network namespace created
|
||||||
|
// container:<id> - Using another container's network namespace
|
||||||
|
// ns:<path> - A path to a network namespace has been specified
|
||||||
|
NetworkMode string `json:"NetworkMode"`
|
||||||
|
// PortBindings contains the container's port bindings.
|
||||||
|
// It is formatted as map[string][]InspectHostPort.
|
||||||
|
// The string key here is formatted as <integer port number>/<protocol>
|
||||||
|
// and represents the container port. A single container port may be
|
||||||
|
// bound to multiple host ports (on different IPs).
|
||||||
|
PortBindings map[string][]InspectHostPort `json:"PortBindings"`
|
||||||
|
// RestartPolicy contains the container's restart policy.
|
||||||
|
RestartPolicy *InspectRestartPolicy `json:"RestartPolicy"`
|
||||||
|
// AutoRemove is whether the container will be automatically removed on
|
||||||
|
// exiting.
|
||||||
|
// It is not handled directly within libpod and is stored in an
|
||||||
|
// annotation.
|
||||||
|
AutoRemove bool `json:"AutoRemove"`
|
||||||
|
// VolumeDriver is presently unused and is retained for Docker
|
||||||
|
// compatibility.
|
||||||
|
VolumeDriver string `json:"VolumeDriver"`
|
||||||
|
// VolumesFrom is a list of containers which this container uses volumes
|
||||||
|
// from. This is not handled directly within libpod and is stored in an
|
||||||
|
// annotation.
|
||||||
|
// It is formatted as an array of container names and IDs.
|
||||||
|
VolumesFrom []string `json:"VolumesFrom"`
|
||||||
|
// CapAdd is a list of capabilities added to the container.
|
||||||
|
// It is not directly stored by Libpod, and instead computed from the
|
||||||
|
// capabilities listed in the container's spec, compared against a set
|
||||||
|
// of default capabilities.
|
||||||
|
CapAdd []string `json:"CapAdd"`
|
||||||
|
// CapDrop is a list of capabilities removed from the container.
|
||||||
|
// It is not directly stored by libpod, and instead computed from the
|
||||||
|
// capabilities listed in the container's spec, compared against a set
|
||||||
|
// of default capabilities.
|
||||||
|
CapDrop []string `json:"CapDrop"`
|
||||||
|
// Dns is a list of DNS nameservers that will be added to the
|
||||||
|
// container's resolv.conf
|
||||||
|
Dns []string `json:"Dns"`
|
||||||
|
// DnsOptions is a list of DNS options that will be set in the
|
||||||
|
// container's resolv.conf
|
||||||
|
DnsOptions []string `json:"DnsOptions"`
|
||||||
|
// DnsSearch is a list of DNS search domains that will be set in the
|
||||||
|
// container's resolv.conf
|
||||||
|
DnsSearch []string `json:"DnsSearch"`
|
||||||
|
// ExtraHosts contains hosts that will be aded to the container's
|
||||||
|
// /etc/hosts.
|
||||||
|
ExtraHosts []string `json:"ExtraHosts"`
|
||||||
|
// GroupAdd contains groups that the user inside the container will be
|
||||||
|
// added to.
|
||||||
|
GroupAdd []string `json:"GroupAdd"`
|
||||||
|
// IpcMode represents the configuration of the container's IPC
|
||||||
|
// namespace.
|
||||||
|
// Populated as follows:
|
||||||
|
// "" (empty string) - Default, an IPC namespace will be created
|
||||||
|
// host - No IPC namespace created
|
||||||
|
// container:<id> - Using another container's IPC namespace
|
||||||
|
// ns:<path> - A path to an IPC namespace has been specified
|
||||||
|
IpcMode string `json:"IpcMode"`
|
||||||
|
// Cgroup contains the container's cgroup. It is presently not
|
||||||
|
// populated.
|
||||||
|
// TODO.
|
||||||
|
Cgroup string `json:"Cgroup"`
|
||||||
|
// Cgroups contains the container's CGroup mode.
|
||||||
|
// Allowed values are "default" (container is creating CGroups) and
|
||||||
|
// "disabled" (container is not creating CGroups).
|
||||||
|
// This is Libpod-specific and not included in `docker inspect`.
|
||||||
|
Cgroups string `json:"Cgroups"`
|
||||||
|
// Links is unused, and provided purely for Docker compatibility.
|
||||||
|
Links []string `json:"Links"`
|
||||||
|
// OOMScoreAdj is an adjustment that will be made to the container's OOM
|
||||||
|
// score.
|
||||||
|
OomScoreAdj int `json:"OomScoreAdj"`
|
||||||
|
// PidMode represents the configuration of the container's PID
|
||||||
|
// namespace.
|
||||||
|
// Populated as follows:
|
||||||
|
// "" (empty string) - Default, a PID namespace will be created
|
||||||
|
// host - No PID namespace created
|
||||||
|
// container:<id> - Using another container's PID namespace
|
||||||
|
// ns:<path> - A path to a PID namespace has been specified
|
||||||
|
PidMode string `json:"PidMode"`
|
||||||
|
// Privileged indicates whether the container is running with elevated
|
||||||
|
// privileges.
|
||||||
|
// This has a very specific meaning in the Docker sense, so it's very
|
||||||
|
// difficult to decode from the spec and config, and so is stored as an
|
||||||
|
// annotation.
|
||||||
|
Privileged bool `json:"Privileged"`
|
||||||
|
// PublishAllPorts indicates whether image ports are being published.
|
||||||
|
// This is not directly stored in libpod and is saved as an annotation.
|
||||||
|
PublishAllPorts bool `json:"PublishAllPorts"`
|
||||||
|
// ReadonlyRootfs is whether the container will be mounted read-only.
|
||||||
|
ReadonlyRootfs bool `json:"ReadonlyRootfs"`
|
||||||
|
// SecurityOpt is a list of security-related options that are set in the
|
||||||
|
// container.
|
||||||
|
SecurityOpt []string `json:"SecurityOpt"`
|
||||||
|
// Tmpfs is a list of tmpfs filesystems that will be mounted into the
|
||||||
|
// container.
|
||||||
|
// It is a map of destination path to options for the mount.
|
||||||
|
Tmpfs map[string]string `json:"Tmpfs"`
|
||||||
|
// UTSMode represents the configuration of the container's UID
|
||||||
|
// namespace.
|
||||||
|
// Populated as follows:
|
||||||
|
// "" (empty string) - Default, a UTS namespace will be created
|
||||||
|
// host - no UTS namespace created
|
||||||
|
// container:<id> - Using another container's UTS namespace
|
||||||
|
// ns:<path> - A path to a UTS namespace has been specified
|
||||||
|
UTSMode string `json:"UTSMode"`
|
||||||
|
// UsernsMode represents the configuration of the container's user
|
||||||
|
// namespace.
|
||||||
|
// When running rootless, a user namespace is created outside of libpod
|
||||||
|
// to allow some privileged operations. This will not be reflected here.
|
||||||
|
// Populated as follows:
|
||||||
|
// "" (empty string) - No user namespace will be created
|
||||||
|
// private - The container will be run in a user namespace
|
||||||
|
// container:<id> - Using another container's user namespace
|
||||||
|
// ns:<path> - A path to a user namespace has been specified
|
||||||
|
// TODO Rootless has an additional 'keep-id' option, presently not
|
||||||
|
// reflected here.
|
||||||
|
UsernsMode string `json:"UsernsMode"`
|
||||||
|
// ShmSize is the size of the container's SHM device.
|
||||||
|
ShmSize int64 `json:"ShmSize"`
|
||||||
|
// Runtime is provided purely for Docker compatibility.
|
||||||
|
// It is set unconditionally to "oci" as Podman does not presently
|
||||||
|
// support non-OCI runtimes.
|
||||||
|
Runtime string `json:"Runtime"`
|
||||||
|
// ConsoleSize is an array of 2 integers showing the size of the
|
||||||
|
// container's console.
|
||||||
|
// It is only set if the container is creating a terminal.
|
||||||
|
// TODO.
|
||||||
|
ConsoleSize []uint `json:"ConsoleSize"`
|
||||||
|
// Isolation is presently unused and provided solely for Docker
|
||||||
|
// compatibility.
|
||||||
|
Isolation string `json:"Isolation"`
|
||||||
|
// CpuShares indicates the CPU resources allocated to the container.
|
||||||
|
// It is a relative weight in the scheduler for assigning CPU time
|
||||||
|
// versus other CGroups.
|
||||||
|
CpuShares uint64 `json:"CpuShares"`
|
||||||
|
// Memory indicates the memory resources allocated to the container.
|
||||||
|
// This is the limit (in bytes) of RAM the container may use.
|
||||||
|
Memory int64 `json:"Memory"`
|
||||||
|
// NanoCpus indicates number of CPUs allocated to the container.
|
||||||
|
// It is an integer where one full CPU is indicated by 1000000000 (one
|
||||||
|
// billion).
|
||||||
|
// Thus, 2.5 CPUs (fractional portions of CPUs are allowed) would be
|
||||||
|
// 2500000000 (2.5 billion).
|
||||||
|
// In 'docker inspect' this is set exclusively of two further options in
|
||||||
|
// the output (CpuPeriod and CpuQuota) which are both used to implement
|
||||||
|
// this functionality.
|
||||||
|
// We can't distinguish here, so if CpuQuota is set to the default of
|
||||||
|
// 100000, we will set both CpuQuota, CpuPeriod, and NanoCpus. If
|
||||||
|
// CpuQuota is not the default, we will not set NanoCpus.
|
||||||
|
NanoCpus int64 `json:"NanoCpus"`
|
||||||
|
// CgroupParent is the CGroup parent of the container.
|
||||||
|
// Only set if not default.
|
||||||
|
CgroupParent string `json:"CgroupParent"`
|
||||||
|
// BlkioWeight indicates the I/O resources allocated to the container.
|
||||||
|
// It is a relative weight in the scheduler for assigning I/O time
|
||||||
|
// versus other CGroups.
|
||||||
|
BlkioWeight uint16 `json:"BlkioWeight"`
|
||||||
|
// BlkioWeightDevice is an array of I/O resource priorities for
|
||||||
|
// individual device nodes.
|
||||||
|
// Unfortunately, the spec only stores the device's Major/Minor numbers
|
||||||
|
// and not the path, which is used here.
|
||||||
|
// Fortunately, the kernel provides an interface for retrieving the path
|
||||||
|
// of a given node by major:minor at /sys/dev/. However, the exact path
|
||||||
|
// in use may not be what was used in the original CLI invocation -
|
||||||
|
// though it is guaranteed that the device node will be the same, and
|
||||||
|
// using the given path will be functionally identical.
|
||||||
|
BlkioWeightDevice []InspectBlkioWeightDevice `json:"BlkioWeightDevice"`
|
||||||
|
// BlkioDeviceReadBps is an array of I/O throttle parameters for
|
||||||
|
// individual device nodes.
|
||||||
|
// This specifically sets read rate cap in bytes per second for device
|
||||||
|
// nodes.
|
||||||
|
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
||||||
|
// don't guarantee the path will be identical to the original (though
|
||||||
|
// the node will be).
|
||||||
|
BlkioDeviceReadBps []InspectBlkioThrottleDevice `json:"BlkioDeviceReadBps"`
|
||||||
|
// BlkioDeviceWriteBps is an array of I/O throttle parameters for
|
||||||
|
// individual device nodes.
|
||||||
|
// this specifically sets write rate cap in bytes per second for device
|
||||||
|
// nodes.
|
||||||
|
// as with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
||||||
|
// don't guarantee the path will be identical to the original (though
|
||||||
|
// the node will be).
|
||||||
|
BlkioDeviceWriteBps []InspectBlkioThrottleDevice `json:"BlkioDeviceWriteBps"`
|
||||||
|
// BlkioDeviceReadIOps is an array of I/O throttle parameters for
|
||||||
|
// individual device nodes.
|
||||||
|
// This specifically sets the read rate cap in iops per second for
|
||||||
|
// device nodes.
|
||||||
|
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
||||||
|
// don't guarantee the path will be identical to the original (though
|
||||||
|
// the node will be).
|
||||||
|
BlkioDeviceReadIOps []InspectBlkioThrottleDevice `json:"BlkioDeviceReadIOps"`
|
||||||
|
// BlkioDeviceWriteIOps is an array of I/O throttle parameters for
|
||||||
|
// individual device nodes.
|
||||||
|
// This specifically sets the write rate cap in iops per second for
|
||||||
|
// device nodes.
|
||||||
|
// As with BlkioWeightDevice, we pull the path from /sys/dev, and we
|
||||||
|
// don't guarantee the path will be identical to the original (though
|
||||||
|
// the node will be).
|
||||||
|
BlkioDeviceWriteIOps []InspectBlkioThrottleDevice `json:"BlkioDeviceWriteIOps"`
|
||||||
|
// CpuPeriod is the length of a CPU period in microseconds.
|
||||||
|
// It relates directly to CpuQuota.
|
||||||
|
CpuPeriod uint64 `json:"CpuPeriod"`
|
||||||
|
// CpuPeriod is the amount of time (in microseconds) that a container
|
||||||
|
// can use the CPU in every CpuPeriod.
|
||||||
|
CpuQuota int64 `json:"CpuQuota"`
|
||||||
|
// CpuRealtimePeriod is the length of time (in microseconds) of the CPU
|
||||||
|
// realtime period. If set to 0, no time will be allocated to realtime
|
||||||
|
// tasks.
|
||||||
|
CpuRealtimePeriod uint64 `json:"CpuRealtimePeriod"`
|
||||||
|
// CpuRealtimeRuntime is the length of time (in microseconds) allocated
|
||||||
|
// for realtime tasks within every CpuRealtimePeriod.
|
||||||
|
CpuRealtimeRuntime int64 `json:"CpuRealtimeRuntime"`
|
||||||
|
// CpusetCpus is the is the set of CPUs that the container will execute
|
||||||
|
// on. Formatted as `0-3` or `0,2`. Default (if unset) is all CPUs.
|
||||||
|
CpusetCpus string `json:"CpusetCpus"`
|
||||||
|
// CpusetMems is the set of memory nodes the container will use.
|
||||||
|
// Formatted as `0-3` or `0,2`. Default (if unset) is all memory nodes.
|
||||||
|
CpusetMems string `json:"CpusetMems"`
|
||||||
|
// Devices is a list of device nodes that will be added to the
|
||||||
|
// container.
|
||||||
|
// These are stored in the OCI spec only as type, major, minor while we
|
||||||
|
// display the host path. We convert this with /sys/dev, but we cannot
|
||||||
|
// guarantee that the host path will be identical - only that the actual
|
||||||
|
// device will be.
|
||||||
|
Devices []InspectDevice `json:"Devices"`
|
||||||
|
// DiskQuota is the maximum amount of disk space the container may use
|
||||||
|
// (in bytes).
|
||||||
|
// Presently not populated.
|
||||||
|
// TODO.
|
||||||
|
DiskQuota uint64 `json:"DiskQuota"`
|
||||||
|
// KernelMemory is the maximum amount of memory the kernel will devote
|
||||||
|
// to the container.
|
||||||
|
KernelMemory int64 `json:"KernelMemory"`
|
||||||
|
// MemoryReservation is the reservation (soft limit) of memory available
|
||||||
|
// to the container. Soft limits are warnings only and can be exceeded.
|
||||||
|
MemoryReservation int64 `json:"MemoryReservation"`
|
||||||
|
// MemorySwap is the total limit for all memory available to the
|
||||||
|
// container, including swap. 0 indicates that there is no limit to the
|
||||||
|
// amount of memory available.
|
||||||
|
MemorySwap int64 `json:"MemorySwap"`
|
||||||
|
// MemorySwappiness is the willingness of the kernel to page container
|
||||||
|
// memory to swap. It is an integer from 0 to 100, with low numbers
|
||||||
|
// being more likely to be put into swap.
|
||||||
|
// -1, the default, will not set swappiness and use the system defaults.
|
||||||
|
MemorySwappiness int64 `json:"MemorySwappiness"`
|
||||||
|
// OomKillDisable indicates whether the kernel OOM killer is disabled
|
||||||
|
// for the container.
|
||||||
|
OomKillDisable bool `json:"OomKillDisable"`
|
||||||
|
// Init indicates whether the container has an init mounted into it.
|
||||||
|
Init bool `json:"Init,omitempty"`
|
||||||
|
// PidsLimit is the maximum number of PIDs what may be created within
|
||||||
|
// the container. 0, the default, indicates no limit.
|
||||||
|
PidsLimit int64 `json:"PidsLimit"`
|
||||||
|
// Ulimits is a set of ulimits that will be set within the container.
|
||||||
|
Ulimits []InspectUlimit `json:"Ulimits"`
|
||||||
|
// CpuCount is Windows-only and not presently implemented.
|
||||||
|
CpuCount uint64 `json:"CpuCount"`
|
||||||
|
// CpuPercent is Windows-only and not presently implemented.
|
||||||
|
CpuPercent uint64 `json:"CpuPercent"`
|
||||||
|
// IOMaximumIOps is Windows-only and not presently implemented.
|
||||||
|
IOMaximumIOps uint64 `json:"IOMaximumIOps"`
|
||||||
|
// IOMaximumBandwidth is Windows-only and not presently implemented.
|
||||||
|
IOMaximumBandwidth uint64 `json:"IOMaximumBandwidth"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectBasicNetworkConfig holds basic configuration information (e.g. IP
|
||||||
|
// addresses, MAC address, subnet masks, etc) that are common for all networks
|
||||||
|
// (both additional and main).
|
||||||
|
type InspectBasicNetworkConfig struct {
|
||||||
|
// EndpointID is unused, maintained exclusively for compatibility.
|
||||||
|
EndpointID string `json:"EndpointID"`
|
||||||
|
// Gateway is the IP address of the gateway this network will use.
|
||||||
|
Gateway string `json:"Gateway"`
|
||||||
|
// IPAddress is the IP address for this network.
|
||||||
|
IPAddress string `json:"IPAddress"`
|
||||||
|
// IPPrefixLen is the length of the subnet mask of this network.
|
||||||
|
IPPrefixLen int `json:"IPPrefixLen"`
|
||||||
|
// SecondaryIPAddresses is a list of extra IP Addresses that the
|
||||||
|
// container has been assigned in this network.
|
||||||
|
SecondaryIPAddresses []string `json:"SecondaryIPAddresses,omitempty"`
|
||||||
|
// IPv6Gateway is the IPv6 gateway this network will use.
|
||||||
|
IPv6Gateway string `json:"IPv6Gateway"`
|
||||||
|
// GlobalIPv6Address is the global-scope IPv6 Address for this network.
|
||||||
|
GlobalIPv6Address string `json:"GlobalIPv6Address"`
|
||||||
|
// GlobalIPv6PrefixLen is the length of the subnet mask of this network.
|
||||||
|
GlobalIPv6PrefixLen int `json:"GlobalIPv6PrefixLen"`
|
||||||
|
// SecondaryIPv6Addresses is a list of extra IPv6 Addresses that the
|
||||||
|
// container has been assigned in this networ.
|
||||||
|
SecondaryIPv6Addresses []string `json:"SecondaryIPv6Addresses,omitempty"`
|
||||||
|
// MacAddress is the MAC address for the interface in this network.
|
||||||
|
MacAddress string `json:"MacAddress"`
|
||||||
|
// AdditionalMacAddresses is a set of additional MAC Addresses beyond
|
||||||
|
// the first. CNI may configure more than one interface for a single
|
||||||
|
// network, which can cause this.
|
||||||
|
AdditionalMacAddresses []string `json:"AdditionalMACAddresses,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectAdditionalNetwork holds information about non-default CNI networks the
|
||||||
|
// container has been connected to.
|
||||||
|
// As with InspectNetworkSettings, many fields are unused and maintained only
|
||||||
|
// for compatibility with Docker.
|
||||||
|
type InspectAdditionalNetwork struct {
|
||||||
|
InspectBasicNetworkConfig
|
||||||
|
|
||||||
|
// Name of the network we're connecting to.
|
||||||
|
NetworkID string `json:"NetworkID,omitempty"`
|
||||||
|
// DriverOpts is presently unused and maintained exclusively for
|
||||||
|
// compatibility.
|
||||||
|
DriverOpts map[string]string `json:"DriverOpts"`
|
||||||
|
// IPAMConfig is presently unused and maintained exclusively for
|
||||||
|
// compatibility.
|
||||||
|
IPAMConfig map[string]string `json:"IPAMConfig"`
|
||||||
|
// Links is presently unused and maintained exclusively for
|
||||||
|
// compatibility.
|
||||||
|
Links []string `json:"Links"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectNetworkSettings holds information about the network settings of the
|
||||||
|
// container.
|
||||||
|
// Many fields are maintained only for compatibility with `docker inspect` and
|
||||||
|
// are unused within Libpod.
|
||||||
|
type InspectNetworkSettings struct {
|
||||||
|
InspectBasicNetworkConfig
|
||||||
|
|
||||||
|
Bridge string `json:"Bridge"`
|
||||||
|
SandboxID string `json:"SandboxID"`
|
||||||
|
HairpinMode bool `json:"HairpinMode"`
|
||||||
|
LinkLocalIPv6Address string `json:"LinkLocalIPv6Address"`
|
||||||
|
LinkLocalIPv6PrefixLen int `json:"LinkLocalIPv6PrefixLen"`
|
||||||
|
Ports []ocicni.PortMapping `json:"Ports"`
|
||||||
|
SandboxKey string `json:"SandboxKey"`
|
||||||
|
// Networks contains information on non-default CNI networks this
|
||||||
|
// container has joined.
|
||||||
|
// It is a map of network name to network information.
|
||||||
|
Networks map[string]*InspectAdditionalNetwork `json:"Networks,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// InspectContainerData provides a detailed record of a container's configuration
|
||||||
|
// and state as viewed by Libpod.
|
||||||
|
// Large portions of this structure are defined such that the output is
|
||||||
|
// compatible with `docker inspect` JSON, but additional fields have been added
|
||||||
|
// as required to share information not in the original output.
|
||||||
|
type InspectContainerData struct {
|
||||||
|
ID string `json:"Id"`
|
||||||
|
Created time.Time `json:"Created"`
|
||||||
|
Path string `json:"Path"`
|
||||||
|
Args []string `json:"Args"`
|
||||||
|
State *InspectContainerState `json:"State"`
|
||||||
|
Image string `json:"Image"`
|
||||||
|
ImageName string `json:"ImageName"`
|
||||||
|
Rootfs string `json:"Rootfs"`
|
||||||
|
Pod string `json:"Pod"`
|
||||||
|
ResolvConfPath string `json:"ResolvConfPath"`
|
||||||
|
HostnamePath string `json:"HostnamePath"`
|
||||||
|
HostsPath string `json:"HostsPath"`
|
||||||
|
StaticDir string `json:"StaticDir"`
|
||||||
|
OCIConfigPath string `json:"OCIConfigPath,omitempty"`
|
||||||
|
OCIRuntime string `json:"OCIRuntime,omitempty"`
|
||||||
|
LogPath string `json:"LogPath"`
|
||||||
|
LogTag string `json:"LogTag"`
|
||||||
|
ConmonPidFile string `json:"ConmonPidFile"`
|
||||||
|
Name string `json:"Name"`
|
||||||
|
RestartCount int32 `json:"RestartCount"`
|
||||||
|
Driver string `json:"Driver"`
|
||||||
|
MountLabel string `json:"MountLabel"`
|
||||||
|
ProcessLabel string `json:"ProcessLabel"`
|
||||||
|
AppArmorProfile string `json:"AppArmorProfile"`
|
||||||
|
EffectiveCaps []string `json:"EffectiveCaps"`
|
||||||
|
BoundingCaps []string `json:"BoundingCaps"`
|
||||||
|
ExecIDs []string `json:"ExecIDs"`
|
||||||
|
GraphDriver *driver.Data `json:"GraphDriver"`
|
||||||
|
SizeRw *int64 `json:"SizeRw,omitempty"`
|
||||||
|
SizeRootFs int64 `json:"SizeRootFs,omitempty"`
|
||||||
|
Mounts []InspectMount `json:"Mounts"`
|
||||||
|
Dependencies []string `json:"Dependencies"`
|
||||||
|
NetworkSettings *InspectNetworkSettings `json:"NetworkSettings"` //TODO
|
||||||
|
ExitCommand []string `json:"ExitCommand"`
|
||||||
|
Namespace string `json:"Namespace"`
|
||||||
|
IsInfra bool `json:"IsInfra"`
|
||||||
|
Config *InspectContainerConfig `json:"Config"`
|
||||||
|
HostConfig *InspectContainerHostConfig `json:"HostConfig"`
|
||||||
|
}
|
|
@ -53,28 +53,6 @@ const (
|
||||||
HealthCheckStarting string = "starting"
|
HealthCheckStarting string = "starting"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HealthCheckResults describes the results/logs from a healthcheck
|
|
||||||
type HealthCheckResults struct {
|
|
||||||
// Status healthy or unhealthy
|
|
||||||
Status string `json:"Status"`
|
|
||||||
// FailingStreak is the number of consecutive failed healthchecks
|
|
||||||
FailingStreak int `json:"FailingStreak"`
|
|
||||||
// Log describes healthcheck attempts and results
|
|
||||||
Log []HealthCheckLog `json:"Log"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// HealthCheckLog describes the results of a single healthcheck
|
|
||||||
type HealthCheckLog struct {
|
|
||||||
// Start time as string
|
|
||||||
Start string `json:"Start"`
|
|
||||||
// End time as a string
|
|
||||||
End string `json:"End"`
|
|
||||||
// Exitcode is 0 or 1
|
|
||||||
ExitCode int `json:"ExitCode"`
|
|
||||||
// Output is the stdout/stderr from the healthcheck command
|
|
||||||
Output string `json:"Output"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// hcWriteCloser allows us to use bufio as a WriteCloser
|
// hcWriteCloser allows us to use bufio as a WriteCloser
|
||||||
type hcWriteCloser struct {
|
type hcWriteCloser struct {
|
||||||
*bufio.Writer
|
*bufio.Writer
|
||||||
|
@ -200,8 +178,8 @@ func checkHealthCheckCanBeRun(c *Container) (HealthCheckStatus, error) {
|
||||||
return HealthCheckDefined, nil
|
return HealthCheckDefined, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newHealthCheckLog(start, end time.Time, exitCode int, log string) HealthCheckLog {
|
func newHealthCheckLog(start, end time.Time, exitCode int, log string) define.HealthCheckLog {
|
||||||
return HealthCheckLog{
|
return define.HealthCheckLog{
|
||||||
Start: start.Format(time.RFC3339Nano),
|
Start: start.Format(time.RFC3339Nano),
|
||||||
End: end.Format(time.RFC3339Nano),
|
End: end.Format(time.RFC3339Nano),
|
||||||
ExitCode: exitCode,
|
ExitCode: exitCode,
|
||||||
|
@ -225,7 +203,7 @@ func (c *Container) updateHealthStatus(status string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateHealthCheckLog parses the health check results and writes the log
|
// UpdateHealthCheckLog parses the health check results and writes the log
|
||||||
func (c *Container) updateHealthCheckLog(hcl HealthCheckLog, inStartPeriod bool) error {
|
func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPeriod bool) error {
|
||||||
healthCheck, err := c.GetHealthCheckLog()
|
healthCheck, err := c.GetHealthCheckLog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -266,8 +244,8 @@ func (c *Container) healthCheckLogPath() string {
|
||||||
// GetHealthCheckLog returns HealthCheck results by reading the container's
|
// GetHealthCheckLog returns HealthCheck results by reading the container's
|
||||||
// health check log file. If the health check log file does not exist, then
|
// health check log file. If the health check log file does not exist, then
|
||||||
// an empty healthcheck struct is returned
|
// an empty healthcheck struct is returned
|
||||||
func (c *Container) GetHealthCheckLog() (HealthCheckResults, error) {
|
func (c *Container) GetHealthCheckLog() (define.HealthCheckResults, error) {
|
||||||
var healthCheck HealthCheckResults
|
var healthCheck define.HealthCheckResults
|
||||||
if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) {
|
if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) {
|
||||||
return healthCheck, nil
|
return healthCheck, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,8 +573,8 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) {
|
||||||
|
|
||||||
// Produce an InspectNetworkSettings containing information on the container
|
// Produce an InspectNetworkSettings containing information on the container
|
||||||
// network.
|
// network.
|
||||||
func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, error) {
|
||||||
settings := new(InspectNetworkSettings)
|
settings := new(define.InspectNetworkSettings)
|
||||||
settings.Ports = []ocicni.PortMapping{}
|
settings.Ports = []ocicni.PortMapping{}
|
||||||
if c.config.PortMappings != nil {
|
if c.config.PortMappings != nil {
|
||||||
// TODO: This may not be safe.
|
// TODO: This may not be safe.
|
||||||
|
@ -600,13 +600,13 @@ func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
||||||
return nil, errors.Wrapf(define.ErrInternal, "network inspection mismatch: asked to join %d CNI networks but have information on %d networks", len(c.config.Networks), len(c.state.NetworkStatus))
|
return nil, errors.Wrapf(define.ErrInternal, "network inspection mismatch: asked to join %d CNI networks but have information on %d networks", len(c.config.Networks), len(c.state.NetworkStatus))
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Networks = make(map[string]*InspectAdditionalNetwork)
|
settings.Networks = make(map[string]*define.InspectAdditionalNetwork)
|
||||||
|
|
||||||
// CNI results should be in the same order as the list of
|
// CNI results should be in the same order as the list of
|
||||||
// networks we pass into CNI.
|
// networks we pass into CNI.
|
||||||
for index, name := range c.config.Networks {
|
for index, name := range c.config.Networks {
|
||||||
cniResult := c.state.NetworkStatus[index]
|
cniResult := c.state.NetworkStatus[index]
|
||||||
addedNet := new(InspectAdditionalNetwork)
|
addedNet := new(define.InspectAdditionalNetwork)
|
||||||
addedNet.NetworkID = name
|
addedNet.NetworkID = name
|
||||||
|
|
||||||
basicConfig, err := resultToBasicNetworkConfig(cniResult)
|
basicConfig, err := resultToBasicNetworkConfig(cniResult)
|
||||||
|
@ -640,8 +640,8 @@ func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
||||||
|
|
||||||
// resultToBasicNetworkConfig produces an InspectBasicNetworkConfig from a CNI
|
// resultToBasicNetworkConfig produces an InspectBasicNetworkConfig from a CNI
|
||||||
// result
|
// result
|
||||||
func resultToBasicNetworkConfig(result *cnitypes.Result) (InspectBasicNetworkConfig, error) {
|
func resultToBasicNetworkConfig(result *cnitypes.Result) (define.InspectBasicNetworkConfig, error) {
|
||||||
config := InspectBasicNetworkConfig{}
|
config := define.InspectBasicNetworkConfig{}
|
||||||
|
|
||||||
for _, ctrIP := range result.IPs {
|
for _, ctrIP := range result.IPs {
|
||||||
size, _ := ctrIP.Address.Mask.Size()
|
size, _ := ctrIP.Address.Mask.Size()
|
||||||
|
|
|
@ -20,7 +20,7 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) {
|
||||||
return define.ErrNotImplemented
|
return define.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) getContainerNetworkInfo() (*InspectNetworkSettings, error) {
|
func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, error) {
|
||||||
return nil, define.ErrNotImplemented
|
return nil, define.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Inspect returns an inspect struct from varlink
|
// Inspect returns an inspect struct from varlink
|
||||||
func (c *Container) Inspect(size bool) (*libpod.InspectContainerData, error) {
|
func (c *Container) Inspect(size bool) (*define.InspectContainerData, error) {
|
||||||
reply, err := iopodman.ContainerInspectData().Call(c.Runtime.Conn, c.ID(), size)
|
reply, err := iopodman.ContainerInspectData().Call(c.Runtime.Conn, c.ID(), size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
data := libpod.InspectContainerData{}
|
data := define.InspectContainerData{}
|
||||||
if err := json.Unmarshal([]byte(reply), &data); err != nil {
|
if err := json.Unmarshal([]byte(reply), &data); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/libpod/define"
|
||||||
"github.com/containers/libpod/libpod/image"
|
"github.com/containers/libpod/libpod/image"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
"github.com/containers/libpod/pkg/inspect"
|
"github.com/containers/libpod/pkg/inspect"
|
||||||
|
@ -109,7 +110,7 @@ type swagDockerTopResponse struct {
|
||||||
type swagLibpodInspectContainerResponse struct {
|
type swagLibpodInspectContainerResponse struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body struct {
|
Body struct {
|
||||||
libpod.InspectContainerData
|
define.InspectContainerData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/libpod/define"
|
||||||
"github.com/containers/libpod/pkg/api/handlers/utils"
|
"github.com/containers/libpod/pkg/api/handlers/utils"
|
||||||
"github.com/containers/libpod/pkg/domain/entities"
|
"github.com/containers/libpod/pkg/domain/entities"
|
||||||
)
|
)
|
||||||
|
@ -178,6 +179,6 @@ type swagVolumeListResponse struct {
|
||||||
type swagHealthCheckRunResponse struct {
|
type swagHealthCheckRunResponse struct {
|
||||||
// in:body
|
// in:body
|
||||||
Body struct {
|
Body struct {
|
||||||
libpod.HealthCheckResults
|
define.HealthCheckResults
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
|
||||||
"github.com/containers/libpod/libpod/define"
|
"github.com/containers/libpod/libpod/define"
|
||||||
lpapiv2 "github.com/containers/libpod/pkg/api/handlers/libpod"
|
lpapiv2 "github.com/containers/libpod/pkg/api/handlers/libpod"
|
||||||
"github.com/containers/libpod/pkg/bindings"
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
|
@ -106,7 +105,7 @@ func Remove(ctx context.Context, nameOrID string, force, volumes *bool) error {
|
||||||
// or a partial/full ID. The size bool determines whether the size of the container's root filesystem
|
// or a partial/full ID. The size bool determines whether the size of the container's root filesystem
|
||||||
// should be calculated. Calculating the size of a container requires extra work from the filesystem and
|
// should be calculated. Calculating the size of a container requires extra work from the filesystem and
|
||||||
// is therefore slower.
|
// is therefore slower.
|
||||||
func Inspect(ctx context.Context, nameOrID string, size *bool) (*libpod.InspectContainerData, error) {
|
func Inspect(ctx context.Context, nameOrID string, size *bool) (*define.InspectContainerData, error) {
|
||||||
conn, err := bindings.GetClient(ctx)
|
conn, err := bindings.GetClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -119,7 +118,7 @@ func Inspect(ctx context.Context, nameOrID string, size *bool) (*libpod.InspectC
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
inspect := libpod.InspectContainerData{}
|
inspect := define.InspectContainerData{}
|
||||||
return &inspect, response.Process(&inspect)
|
return &inspect, response.Process(&inspect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,19 +4,19 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod/define"
|
||||||
"github.com/containers/libpod/pkg/bindings"
|
"github.com/containers/libpod/pkg/bindings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunHealthCheck executes the container's healthcheck and returns the health status of the
|
// RunHealthCheck executes the container's healthcheck and returns the health status of the
|
||||||
// container.
|
// container.
|
||||||
func RunHealthCheck(ctx context.Context, nameOrID string) (*libpod.HealthCheckResults, error) {
|
func RunHealthCheck(ctx context.Context, nameOrID string) (*define.HealthCheckResults, error) {
|
||||||
conn, err := bindings.GetClient(ctx)
|
conn, err := bindings.GetClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
status libpod.HealthCheckResults
|
status define.HealthCheckResults
|
||||||
)
|
)
|
||||||
response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nameOrID)
|
response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/healthcheck", nil, nameOrID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -81,3 +81,13 @@ type RmReport struct {
|
||||||
Err error
|
Err error
|
||||||
Id string
|
Id string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ContainerInspectOptions struct {
|
||||||
|
Format string
|
||||||
|
Latest bool
|
||||||
|
Size bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContainerInspectReport struct {
|
||||||
|
*define.InspectContainerData
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
type ContainerEngine interface {
|
type ContainerEngine interface {
|
||||||
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error)
|
||||||
|
ContainerInspect(ctx context.Context, namesOrIds []string, options ContainerInspectOptions) ([]*ContainerInspectReport, error)
|
||||||
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
|
ContainerKill(ctx context.Context, namesOrIds []string, options KillOptions) ([]*KillReport, error)
|
||||||
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
|
ContainerPause(ctx context.Context, namesOrIds []string, options PauseUnPauseOptions) ([]*PauseUnpauseReport, error)
|
||||||
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
|
ContainerRestart(ctx context.Context, namesOrIds []string, options RestartOptions) ([]*RestartReport, error)
|
||||||
|
|
|
@ -239,3 +239,19 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||||
}
|
}
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
|
||||||
|
var reports []*entities.ContainerInspectReport
|
||||||
|
ctrs, err := shortcuts.GetContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, c := range ctrs {
|
||||||
|
data, err := c.Inspect(options.Size)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data})
|
||||||
|
}
|
||||||
|
return reports, nil
|
||||||
|
}
|
||||||
|
|
|
@ -138,3 +138,21 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
|
||||||
}
|
}
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.ContainerInspectOptions) ([]*entities.ContainerInspectReport, error) {
|
||||||
|
var (
|
||||||
|
reports []*entities.ContainerInspectReport
|
||||||
|
)
|
||||||
|
ctrs, err := getContainersByContext(ic.ClientCxt, false, namesOrIds)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, con := range ctrs {
|
||||||
|
data, err := containers.Inspect(ic.ClientCxt, con.ID, &options.Size)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
reports = append(reports, &entities.ContainerInspectReport{InspectContainerData: data})
|
||||||
|
}
|
||||||
|
return reports, nil
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containers/libpod/libpod"
|
"github.com/containers/libpod/libpod"
|
||||||
|
"github.com/containers/libpod/libpod/define"
|
||||||
"github.com/containers/libpod/pkg/inspect"
|
"github.com/containers/libpod/pkg/inspect"
|
||||||
"github.com/containers/libpod/pkg/rootless"
|
"github.com/containers/libpod/pkg/rootless"
|
||||||
. "github.com/containers/libpod/test/utils"
|
. "github.com/containers/libpod/test/utils"
|
||||||
|
@ -320,7 +321,7 @@ func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InspectContainer returns a container's inspect data in JSON format
|
// InspectContainer returns a container's inspect data in JSON format
|
||||||
func (p *PodmanTestIntegration) InspectContainer(name string) []libpod.InspectContainerData {
|
func (p *PodmanTestIntegration) InspectContainer(name string) []define.InspectContainerData {
|
||||||
cmd := []string{"inspect", name}
|
cmd := []string{"inspect", name}
|
||||||
session := p.Podman(cmd)
|
session := p.Podman(cmd)
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
|
@ -492,8 +493,8 @@ func (p *PodmanTestIntegration) PullImage(image string) error {
|
||||||
|
|
||||||
// InspectContainerToJSON takes the session output of an inspect
|
// InspectContainerToJSON takes the session output of an inspect
|
||||||
// container and returns json
|
// container and returns json
|
||||||
func (s *PodmanSessionIntegration) InspectContainerToJSON() []libpod.InspectContainerData {
|
func (s *PodmanSessionIntegration) InspectContainerToJSON() []define.InspectContainerData {
|
||||||
var i []libpod.InspectContainerData
|
var i []define.InspectContainerData
|
||||||
err := json.Unmarshal(s.Out.Contents(), &i)
|
err := json.Unmarshal(s.Out.Contents(), &i)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
return i
|
return i
|
||||||
|
|
Loading…
Reference in New Issue