Begin to break up pkg/inspect

Let's put inspect structs where they're actually being used. We
originally made pkg/inspect to solve circular import issues.
There are no more circular import issues.

Image structs remain for now, I'm focusing on container inspect.

Signed-off-by: Matthew Heon <matthew.heon@pm.me>
This commit is contained in:
Matthew Heon
2019-05-21 16:42:41 -04:00
committed by Matthew Heon
parent 7c465d4d97
commit 1be345bd9d
12 changed files with 420 additions and 402 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"io"
v1 "k8s.io/api/core/v1"
"os"
"path/filepath"
"regexp"
@ -17,15 +16,13 @@ import (
"github.com/containers/image/types"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/inspect"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-units"
"github.com/google/shlex"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
)
const (
@ -621,145 +618,6 @@ func getStrFromSquareBrackets(cmd string) string {
return strings.Join(arr, ",")
}
// GetCtrInspectInfo takes container inspect data and collects all its info into a ContainerData
// structure for inspection related methods
func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.ContainerInspectData, createArtifact *cc.CreateConfig) (*inspect.ContainerData, error) {
spec := config.Spec
cpus, mems, period, quota, realtimePeriod, realtimeRuntime, shares := getCPUInfo(spec)
blkioWeight, blkioWeightDevice, blkioReadBps, blkioWriteBps, blkioReadIOPS, blkioeWriteIOPS := getBLKIOInfo(spec)
memKernel, memReservation, memSwap, memSwappiness, memDisableOOMKiller := getMemoryInfo(spec)
pidsLimit := getPidsInfo(spec)
cgroup := getCgroup(spec)
logConfig := inspect.LogConfig{
config.LogDriver,
make(map[string]string),
}
data := &inspect.ContainerData{
ctrInspectData,
&inspect.HostConfig{
ConsoleSize: spec.Process.ConsoleSize,
OomScoreAdj: spec.Process.OOMScoreAdj,
CPUShares: shares,
BlkioWeight: blkioWeight,
BlkioWeightDevice: blkioWeightDevice,
BlkioDeviceReadBps: blkioReadBps,
BlkioDeviceWriteBps: blkioWriteBps,
BlkioDeviceReadIOps: blkioReadIOPS,
BlkioDeviceWriteIOps: blkioeWriteIOPS,
CPUPeriod: period,
CPUQuota: quota,
CPURealtimePeriod: realtimePeriod,
CPURealtimeRuntime: realtimeRuntime,
CPUSetCPUs: cpus,
CPUSetMems: mems,
Devices: spec.Linux.Devices,
KernelMemory: memKernel,
MemoryReservation: memReservation,
MemorySwap: memSwap,
MemorySwappiness: memSwappiness,
OomKillDisable: memDisableOOMKiller,
PidsLimit: pidsLimit,
Privileged: config.Privileged,
ReadOnlyRootfs: spec.Root.Readonly,
ReadOnlyTmpfs: createArtifact.ReadOnlyTmpfs,
Runtime: config.OCIRuntime,
NetworkMode: string(createArtifact.NetMode),
IpcMode: string(createArtifact.IpcMode),
Cgroup: cgroup,
UTSMode: string(createArtifact.UtsMode),
UsernsMode: string(createArtifact.UsernsMode),
GroupAdd: spec.Process.User.AdditionalGids,
ContainerIDFile: createArtifact.CidFile,
AutoRemove: createArtifact.Rm,
CapAdd: createArtifact.CapAdd,
CapDrop: createArtifact.CapDrop,
DNS: createArtifact.DNSServers,
DNSOptions: createArtifact.DNSOpt,
DNSSearch: createArtifact.DNSSearch,
PidMode: string(createArtifact.PidMode),
CgroupParent: createArtifact.CgroupParent,
ShmSize: createArtifact.Resources.ShmSize,
Memory: createArtifact.Resources.Memory,
Ulimits: createArtifact.Resources.Ulimit,
SecurityOpt: createArtifact.SecurityOpts,
Tmpfs: createArtifact.Tmpfs,
LogConfig: &logConfig,
},
&inspect.CtrConfig{
Hostname: spec.Hostname,
User: spec.Process.User,
Env: spec.Process.Env,
Image: config.RootfsImageName,
WorkingDir: spec.Process.Cwd,
Labels: config.Labels,
Annotations: spec.Annotations,
Tty: spec.Process.Terminal,
OpenStdin: config.Stdin,
StopSignal: config.StopSignal,
Cmd: config.Spec.Process.Args,
Entrypoint: strings.Join(createArtifact.Entrypoint, " "),
Healthcheck: config.HealthCheckConfig,
},
}
return data, nil
}
func getCPUInfo(spec *specs.Spec) (string, string, *uint64, *int64, *uint64, *int64, *uint64) {
if spec.Linux.Resources == nil {
return "", "", nil, nil, nil, nil, nil
}
cpu := spec.Linux.Resources.CPU
if cpu == nil {
return "", "", nil, nil, nil, nil, nil
}
return cpu.Cpus, cpu.Mems, cpu.Period, cpu.Quota, cpu.RealtimePeriod, cpu.RealtimeRuntime, cpu.Shares
}
func getBLKIOInfo(spec *specs.Spec) (*uint16, []specs.LinuxWeightDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice) {
if spec.Linux.Resources == nil {
return nil, nil, nil, nil, nil, nil
}
blkio := spec.Linux.Resources.BlockIO
if blkio == nil {
return nil, nil, nil, nil, nil, nil
}
return blkio.Weight, blkio.WeightDevice, blkio.ThrottleReadBpsDevice, blkio.ThrottleWriteBpsDevice, blkio.ThrottleReadIOPSDevice, blkio.ThrottleWriteIOPSDevice
}
func getMemoryInfo(spec *specs.Spec) (*int64, *int64, *int64, *uint64, *bool) {
if spec.Linux.Resources == nil {
return nil, nil, nil, nil, nil
}
memory := spec.Linux.Resources.Memory
if memory == nil {
return nil, nil, nil, nil, nil
}
return memory.Kernel, memory.Reservation, memory.Swap, memory.Swappiness, memory.DisableOOMKiller
}
func getPidsInfo(spec *specs.Spec) *int64 {
if spec.Linux.Resources == nil {
return nil
}
pids := spec.Linux.Resources.Pids
if pids == nil {
return nil
}
return &pids.Limit
}
func getCgroup(spec *specs.Spec) string {
cgroup := "host"
for _, ns := range spec.Linux.Namespaces {
if ns.Type == specs.CgroupNamespace && ns.Path != "" {
cgroup = "container"
}
}
return cgroup
}
func comparePorts(i, j ocicni.PortMapping) bool {
if i.ContainerPort != j.ContainerPort {
return i.ContainerPort < j.ContainerPort

View File

@ -0,0 +1,255 @@
package shared
import (
"strings"
"github.com/containers/image/manifest"
"github.com/containers/libpod/libpod"
cc "github.com/containers/libpod/pkg/spec"
"github.com/docker/go-connections/nat"
specs "github.com/opencontainers/runtime-spec/specs-go"
)
// InspectContainer holds all inspect data for a container.
// The format of individual components is fixed so the overall structure, when
// JSON encoded, matches the output of `docker inspect`.
// It combines Libpod-source inspect data with Podman-specific inspect data.
type InspectContainer struct {
*libpod.InspectContainerData
HostConfig *InspectContainerHostConfig `json:"HostConfig"`
Config *InspectContainerConfig `json:"Config"`
}
// InspectContainerHostConfig holds Container configuration that is not specific
// to Libpod. This information is (mostly) stored by Podman as an artifact.
// This struct is matched to the output of `docker inspect`.
type InspectContainerHostConfig struct {
ContainerIDFile string `json:"ContainerIDFile"`
LogConfig *InspectLogConfig `json:"LogConfig"` //TODO
NetworkMode string `json:"NetworkMode"`
PortBindings nat.PortMap `json:"PortBindings"` //TODO
AutoRemove bool `json:"AutoRemove"`
CapAdd []string `json:"CapAdd"`
CapDrop []string `json:"CapDrop"`
DNS []string `json:"DNS"`
DNSOptions []string `json:"DNSOptions"`
DNSSearch []string `json:"DNSSearch"`
ExtraHosts []string `json:"ExtraHosts"`
GroupAdd []uint32 `json:"GroupAdd"`
IpcMode string `json:"IpcMode"`
Cgroup string `json:"Cgroup"`
OomScoreAdj *int `json:"OomScoreAdj"`
PidMode string `json:"PidMode"`
Privileged bool `json:"Privileged"`
PublishAllPorts bool `json:"PublishAllPorts"` //TODO
ReadOnlyRootfs bool `json:"ReadonlyRootfs"`
ReadOnlyTmpfs bool `json:"ReadonlyTmpfs"`
SecurityOpt []string `json:"SecurityOpt"`
UTSMode string `json:"UTSMode"`
UsernsMode string `json:"UsernsMode"`
ShmSize int64 `json:"ShmSize"`
Runtime string `json:"Runtime"`
ConsoleSize *specs.Box `json:"ConsoleSize"`
CPUShares *uint64 `json:"CpuShares"`
Memory int64 `json:"Memory"`
NanoCPUs int `json:"NanoCpus"`
CgroupParent string `json:"CgroupParent"`
BlkioWeight *uint16 `json:"BlkioWeight"`
BlkioWeightDevice []specs.LinuxWeightDevice `json:"BlkioWeightDevice"`
BlkioDeviceReadBps []specs.LinuxThrottleDevice `json:"BlkioDeviceReadBps"`
BlkioDeviceWriteBps []specs.LinuxThrottleDevice `json:"BlkioDeviceWriteBps"`
BlkioDeviceReadIOps []specs.LinuxThrottleDevice `json:"BlkioDeviceReadIOps"`
BlkioDeviceWriteIOps []specs.LinuxThrottleDevice `json:"BlkioDeviceWriteIOps"`
CPUPeriod *uint64 `json:"CpuPeriod"`
CPUQuota *int64 `json:"CpuQuota"`
CPURealtimePeriod *uint64 `json:"CpuRealtimePeriod"`
CPURealtimeRuntime *int64 `json:"CpuRealtimeRuntime"`
CPUSetCPUs string `json:"CpuSetCpus"`
CPUSetMems string `json:"CpuSetMems"`
Devices []specs.LinuxDevice `json:"Devices"`
DiskQuota int `json:"DiskQuota"` //check type, TODO
KernelMemory *int64 `json:"KernelMemory"`
MemoryReservation *int64 `json:"MemoryReservation"`
MemorySwap *int64 `json:"MemorySwap"`
MemorySwappiness *uint64 `json:"MemorySwappiness"`
OomKillDisable *bool `json:"OomKillDisable"`
PidsLimit *int64 `json:"PidsLimit"`
Ulimits []string `json:"Ulimits"`
CPUCount int `json:"CpuCount"`
CPUPercent int `json:"CpuPercent"`
IOMaximumIOps int `json:"IOMaximumIOps"` //check type, TODO
IOMaximumBandwidth int `json:"IOMaximumBandwidth"` //check type, TODO
Tmpfs []string `json:"Tmpfs"`
}
// InspectContainerConfig holds further data about a container, again mostly
// not directly stored in Libpod. This struct is matched to the output of
// `docker inspect`.
type InspectContainerConfig struct {
Hostname string `json:"Hostname"`
DomainName string `json:"Domainname"` //TODO
User specs.User `json:"User"`
AttachStdin bool `json:"AttachStdin"` //TODO
AttachStdout bool `json:"AttachStdout"` //TODO
AttachStderr bool `json:"AttachStderr"` //TODO
Tty bool `json:"Tty"`
OpenStdin bool `json:"OpenStdin"`
StdinOnce bool `json:"StdinOnce"` //TODO
Env []string `json:"Env"`
Cmd []string `json:"Cmd"`
Image string `json:"Image"`
Volumes map[string]struct{} `json:"Volumes"`
WorkingDir string `json:"WorkingDir"`
Entrypoint string `json:"Entrypoint"`
Labels map[string]string `json:"Labels"`
Annotations map[string]string `json:"Annotations"`
StopSignal uint `json:"StopSignal"`
Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"`
}
// InspectLogConfig holds information about a container's configured log driver
// and is presently unused. It is retained for Docker compatability.
type InspectLogConfig struct {
Type string `json:"Type"`
Config map[string]string `json:"Config"` //idk type, TODO
}
// GetCtrInspectInfo inspects a container, combining Libpod inspect information
// with other information not stored in Libpod and returning a struct that, when
// formatted for JSON output, is compatible with `docker inspect`.
func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *libpod.InspectContainerData, createArtifact *cc.CreateConfig) (*InspectContainer, error) {
spec := config.Spec
cpus, mems, period, quota, realtimePeriod, realtimeRuntime, shares := getCPUInfo(spec)
blkioWeight, blkioWeightDevice, blkioReadBps, blkioWriteBps, blkioReadIOPS, blkioeWriteIOPS := getBLKIOInfo(spec)
memKernel, memReservation, memSwap, memSwappiness, memDisableOOMKiller := getMemoryInfo(spec)
pidsLimit := getPidsInfo(spec)
cgroup := getCgroup(spec)
logConfig := InspectLogConfig{
config.LogDriver,
make(map[string]string),
}
data := &InspectContainer{
ctrInspectData,
&InspectContainerHostConfig{
ConsoleSize: spec.Process.ConsoleSize,
OomScoreAdj: spec.Process.OOMScoreAdj,
CPUShares: shares,
BlkioWeight: blkioWeight,
BlkioWeightDevice: blkioWeightDevice,
BlkioDeviceReadBps: blkioReadBps,
BlkioDeviceWriteBps: blkioWriteBps,
BlkioDeviceReadIOps: blkioReadIOPS,
BlkioDeviceWriteIOps: blkioeWriteIOPS,
CPUPeriod: period,
CPUQuota: quota,
CPURealtimePeriod: realtimePeriod,
CPURealtimeRuntime: realtimeRuntime,
CPUSetCPUs: cpus,
CPUSetMems: mems,
Devices: spec.Linux.Devices,
KernelMemory: memKernel,
LogConfig: &logConfig,
MemoryReservation: memReservation,
MemorySwap: memSwap,
MemorySwappiness: memSwappiness,
OomKillDisable: memDisableOOMKiller,
PidsLimit: pidsLimit,
Privileged: config.Privileged,
ReadOnlyRootfs: spec.Root.Readonly,
ReadOnlyTmpfs: createArtifact.ReadOnlyTmpfs,
Runtime: config.OCIRuntime,
NetworkMode: string(createArtifact.NetMode),
IpcMode: string(createArtifact.IpcMode),
Cgroup: cgroup,
UTSMode: string(createArtifact.UtsMode),
UsernsMode: string(createArtifact.UsernsMode),
GroupAdd: spec.Process.User.AdditionalGids,
ContainerIDFile: createArtifact.CidFile,
AutoRemove: createArtifact.Rm,
CapAdd: createArtifact.CapAdd,
CapDrop: createArtifact.CapDrop,
DNS: createArtifact.DNSServers,
DNSOptions: createArtifact.DNSOpt,
DNSSearch: createArtifact.DNSSearch,
PidMode: string(createArtifact.PidMode),
CgroupParent: createArtifact.CgroupParent,
ShmSize: createArtifact.Resources.ShmSize,
Memory: createArtifact.Resources.Memory,
Ulimits: createArtifact.Resources.Ulimit,
SecurityOpt: createArtifact.SecurityOpts,
Tmpfs: createArtifact.Tmpfs,
},
&InspectContainerConfig{
Hostname: spec.Hostname,
User: spec.Process.User,
Env: spec.Process.Env,
Image: config.RootfsImageName,
WorkingDir: spec.Process.Cwd,
Labels: config.Labels,
Annotations: spec.Annotations,
Tty: spec.Process.Terminal,
OpenStdin: config.Stdin,
StopSignal: config.StopSignal,
Cmd: config.Spec.Process.Args,
Entrypoint: strings.Join(createArtifact.Entrypoint, " "),
Healthcheck: config.HealthCheckConfig,
},
}
return data, nil
}
func getCPUInfo(spec *specs.Spec) (string, string, *uint64, *int64, *uint64, *int64, *uint64) {
if spec.Linux.Resources == nil {
return "", "", nil, nil, nil, nil, nil
}
cpu := spec.Linux.Resources.CPU
if cpu == nil {
return "", "", nil, nil, nil, nil, nil
}
return cpu.Cpus, cpu.Mems, cpu.Period, cpu.Quota, cpu.RealtimePeriod, cpu.RealtimeRuntime, cpu.Shares
}
func getBLKIOInfo(spec *specs.Spec) (*uint16, []specs.LinuxWeightDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice, []specs.LinuxThrottleDevice) {
if spec.Linux.Resources == nil {
return nil, nil, nil, nil, nil, nil
}
blkio := spec.Linux.Resources.BlockIO
if blkio == nil {
return nil, nil, nil, nil, nil, nil
}
return blkio.Weight, blkio.WeightDevice, blkio.ThrottleReadBpsDevice, blkio.ThrottleWriteBpsDevice, blkio.ThrottleReadIOPSDevice, blkio.ThrottleWriteIOPSDevice
}
func getMemoryInfo(spec *specs.Spec) (*int64, *int64, *int64, *uint64, *bool) {
if spec.Linux.Resources == nil {
return nil, nil, nil, nil, nil
}
memory := spec.Linux.Resources.Memory
if memory == nil {
return nil, nil, nil, nil, nil
}
return memory.Kernel, memory.Reservation, memory.Swap, memory.Swappiness, memory.DisableOOMKiller
}
func getPidsInfo(spec *specs.Spec) *int64 {
if spec.Linux.Resources == nil {
return nil
}
pids := spec.Linux.Resources.Pids
if pids == nil {
return nil
}
return &pids.Limit
}
func getCgroup(spec *specs.Spec) string {
cgroup := "host"
for _, ns := range spec.Linux.Namespaces {
if ns.Type == specs.CgroupNamespace && ns.Path != "" {
cgroup = "container"
}
}
return cgroup
}

View File

@ -10,9 +10,7 @@ import (
"sync"
"time"
"github.com/containers/libpod/libpod/driver"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/lookup"
"github.com/containers/storage/pkg/stringid"
"github.com/docker/docker/oci/caps"
@ -535,32 +533,6 @@ func (c *Container) RemoveArtifact(name string) error {
return os.Remove(c.getArtifactPath(name))
}
// Inspect a container for low-level information
func (c *Container) Inspect(size bool) (*inspect.ContainerInspectData, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.syncContainer(); err != nil {
return nil, err
}
}
storeCtr, err := c.runtime.store.Container(c.ID())
if err != nil {
return nil, errors.Wrapf(err, "error getting container from store %q", c.ID())
}
layer, err := c.runtime.store.Layer(storeCtr.LayerID)
if err != nil {
return nil, errors.Wrapf(err, "error reading information about layer %q", storeCtr.LayerID)
}
driverData, err := driver.GetDriverData(c.runtime.store, layer.ID)
if err != nil {
return nil, errors.Wrapf(err, "error getting graph driver info %q", c.ID())
}
return c.getContainerInspectData(size, driverData)
}
// Wait blocks until the container exits and returns its exit code.
func (c *Container) Wait() (int32, error) {
return c.WaitWithInterval(DefaultWaitInterval)

View File

@ -2,14 +2,127 @@ package libpod
import (
"strings"
"time"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/libpod/driver"
"github.com/cri-o/ocicni/pkg/ocicni"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data) (*inspect.ContainerInspectData, error) {
// 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"`
ImageID string `json:"Image"`
ImageName string `json:"ImageName"`
Rootfs string `json:"Rootfs"`
ResolvConfPath string `json:"ResolvConfPath"`
HostnamePath string `json:"HostnamePath"`
HostsPath string `json:"HostsPath"`
StaticDir string `json:"StaticDir"`
LogPath string `json:"LogPath"`
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 []specs.Mount `json:"Mounts"`
Dependencies []string `json:"Dependencies"`
NetworkSettings *InspectNetworkSettings `json:"NetworkSettings"` //TODO
ExitCommand []string `json:"ExitCommand"`
Namespace string `json:"Namespace"`
IsInfra bool `json:"IsInfra"`
}
// 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"`
ExitCode int32 `json:"ExitCode"`
Error string `json:"Error"` // TODO
StartedAt time.Time `json:"StartedAt"`
FinishedAt time.Time `json:"FinishedAt"`
Healthcheck HealthCheckResults `json:"Healthcheck,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 {
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"`
SecondaryIPAddresses []string `json:"SecondaryIPAddresses"`
SecondaryIPv6Addresses []string `json:"SecondaryIPv6Addresses"`
EndpointID string `json:"EndpointID"`
Gateway string `json:"Gateway"`
GlobalIPv6Address string `json:"GlobalIPv6Address"`
GlobalIPv6PrefixLen int `json:"GlobalIPv6PrefixLen"`
IPAddress string `json:"IPAddress"`
IPPrefixLen int `json:"IPPrefixLen"`
IPv6Gateway string `json:"IPv6Gateway"`
MacAddress string `json:"MacAddress"`
}
// Inspect a container for low-level information
func (c *Container) Inspect(size bool) (*InspectContainerData, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.syncContainer(); err != nil {
return nil, err
}
}
storeCtr, err := c.runtime.store.Container(c.ID())
if err != nil {
return nil, errors.Wrapf(err, "error getting container from store %q", c.ID())
}
layer, err := c.runtime.store.Layer(storeCtr.LayerID)
if err != nil {
return nil, errors.Wrapf(err, "error reading information about layer %q", storeCtr.LayerID)
}
driverData, err := driver.GetDriverData(c.runtime.store, layer.ID)
if err != nil {
return nil, errors.Wrapf(err, "error getting graph driver info %q", c.ID())
}
return c.getContainerInspectData(size, driverData)
}
func (c *Container) getContainerInspectData(size bool, driverData *driver.Data) (*InspectContainerData, error) {
config := c.config
runtimeInfo := c.state
spec, err := c.specFromState()
@ -65,12 +178,12 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
}
}
data := &inspect.ContainerInspectData{
data := &InspectContainerData{
ID: config.ID,
Created: config.CreatedTime,
Path: path,
Args: args,
State: &inspect.ContainerInspectState{
State: &InspectContainerState{
OciVersion: spec.Version,
Status: runtimeInfo.State.String(),
Running: runtimeInfo.State == ContainerStateRunning,
@ -106,7 +219,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
GraphDriver: driverData,
Mounts: mounts,
Dependencies: c.Dependencies(),
NetworkSettings: &inspect.NetworkSettings{
NetworkSettings: &InspectNetworkSettings{
Bridge: "", // TODO
SandboxID: "", // TODO - is this even relevant?
HairpinMode: false, // TODO

View File

@ -1,10 +1,15 @@
package driver
import (
"github.com/containers/libpod/pkg/inspect"
cstorage "github.com/containers/storage"
)
// Data handles the data for a storage driver
type Data struct {
Name string `json:"Name"`
Data map[string]string `json:"Data"`
}
// GetDriverName returns the name of the driver for the given store
func GetDriverName(store cstorage.Store) (string, error) {
driver, err := store.GraphDriver()
@ -24,7 +29,7 @@ func GetDriverMetadata(store cstorage.Store, layerID string) (map[string]string,
}
// GetDriverData returns the Data struct with information of the driver used by the store
func GetDriverData(store cstorage.Store, layerID string) (*inspect.Data, error) {
func GetDriverData(store cstorage.Store, layerID string) (*Data, error) {
name, err := GetDriverName(store)
if err != nil {
return nil, err
@ -33,7 +38,7 @@ func GetDriverData(store cstorage.Store, layerID string) (*inspect.Data, error)
if err != nil {
return nil, err
}
return &inspect.Data{
return &Data{
Name: name,
Data: metaData,
}, nil

View File

@ -9,7 +9,6 @@ import (
"strings"
"time"
"github.com/containers/libpod/pkg/inspect"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@ -53,6 +52,28 @@ const (
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
type hcWriteCloser struct {
*bufio.Writer
@ -157,8 +178,8 @@ func checkHealthCheckCanBeRun(c *Container) (HealthCheckStatus, error) {
return HealthCheckDefined, nil
}
func newHealthCheckLog(start, end time.Time, exitCode int, log string) inspect.HealthCheckLog {
return inspect.HealthCheckLog{
func newHealthCheckLog(start, end time.Time, exitCode int, log string) HealthCheckLog {
return HealthCheckLog{
Start: start.Format(time.RFC3339Nano),
End: end.Format(time.RFC3339Nano),
ExitCode: exitCode,
@ -182,7 +203,7 @@ func (c *Container) updateHealthStatus(status string) error {
}
// UpdateHealthCheckLog parses the health check results and writes the log
func (c *Container) updateHealthCheckLog(hcl inspect.HealthCheckLog, inStartPeriod bool) error {
func (c *Container) updateHealthCheckLog(hcl HealthCheckLog, inStartPeriod bool) error {
healthCheck, err := c.GetHealthCheckLog()
if err != nil {
return err
@ -223,8 +244,8 @@ func (c *Container) healthCheckLogPath() string {
// GetHealthCheckLog returns HealthCheck results by reading the container's
// health check log file. If the health check log file does not exist, then
// an empty healthcheck struct is returned
func (c *Container) GetHealthCheckLog() (inspect.HealthCheckResults, error) {
var healthCheck inspect.HealthCheckResults
func (c *Container) GetHealthCheckLog() (HealthCheckResults, error) {
var healthCheck HealthCheckResults
if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) {
return healthCheck, nil
}

View File

@ -659,7 +659,7 @@ func (i *Image) Size(ctx context.Context) (*uint64, error) {
}
// DriverData gets the driver data from the store on a layer
func (i *Image) DriverData() (*inspect.Data, error) {
func (i *Image) DriverData() (*driver.Data, error) {
topLayer, err := i.Layer()
if err != nil {
return nil, err

View File

@ -17,7 +17,6 @@ import (
cnitypes "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/libpod/pkg/firewall"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/netns"
"github.com/containers/libpod/pkg/rootless"
"github.com/cri-o/ocicni/pkg/ocicni"
@ -470,7 +469,7 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) {
return netStats, err
}
func (c *Container) getContainerNetworkInfo(data *inspect.ContainerInspectData) *inspect.ContainerInspectData {
func (c *Container) getContainerNetworkInfo(data *InspectContainerData) *InspectContainerData {
if c.state.NetNS != nil && len(c.state.NetworkStatus) > 0 {
// Report network settings from the first pod network
result := c.state.NetworkStatus[0]

View File

@ -2,10 +2,6 @@
package libpod
import (
"github.com/containers/libpod/pkg/inspect"
)
func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) {
return ErrNotImplemented
}
@ -22,6 +18,6 @@ func (r *Runtime) createNetNS(ctr *Container) (err error) {
return ErrNotImplemented
}
func (c *Container) getContainerNetworkInfo(data *inspect.ContainerInspectData) *inspect.ContainerInspectData {
func (c *Container) getContainerNetworkInfo(data *InspectContainerData) *InspectContainerData {
return nil
}

View File

@ -16,7 +16,6 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/docker/pkg/term"
@ -29,12 +28,12 @@ import (
)
// Inspect returns an inspect struct from varlink
func (c *Container) Inspect(size bool) (*inspect.ContainerInspectData, error) {
func (c *Container) Inspect(size bool) (*libpod.InspectContainerData, error) {
reply, err := iopodman.ContainerInspectData().Call(c.Runtime.Conn, c.ID(), size)
if err != nil {
return nil, err
}
data := inspect.ContainerInspectData{}
data := libpod.InspectContainerData{}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
return nil, err
}

View File

@ -3,110 +3,11 @@ package inspect
import (
"time"
"github.com/containers/image/manifest"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/go-connections/nat"
"github.com/containers/libpod/libpod/driver"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/runtime-spec/specs-go"
)
// ContainerData holds the podman inspect data for a container
type ContainerData struct {
*ContainerInspectData
HostConfig *HostConfig `json:"HostConfig"`
Config *CtrConfig `json:"Config"`
}
// HostConfig represents the host configuration for the container
type HostConfig struct {
ContainerIDFile string `json:"ContainerIDFile"`
LogConfig *LogConfig `json:"LogConfig"` //TODO
NetworkMode string `json:"NetworkMode"`
PortBindings nat.PortMap `json:"PortBindings"` //TODO
AutoRemove bool `json:"AutoRemove"`
CapAdd []string `json:"CapAdd"`
CapDrop []string `json:"CapDrop"`
DNS []string `json:"DNS"`
DNSOptions []string `json:"DNSOptions"`
DNSSearch []string `json:"DNSSearch"`
ExtraHosts []string `json:"ExtraHosts"`
GroupAdd []uint32 `json:"GroupAdd"`
IpcMode string `json:"IpcMode"`
Cgroup string `json:"Cgroup"`
OomScoreAdj *int `json:"OomScoreAdj"`
PidMode string `json:"PidMode"`
Privileged bool `json:"Privileged"`
PublishAllPorts bool `json:"PublishAllPorts"` //TODO
ReadOnlyRootfs bool `json:"ReadonlyRootfs"`
ReadOnlyTmpfs bool `json:"ReadonlyTmpfs"`
SecurityOpt []string `json:"SecurityOpt"`
UTSMode string `json:"UTSMode"`
UsernsMode string `json:"UsernsMode"`
ShmSize int64 `json:"ShmSize"`
Runtime string `json:"Runtime"`
ConsoleSize *specs.Box `json:"ConsoleSize"`
CPUShares *uint64 `json:"CpuShares"`
Memory int64 `json:"Memory"`
NanoCPUs int `json:"NanoCpus"`
CgroupParent string `json:"CgroupParent"`
BlkioWeight *uint16 `json:"BlkioWeight"`
BlkioWeightDevice []specs.LinuxWeightDevice `json:"BlkioWeightDevice"`
BlkioDeviceReadBps []specs.LinuxThrottleDevice `json:"BlkioDeviceReadBps"`
BlkioDeviceWriteBps []specs.LinuxThrottleDevice `json:"BlkioDeviceWriteBps"`
BlkioDeviceReadIOps []specs.LinuxThrottleDevice `json:"BlkioDeviceReadIOps"`
BlkioDeviceWriteIOps []specs.LinuxThrottleDevice `json:"BlkioDeviceWriteIOps"`
CPUPeriod *uint64 `json:"CpuPeriod"`
CPUQuota *int64 `json:"CpuQuota"`
CPURealtimePeriod *uint64 `json:"CpuRealtimePeriod"`
CPURealtimeRuntime *int64 `json:"CpuRealtimeRuntime"`
CPUSetCPUs string `json:"CpuSetCpus"`
CPUSetMems string `json:"CpuSetMems"`
Devices []specs.LinuxDevice `json:"Devices"`
DiskQuota int `json:"DiskQuota"` //check type, TODO
KernelMemory *int64 `json:"KernelMemory"`
MemoryReservation *int64 `json:"MemoryReservation"`
MemorySwap *int64 `json:"MemorySwap"`
MemorySwappiness *uint64 `json:"MemorySwappiness"`
OomKillDisable *bool `json:"OomKillDisable"`
PidsLimit *int64 `json:"PidsLimit"`
Ulimits []string `json:"Ulimits"`
CPUCount int `json:"CpuCount"`
CPUPercent int `json:"CpuPercent"`
IOMaximumIOps int `json:"IOMaximumIOps"` //check type, TODO
IOMaximumBandwidth int `json:"IOMaximumBandwidth"` //check type, TODO
Tmpfs []string `json:"Tmpfs"`
}
// CtrConfig holds information about the container configuration
type CtrConfig struct {
Hostname string `json:"Hostname"`
DomainName string `json:"Domainname"` //TODO
User specs.User `json:"User"`
AttachStdin bool `json:"AttachStdin"` //TODO
AttachStdout bool `json:"AttachStdout"` //TODO
AttachStderr bool `json:"AttachStderr"` //TODO
Tty bool `json:"Tty"`
OpenStdin bool `json:"OpenStdin"`
StdinOnce bool `json:"StdinOnce"` //TODO
Env []string `json:"Env"`
Cmd []string `json:"Cmd"`
Image string `json:"Image"`
Volumes map[string]struct{} `json:"Volumes"`
WorkingDir string `json:"WorkingDir"`
Entrypoint string `json:"Entrypoint"`
Labels map[string]string `json:"Labels"`
Annotations map[string]string `json:"Annotations"`
StopSignal uint `json:"StopSignal"`
Healthcheck *manifest.Schema2HealthConfig `json:"Healthcheck,omitempty"`
}
// LogConfig holds the log information for a container
type LogConfig struct {
Type string `json:"Type"`
Config map[string]string `json:"Config"` //idk type, TODO
}
// ImageData holds the inspect information of an image
type ImageData struct {
ID string `json:"Id"`
@ -123,7 +24,7 @@ type ImageData struct {
Os string `json:"Os"`
Size int64 `json:"Size"`
VirtualSize int64 `json:"VirtualSize"`
GraphDriver *Data `json:"GraphDriver"`
GraphDriver *driver.Data `json:"GraphDriver"`
RootFS *RootFS `json:"RootFS"`
Labels map[string]string `json:"Labels"`
Annotations map[string]string `json:"Annotations"`
@ -138,86 +39,6 @@ type RootFS struct {
Layers []digest.Digest `json:"Layers"`
}
// Data handles the data for a storage driver
type Data struct {
Name string `json:"Name"`
Data map[string]string `json:"Data"`
}
// ContainerInspectData handles the data used when inspecting a container
type ContainerInspectData struct {
ID string `json:"ID"`
Created time.Time `json:"Created"`
Path string `json:"Path"`
Args []string `json:"Args"`
State *ContainerInspectState `json:"State"`
ImageID string `json:"Image"`
ImageName string `json:"ImageName"`
Rootfs string `json:"Rootfs"`
ResolvConfPath string `json:"ResolvConfPath"`
HostnamePath string `json:"HostnamePath"`
HostsPath string `json:"HostsPath"`
StaticDir string `json:"StaticDir"`
LogPath string `json:"LogPath"`
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 *Data `json:"GraphDriver"`
SizeRw int64 `json:"SizeRw,omitempty"`
SizeRootFs int64 `json:"SizeRootFs,omitempty"`
Mounts []specs.Mount `json:"Mounts"`
Dependencies []string `json:"Dependencies"`
NetworkSettings *NetworkSettings `json:"NetworkSettings"` //TODO
ExitCommand []string `json:"ExitCommand"`
Namespace string `json:"Namespace"`
IsInfra bool `json:"IsInfra"`
}
// ContainerInspectState represents the state of a container.
type ContainerInspectState 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"`
ExitCode int32 `json:"ExitCode"`
Error string `json:"Error"` // TODO
StartedAt time.Time `json:"StartedAt"`
FinishedAt time.Time `json:"FinishedAt"`
Healthcheck HealthCheckResults `json:"Healthcheck,omitempty"`
}
// NetworkSettings holds information about the newtwork settings of the container
type NetworkSettings struct {
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"`
SecondaryIPAddresses []string `json:"SecondaryIPAddresses"`
SecondaryIPv6Addresses []string `json:"SecondaryIPv6Addresses"`
EndpointID string `json:"EndpointID"`
Gateway string `json:"Gateway"`
GlobalIPv6Address string `json:"GlobalIPv6Address"`
GlobalIPv6PrefixLen int `json:"GlobalIPv6PrefixLen"`
IPAddress string `json:"IPAddress"`
IPPrefixLen int `json:"IPPrefixLen"`
IPv6Gateway string `json:"IPv6Gateway"`
MacAddress string `json:"MacAddress"`
}
// ImageResult is used for podman images for collection and output
type ImageResult struct {
Tag string
@ -232,25 +53,3 @@ type ImageResult struct {
Labels map[string]string
Dangling bool
}
// 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"`
}

View File

@ -11,6 +11,7 @@ import (
"strings"
"testing"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/rootless"
@ -319,7 +320,7 @@ func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
}
// InspectContainer returns a container's inspect data in JSON format
func (p *PodmanTestIntegration) InspectContainer(name string) []inspect.ContainerData {
func (p *PodmanTestIntegration) InspectContainer(name string) []shared.InspectContainer {
cmd := []string{"inspect", name}
session := p.Podman(cmd)
session.WaitWithDefaultTimeout()
@ -466,8 +467,8 @@ func (p *PodmanTestIntegration) PullImage(image string) error {
// InspectContainerToJSON takes the session output of an inspect
// container and returns json
func (s *PodmanSessionIntegration) InspectContainerToJSON() []inspect.ContainerData {
var i []inspect.ContainerData
func (s *PodmanSessionIntegration) InspectContainerToJSON() []shared.InspectContainer {
var i []shared.InspectContainer
err := json.Unmarshal(s.Out.Contents(), &i)
Expect(err).To(BeNil())
return i