diff options
Diffstat (limited to 'cmd/kpod/inspect.go')
-rw-r--r-- | cmd/kpod/inspect.go | 308 |
1 files changed, 275 insertions, 33 deletions
diff --git a/cmd/kpod/inspect.go b/cmd/kpod/inspect.go index a70e285ac..e2f9ec97e 100644 --- a/cmd/kpod/inspect.go +++ b/cmd/kpod/inspect.go @@ -1,10 +1,12 @@ package main import ( + "encoding/json" + + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/projectatomic/libpod/cmd/kpod/formats" - "github.com/projectatomic/libpod/libkpod" - "github.com/projectatomic/libpod/libpod/images" + "github.com/projectatomic/libpod/libpod" "github.com/urfave/cli" ) @@ -53,56 +55,63 @@ func inspectCmd(c *cli.Context) error { return err } - itemType := c.String("type") - size := c.Bool("size") + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "error creating libpod runtime") + } + defer runtime.Shutdown(false) - switch itemType { - case inspectTypeContainer: - case inspectTypeImage: - case inspectAll: - default: + if c.String("type") != inspectTypeContainer && c.String("type") != inspectTypeImage && c.String("type") != inspectAll { return errors.Errorf("the only recognized types are %q, %q, and %q", inspectTypeContainer, inspectTypeImage, inspectAll) } name := args[0] - config, err := getConfig(c) - if err != nil { - return errors.Wrapf(err, "Could not get config") - } - server, err := libkpod.New(config) - if err != nil { - return errors.Wrapf(err, "could not get container server") - } - defer server.Shutdown() - if err = server.Update(); err != nil { - return errors.Wrapf(err, "could not update list of containers") - } - outputFormat := c.String("format") var data interface{} - switch itemType { + switch c.String("type") { case inspectTypeContainer: - data, err = server.GetContainerData(name, size) + ctr, err := runtime.LookupContainer(name) + if err != nil { + return errors.Wrapf(err, "error looking up container %q", name) + } + libpodInspectData, err := ctr.Inspect(c.Bool("size")) + if err != nil { + return errors.Wrapf(err, "error getting libpod container inspect data %q", ctr.ID) + } + data, err = getCtrInspectInfo(ctr, libpodInspectData) if err != nil { - return errors.Wrapf(err, "error parsing container data") + return errors.Wrapf(err, "error parsing container data %q", ctr.ID()) } case inspectTypeImage: - data, err = images.GetData(server.Store(), name) + image, err := runtime.GetImage(name) if err != nil { - return errors.Wrapf(err, "error parsing image data") + return errors.Wrapf(err, "error getting image %q", name) + } + data, err = runtime.GetImageInspectInfo(*image) + if err != nil { + return errors.Wrapf(err, "error parsing image data %q", image.ID) } case inspectAll: - ctrData, err := server.GetContainerData(name, size) + ctr, err := runtime.LookupContainer(name) if err != nil { - imgData, err := images.GetData(server.Store(), name) + image, err := runtime.GetImage(name) if err != nil { - return errors.Wrapf(err, "error parsing container or image data") + return errors.Wrapf(err, "error getting image %q", name) + } + data, err = runtime.GetImageInspectInfo(*image) + if err != nil { + return errors.Wrapf(err, "error parsing image data %q", image.ID) } - data = imgData - } else { - data = ctrData + libpodInspectData, err := ctr.Inspect(c.Bool("size")) + if err != nil { + return errors.Wrapf(err, "error getting libpod container inspect data %q", ctr.ID) + } + data, err = getCtrInspectInfo(ctr, libpodInspectData) + if err != nil { + return errors.Wrapf(err, "error parsing container data %q", ctr.ID) + } } } @@ -118,3 +127,236 @@ func inspectCmd(c *cli.Context) error { formats.Writer(out).Out() return nil } + +func getCtrInspectInfo(ctr *libpod.Container, ctrInspectData *libpod.ContainerInspectData) (*ContainerData, error) { + config := ctr.Config() + 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) + + artifact, err := ctr.GetArtifact("create-config") + if err != nil { + return nil, errors.Wrapf(err, "error getting artifact %q", ctr.ID()) + } + var createArtifact createConfig + if err := json.Unmarshal(artifact, &createArtifact); err != nil { + return nil, err + } + + data := &ContainerData{ + CtrInspectData: ctrInspectData, + HostConfig: &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: spec.Process.NoNewPrivileges, + ReadonlyRootfs: spec.Root.Readonly, + Runtime: ctr.RuntimeName(), + NetworkMode: string(createArtifact.NetMode), + IpcMode: string(createArtifact.IpcMode), + Cgroup: cgroup, + UTSMode: string(createArtifact.UtsMode), + UsernsMode: createArtifact.NsUser, + 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, + }, + Config: &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: createArtifact.Entrypoint, + }, + } + 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 +} + +// ContainerData holds the kpod inspect data for a container +type ContainerData struct { + CtrInspectData *libpod.ContainerInspectData `json:"CtrInspectData"` + HostConfig *HostConfig `json:"HostConfig"` + Config *CtrConfig `json:"Config"` +} + +// LogConfig holds the log information for a container +type LogConfig struct { + Type string `json:"Type"` // TODO + Config map[string]string `json:"Config"` //idk type, TODO +} + +// 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 map[string]struct{} `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"` + SecurityOpt []string `json:"SecurityOpt"` + UTSMode string `json:"UTSMode"` + UsernsMode string `json:"UsernsMode"` + ShmSize string `json:"ShmSize"` + Runtime string `json:"Runtime"` + ConsoleSize *specs.Box `json:"ConsoleSize"` + Isolation string `json:"Isolation"` //TODO + CPUShares *uint64 `json:"CPUSShares"` + Memory int64 `json:"Memory"` + NanoCpus int `json:"NanoCpus"` //check type, TODO + 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"` //check type, TODO + CPUPercent int `json:"CPUPercent"` //check type, TODO + IOMaximumIOps int `json:"IOMaximumIOps"` //check type, TODO + IOMaximumBandwidth int `json:"IOMaximumBandwidth"` //check type, TODO +} + +// 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"` +} |