diff options
Diffstat (limited to 'cmd/kpod')
-rw-r--r-- | cmd/kpod/create.go | 363 | ||||
-rw-r--r-- | cmd/kpod/create_cli.go | 106 | ||||
-rw-r--r-- | cmd/kpod/images.go | 33 | ||||
-rw-r--r-- | cmd/kpod/inspect.go | 308 | ||||
-rw-r--r-- | cmd/kpod/run.go | 12 | ||||
-rw-r--r-- | cmd/kpod/spec.go | 162 | ||||
-rw-r--r-- | cmd/kpod/spec_test.go | 4 |
7 files changed, 620 insertions, 368 deletions
diff --git a/cmd/kpod/create.go b/cmd/kpod/create.go index fc6e519fa..3548ad7df 100644 --- a/cmd/kpod/create.go +++ b/cmd/kpod/create.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "os" "strconv" @@ -36,91 +37,92 @@ var ( ) type createResourceConfig struct { - blkioWeight uint16 // blkio-weight - blkioWeightDevice []string // blkio-weight-device - cpuPeriod uint64 // cpu-period - cpuQuota int64 // cpu-quota - cpuRtPeriod uint64 // cpu-rt-period - cpuRtRuntime int64 // cpu-rt-runtime - cpuShares uint64 // cpu-shares - cpus string // cpus - cpusetCpus string - cpusetMems string // cpuset-mems - deviceReadBps []string // device-read-bps - deviceReadIOps []string // device-read-iops - deviceWriteBps []string // device-write-bps - deviceWriteIOps []string // device-write-iops - disableOomKiller bool // oom-kill-disable - kernelMemory int64 // kernel-memory - memory int64 //memory - memoryReservation int64 // memory-reservation - memorySwap int64 //memory-swap - memorySwappiness int // memory-swappiness - oomScoreAdj int //oom-score-adj - pidsLimit int64 // pids-limit - shmSize string - ulimit []string //ulimit + BlkioWeight uint16 // blkio-weight + BlkioWeightDevice []string // blkio-weight-device + CpuPeriod uint64 // cpu-period + CpuQuota int64 // cpu-quota + CpuRtPeriod uint64 // cpu-rt-period + CpuRtRuntime int64 // cpu-rt-runtime + CpuShares uint64 // cpu-shares + Cpus string // cpus + CpusetCpus string + CpusetMems string // cpuset-mems + DeviceReadBps []string // device-read-bps + DeviceReadIOps []string // device-read-iops + DeviceWriteBps []string // device-write-bps + DeviceWriteIOps []string // device-write-iops + DisableOomKiller bool // oom-kill-disable + KernelMemory int64 // kernel-memory + Memory int64 //memory + MemoryReservation int64 // memory-reservation + MemorySwap int64 //memory-swap + MemorySwappiness int // memory-swappiness + OomScoreAdj int //oom-score-adj + PidsLimit int64 // pids-limit + ShmSize string + Ulimit []string //ulimit } type createConfig struct { - runtime *libpod.Runtime - args []string - capAdd []string // cap-add - capDrop []string // cap-drop - cidFile string - cgroupParent string // cgroup-parent - command []string - detach bool // detach - devices []*pb.Device // device - dnsOpt []string //dns-opt - dnsSearch []string //dns-search - dnsServers []string //dns - entrypoint string //entrypoint - env map[string]string //env - expose []string //expose - groupAdd []uint32 // group-add - hostname string //hostname - image string - interactive bool //interactive - ipcMode container.IpcMode //ipc - ip6Address string //ipv6 - ipAddress string //ip - labels map[string]string //label - linkLocalIP []string // link-local-ip - logDriver string // log-driver - logDriverOpt []string // log-opt - macAddress string //mac-address - name string //name - netMode container.NetworkMode //net - network string //network - networkAlias []string //network-alias - pidMode container.PidMode //pid - nsUser string - pod string //pod - privileged bool //privileged - publish []string //publish - publishAll bool //publish-all - readOnlyRootfs bool //read-only - resources createResourceConfig - rm bool //rm - shmDir string - sigProxy bool //sig-proxy - stopSignal string // stop-signal - stopTimeout int64 // stop-timeout - storageOpts []string //storage-opt - sysctl map[string]string //sysctl - tmpfs []string // tmpfs - tty bool //tty - user uint32 //user - group uint32 // group - utsMode container.UTSMode //uts - volumes []string //volume - workDir string //workdir - mountLabel string //SecurityOpts - processLabel string //SecurityOpts - noNewPrivileges bool //SecurityOpts - apparmorProfile string //SecurityOpts - seccompProfilePath string //SecurityOpts + Runtime *libpod.Runtime + Args []string + CapAdd []string // cap-add + CapDrop []string // cap-drop + CidFile string + CgroupParent string // cgroup-parent + Command []string + Detach bool // detach + Devices []*pb.Device // device + DnsOpt []string //dns-opt + DnsSearch []string //dns-search + DnsServers []string //dns + Entrypoint string //entrypoint + Env map[string]string //env + Expose []string //expose + GroupAdd []uint32 // group-add + Hostname string //hostname + Image string + Interactive bool //interactive + IpcMode container.IpcMode //ipc + Ip6Address string //ipv6 + IpAddress string //ip + Labels map[string]string //label + LinkLocalIP []string // link-local-ip + LogDriver string // log-driver + LogDriverOpt []string // log-opt + MacAddress string //mac-address + Name string //name + NetMode container.NetworkMode //net + Network string //network + NetworkAlias []string //network-alias + PidMode container.PidMode //pid + NsUser string + Pod string //pod + Privileged bool //privileged + Publish []string //publish + PublishAll bool //publish-all + ReadOnlyRootfs bool //read-only + Resources createResourceConfig + Rm bool //rm + ShmDir string + SigProxy bool //sig-proxy + StopSignal string // stop-signal + StopTimeout int64 // stop-timeout + StorageOpts []string //storage-opt + Sysctl map[string]string //sysctl + Tmpfs []string // tmpfs + Tty bool //tty + User uint32 //user + Group uint32 // group + UtsMode container.UTSMode //uts + Volumes []string //volume + WorkDir string //workdir + MountLabel string //SecurityOpts + ProcessLabel string //SecurityOpts + NoNewPrivileges bool //SecurityOpts + ApparmorProfile string //SecurityOpts + SeccompProfilePath string //SecurityOpts + SecurityOpts []string } var createDescription = "Creates a new container from the given image or" + @@ -160,7 +162,7 @@ func createCmd(c *cli.Context) error { } // Deal with the image after all the args have been checked - createImage := runtime.NewImage(createConfig.image) + createImage := runtime.NewImage(createConfig.Image) createImage.LocalName, _ = createImage.GetLocalImageName() if createImage.LocalName == "" { // The image wasnt found by the user input'd name or its fqname @@ -203,13 +205,21 @@ func createCmd(c *cli.Context) error { } // Gather up the options for NewContainer which consist of With... funcs options = append(options, libpod.WithRootFSFromImage(imageID, imageName, false)) - options = append(options, libpod.WithSELinuxLabels(createConfig.processLabel, createConfig.mountLabel)) - options = append(options, libpod.WithShmDir(createConfig.shmDir)) + options = append(options, libpod.WithSELinuxLabels(createConfig.ProcessLabel, createConfig.MountLabel)) + options = append(options, libpod.WithShmDir(createConfig.ShmDir)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err } + createConfigJSON, err := json.Marshal(createConfig) + if err != nil { + return err + } + if err := ctr.AddArtifact("create-config", createConfigJSON); err != nil { + return err + } + logrus.Debug("new container created ", ctr.ID()) if c.String("cidfile") != "" { @@ -229,29 +239,29 @@ func parseSecurityOpt(config *createConfig, securityOpts []string) error { err error ) - if config.pidMode.IsHost() { + if config.PidMode.IsHost() { labelOpts = append(labelOpts, label.DisableSecOpt()...) - } else if config.pidMode.IsContainer() { - ctr, err := config.runtime.LookupContainer(config.pidMode.Container()) + } else if config.PidMode.IsContainer() { + ctr, err := config.Runtime.LookupContainer(config.PidMode.Container()) if err != nil { - return errors.Wrapf(err, "container %q not found", config.pidMode.Container()) + return errors.Wrapf(err, "container %q not found", config.PidMode.Container()) } labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...) } - if config.ipcMode.IsHost() { + if config.IpcMode.IsHost() { labelOpts = append(labelOpts, label.DisableSecOpt()...) - } else if config.ipcMode.IsContainer() { - ctr, err := config.runtime.LookupContainer(config.ipcMode.Container()) + } else if config.IpcMode.IsContainer() { + ctr, err := config.Runtime.LookupContainer(config.IpcMode.Container()) if err != nil { - return errors.Wrapf(err, "container %q not found", config.ipcMode.Container()) + return errors.Wrapf(err, "container %q not found", config.IpcMode.Container()) } labelOpts = append(labelOpts, label.DupSecOpt(ctr.ProcessLabel())...) } for _, opt := range securityOpts { if opt == "no-new-privileges" { - config.noNewPrivileges = true + config.NoNewPrivileges = true } else { con := strings.SplitN(opt, "=", 2) if len(con) != 2 { @@ -262,25 +272,25 @@ func parseSecurityOpt(config *createConfig, securityOpts []string) error { case "label": labelOpts = append(labelOpts, con[1]) case "apparmor": - config.apparmorProfile = con[1] + config.ApparmorProfile = con[1] case "seccomp": - config.seccompProfilePath = con[1] + config.SeccompProfilePath = con[1] default: return fmt.Errorf("Invalid --security-opt 2: %q", opt) } } } - if config.seccompProfilePath == "" { + if config.SeccompProfilePath == "" { if _, err := os.Stat(seccompDefaultPath); err != nil { if !os.IsNotExist(err) { return errors.Wrapf(err, "can't check if %q exists", seccompDefaultPath) } } else { - config.seccompProfilePath = seccompDefaultPath + config.SeccompProfilePath = seccompDefaultPath } } - config.processLabel, config.mountLabel, err = label.InitLabels(labelOpts) + config.ProcessLabel, config.MountLabel, err = label.InitLabels(labelOpts) return err } @@ -403,88 +413,89 @@ func parseCreateOpts(c *cli.Context, runtime *libpod.Runtime) (*createConfig, er } config := &createConfig{ - runtime: runtime, - capAdd: c.StringSlice("cap-add"), - capDrop: c.StringSlice("cap-drop"), - cgroupParent: c.String("cgroup-parent"), - command: command, - detach: c.Bool("detach"), - dnsOpt: c.StringSlice("dns-opt"), - dnsSearch: c.StringSlice("dns-search"), - dnsServers: c.StringSlice("dns"), - entrypoint: c.String("entrypoint"), - env: env, - expose: c.StringSlice("expose"), - groupAdd: groupAdd, - hostname: c.String("hostname"), - image: image, - interactive: c.Bool("interactive"), - ip6Address: c.String("ipv6"), - ipAddress: c.String("ip"), - labels: labels, - linkLocalIP: c.StringSlice("link-local-ip"), - logDriver: c.String("log-driver"), - logDriverOpt: c.StringSlice("log-opt"), - macAddress: c.String("mac-address"), - name: c.String("name"), - network: c.String("network"), - networkAlias: c.StringSlice("network-alias"), - ipcMode: ipcMode, - netMode: container.NetworkMode(c.String("network")), - utsMode: utsMode, - pidMode: pidMode, - pod: c.String("pod"), - privileged: c.Bool("privileged"), - publish: c.StringSlice("publish"), - publishAll: c.Bool("publish-all"), - readOnlyRootfs: c.Bool("read-only"), - resources: createResourceConfig{ - blkioWeight: blkioWeight, - blkioWeightDevice: c.StringSlice("blkio-weight-device"), - cpuShares: c.Uint64("cpu-shares"), - cpuPeriod: c.Uint64("cpu-period"), - cpusetCpus: c.String("cpu-period"), - cpusetMems: c.String("cpuset-mems"), - cpuQuota: c.Int64("cpu-quota"), - cpuRtPeriod: c.Uint64("cpu-rt-period"), - cpuRtRuntime: c.Int64("cpu-rt-runtime"), - cpus: c.String("cpus"), - deviceReadBps: c.StringSlice("device-read-bps"), - deviceReadIOps: c.StringSlice("device-read-iops"), - deviceWriteBps: c.StringSlice("device-write-bps"), - deviceWriteIOps: c.StringSlice("device-write-iops"), - disableOomKiller: c.Bool("oom-kill-disable"), - shmSize: c.String("shm-size"), - memory: memoryLimit, - memoryReservation: memoryReservation, - memorySwap: memorySwap, - memorySwappiness: c.Int("memory-swappiness"), - kernelMemory: memoryKernel, - oomScoreAdj: c.Int("oom-score-adj"), - - pidsLimit: c.Int64("pids-limit"), - ulimit: c.StringSlice("ulimit"), + Runtime: runtime, + CapAdd: c.StringSlice("cap-add"), + CapDrop: c.StringSlice("cap-drop"), + CgroupParent: c.String("cgroup-parent"), + Command: command, + Detach: c.Bool("detach"), + DnsOpt: c.StringSlice("dns-opt"), + DnsSearch: c.StringSlice("dns-search"), + DnsServers: c.StringSlice("dns"), + Entrypoint: c.String("entrypoint"), + Env: env, + Expose: c.StringSlice("expose"), + GroupAdd: groupAdd, + Hostname: c.String("hostname"), + Image: image, + Interactive: c.Bool("interactive"), + Ip6Address: c.String("ipv6"), + IpAddress: c.String("ip"), + Labels: labels, + LinkLocalIP: c.StringSlice("link-local-ip"), + LogDriver: c.String("log-driver"), + LogDriverOpt: c.StringSlice("log-opt"), + MacAddress: c.String("mac-address"), + Name: c.String("name"), + Network: c.String("network"), + NetworkAlias: c.StringSlice("network-alias"), + IpcMode: ipcMode, + NetMode: container.NetworkMode(c.String("network")), + UtsMode: utsMode, + PidMode: pidMode, + Pod: c.String("pod"), + Privileged: c.Bool("privileged"), + Publish: c.StringSlice("publish"), + PublishAll: c.Bool("publish-all"), + ReadOnlyRootfs: c.Bool("read-only"), + Resources: createResourceConfig{ + BlkioWeight: blkioWeight, + BlkioWeightDevice: c.StringSlice("blkio-weight-device"), + CpuShares: c.Uint64("cpu-shares"), + CpuPeriod: c.Uint64("cpu-period"), + CpusetCpus: c.String("cpu-period"), + CpusetMems: c.String("cpuset-mems"), + CpuQuota: c.Int64("cpu-quota"), + CpuRtPeriod: c.Uint64("cpu-rt-period"), + CpuRtRuntime: c.Int64("cpu-rt-runtime"), + Cpus: c.String("cpus"), + DeviceReadBps: c.StringSlice("device-read-bps"), + DeviceReadIOps: c.StringSlice("device-read-iops"), + DeviceWriteBps: c.StringSlice("device-write-bps"), + DeviceWriteIOps: c.StringSlice("device-write-iops"), + DisableOomKiller: c.Bool("oom-kill-disable"), + ShmSize: c.String("shm-size"), + Memory: memoryLimit, + MemoryReservation: memoryReservation, + MemorySwap: memorySwap, + MemorySwappiness: c.Int("memory-swappiness"), + KernelMemory: memoryKernel, + OomScoreAdj: c.Int("oom-score-adj"), + + PidsLimit: c.Int64("pids-limit"), + Ulimit: c.StringSlice("ulimit"), }, - rm: c.Bool("rm"), - shmDir: shmDir, - sigProxy: c.Bool("sig-proxy"), - stopSignal: c.String("stop-signal"), - stopTimeout: c.Int64("stop-timeout"), - storageOpts: c.StringSlice("storage-opt"), - sysctl: sysctl, - tmpfs: c.StringSlice("tmpfs"), - tty: tty, - user: uid, - group: gid, - volumes: c.StringSlice("volume"), - workDir: c.String("workdir"), - } - - if !config.privileged { + Rm: c.Bool("rm"), + ShmDir: shmDir, + SigProxy: c.Bool("sig-proxy"), + StopSignal: c.String("stop-signal"), + StopTimeout: c.Int64("stop-timeout"), + StorageOpts: c.StringSlice("storage-opt"), + Sysctl: sysctl, + Tmpfs: c.StringSlice("tmpfs"), + Tty: tty, + User: uid, + Group: gid, + Volumes: c.StringSlice("volume"), + WorkDir: c.String("workdir"), + } + + if !config.Privileged { if err := parseSecurityOpt(config, c.StringSlice("security-opt")); err != nil { return nil, err } } + config.SecurityOpts = c.StringSlice("security-opt") warnings, err := verifyContainerResources(config, false) if err != nil { return nil, err diff --git a/cmd/kpod/create_cli.go b/cmd/kpod/create_cli.go index 9686b89a7..a162cb319 100644 --- a/cmd/kpod/create_cli.go +++ b/cmd/kpod/create_cli.go @@ -111,131 +111,131 @@ func verifyContainerResources(config *createConfig, update bool) ([]string, erro sysInfo := sysinfo.New(true) // memory subsystem checks and adjustments - if config.resources.memory != 0 && config.resources.memory < linuxMinMemory { + if config.Resources.Memory != 0 && config.Resources.Memory < linuxMinMemory { return warnings, fmt.Errorf("minimum memory limit allowed is 4MB") } - if config.resources.memory > 0 && !sysInfo.MemoryLimit { + if config.Resources.Memory > 0 && !sysInfo.MemoryLimit { warnings = addWarning(warnings, "Your kernel does not support memory limit capabilities or the cgroup is not mounted. Limitation discarded.") - config.resources.memory = 0 - config.resources.memorySwap = -1 + config.Resources.Memory = 0 + config.Resources.MemorySwap = -1 } - if config.resources.memory > 0 && config.resources.memorySwap != -1 && !sysInfo.SwapLimit { + if config.Resources.Memory > 0 && config.Resources.MemorySwap != -1 && !sysInfo.SwapLimit { warnings = addWarning(warnings, "Your kernel does not support swap limit capabilities,or the cgroup is not mounted. Memory limited without swap.") - config.resources.memorySwap = -1 + config.Resources.MemorySwap = -1 } - if config.resources.memory > 0 && config.resources.memorySwap > 0 && config.resources.memorySwap < config.resources.memory { + if config.Resources.Memory > 0 && config.Resources.MemorySwap > 0 && config.Resources.MemorySwap < config.Resources.Memory { return warnings, fmt.Errorf("minimum memoryswap limit should be larger than memory limit, see usage") } - if config.resources.memory == 0 && config.resources.memorySwap > 0 && !update { - return warnings, fmt.Errorf("you should always set the Memory limit when using Memoryswap limit, see usage") + if config.Resources.Memory == 0 && config.Resources.MemorySwap > 0 && !update { + return warnings, fmt.Errorf("you should always set the memory limit when using memoryswap limit, see usage") } - if config.resources.memorySwappiness != -1 { + if config.Resources.MemorySwappiness != -1 { if !sysInfo.MemorySwappiness { msg := "Your kernel does not support memory swappiness capabilities, or the cgroup is not mounted. Memory swappiness discarded." warnings = addWarning(warnings, msg) - config.resources.memorySwappiness = -1 + config.Resources.MemorySwappiness = -1 } else { - swappiness := config.resources.memorySwappiness + swappiness := config.Resources.MemorySwappiness if swappiness < -1 || swappiness > 100 { return warnings, fmt.Errorf("invalid value: %v, valid memory swappiness range is 0-100", swappiness) } } } - if config.resources.memoryReservation > 0 && !sysInfo.MemoryReservation { + if config.Resources.MemoryReservation > 0 && !sysInfo.MemoryReservation { warnings = addWarning(warnings, "Your kernel does not support memory soft limit capabilities or the cgroup is not mounted. Limitation discarded.") - config.resources.memoryReservation = 0 + config.Resources.MemoryReservation = 0 } - if config.resources.memoryReservation > 0 && config.resources.memoryReservation < linuxMinMemory { + if config.Resources.MemoryReservation > 0 && config.Resources.MemoryReservation < linuxMinMemory { return warnings, fmt.Errorf("minimum memory reservation allowed is 4MB") } - if config.resources.memory > 0 && config.resources.memoryReservation > 0 && config.resources.memory < config.resources.memoryReservation { + if config.Resources.Memory > 0 && config.Resources.MemoryReservation > 0 && config.Resources.Memory < config.Resources.MemoryReservation { return warnings, fmt.Errorf("minimum memory limit can not be less than memory reservation limit, see usage") } - if config.resources.kernelMemory > 0 && !sysInfo.KernelMemory { + if config.Resources.KernelMemory > 0 && !sysInfo.KernelMemory { warnings = addWarning(warnings, "Your kernel does not support kernel memory limit capabilities or the cgroup is not mounted. Limitation discarded.") - config.resources.kernelMemory = 0 + config.Resources.KernelMemory = 0 } - if config.resources.kernelMemory > 0 && config.resources.kernelMemory < linuxMinMemory { + if config.Resources.KernelMemory > 0 && config.Resources.KernelMemory < linuxMinMemory { return warnings, fmt.Errorf("minimum kernel memory limit allowed is 4MB") } - if config.resources.disableOomKiller == true && !sysInfo.OomKillDisable { + if config.Resources.DisableOomKiller == true && !sysInfo.OomKillDisable { // only produce warnings if the setting wasn't to *disable* the OOM Kill; no point // warning the caller if they already wanted the feature to be off warnings = addWarning(warnings, "Your kernel does not support OomKillDisable. OomKillDisable discarded.") - config.resources.disableOomKiller = false + config.Resources.DisableOomKiller = false } - if config.resources.pidsLimit != 0 && !sysInfo.PidsLimit { + if config.Resources.PidsLimit != 0 && !sysInfo.PidsLimit { warnings = addWarning(warnings, "Your kernel does not support pids limit capabilities or the cgroup is not mounted. PIDs limit discarded.") - config.resources.pidsLimit = 0 + config.Resources.PidsLimit = 0 } - if config.resources.cpuShares > 0 && !sysInfo.CPUShares { + if config.Resources.CpuShares > 0 && !sysInfo.CPUShares { warnings = addWarning(warnings, "Your kernel does not support CPU shares or the cgroup is not mounted. Shares discarded.") - config.resources.cpuShares = 0 + config.Resources.CpuShares = 0 } - if config.resources.cpuPeriod > 0 && !sysInfo.CPUCfsPeriod { + if config.Resources.CpuPeriod > 0 && !sysInfo.CPUCfsPeriod { warnings = addWarning(warnings, "Your kernel does not support CPU cfs period or the cgroup is not mounted. Period discarded.") - config.resources.cpuPeriod = 0 + config.Resources.CpuPeriod = 0 } - if config.resources.cpuPeriod != 0 && (config.resources.cpuPeriod < 1000 || config.resources.cpuPeriod > 1000000) { + if config.Resources.CpuPeriod != 0 && (config.Resources.CpuPeriod < 1000 || config.Resources.CpuPeriod > 1000000) { return warnings, fmt.Errorf("CPU cfs period can not be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)") } - if config.resources.cpuQuota > 0 && !sysInfo.CPUCfsQuota { + if config.Resources.CpuQuota > 0 && !sysInfo.CPUCfsQuota { warnings = addWarning(warnings, "Your kernel does not support CPU cfs quota or the cgroup is not mounted. Quota discarded.") - config.resources.cpuQuota = 0 + config.Resources.CpuQuota = 0 } - if config.resources.cpuQuota > 0 && config.resources.cpuQuota < 1000 { + if config.Resources.CpuQuota > 0 && config.Resources.CpuQuota < 1000 { return warnings, fmt.Errorf("CPU cfs quota can not be less than 1ms (i.e. 1000)") } // cpuset subsystem checks and adjustments - if (config.resources.cpusetCpus != "" || config.resources.cpusetMems != "") && !sysInfo.Cpuset { + if (config.Resources.CpusetCpus != "" || config.Resources.CpusetMems != "") && !sysInfo.Cpuset { warnings = addWarning(warnings, "Your kernel does not support cpuset or the cgroup is not mounted. Cpuset discarded.") - config.resources.cpusetCpus = "" - config.resources.cpusetMems = "" + config.Resources.CpusetCpus = "" + config.Resources.CpusetMems = "" } - cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(config.resources.cpusetCpus) + cpusAvailable, err := sysInfo.IsCpusetCpusAvailable(config.Resources.CpusetCpus) if err != nil { - return warnings, fmt.Errorf("invalid value %s for cpuset cpus", config.resources.cpusetCpus) + return warnings, fmt.Errorf("invalid value %s for cpuset cpus", config.Resources.CpusetCpus) } if !cpusAvailable { - return warnings, fmt.Errorf("requested CPUs are not available - requested %s, available: %s", config.resources.cpusetCpus, sysInfo.Cpus) + return warnings, fmt.Errorf("requested CPUs are not available - requested %s, available: %s", config.Resources.CpusetCpus, sysInfo.Cpus) } - memsAvailable, err := sysInfo.IsCpusetMemsAvailable(config.resources.cpusetMems) + memsAvailable, err := sysInfo.IsCpusetMemsAvailable(config.Resources.CpusetMems) if err != nil { - return warnings, fmt.Errorf("invalid value %s for cpuset mems", config.resources.cpusetMems) + return warnings, fmt.Errorf("invalid value %s for cpuset mems", config.Resources.CpusetMems) } if !memsAvailable { - return warnings, fmt.Errorf("requested memory nodes are not available - requested %s, available: %s", config.resources.cpusetMems, sysInfo.Mems) + return warnings, fmt.Errorf("requested memory nodes are not available - requested %s, available: %s", config.Resources.CpusetMems, sysInfo.Mems) } // blkio subsystem checks and adjustments - if config.resources.blkioWeight > 0 && !sysInfo.BlkioWeight { + if config.Resources.BlkioWeight > 0 && !sysInfo.BlkioWeight { warnings = addWarning(warnings, "Your kernel does not support Block I/O weight or the cgroup is not mounted. Weight discarded.") - config.resources.blkioWeight = 0 + config.Resources.BlkioWeight = 0 } - if config.resources.blkioWeight > 0 && (config.resources.blkioWeight < 10 || config.resources.blkioWeight > 1000) { + if config.Resources.BlkioWeight > 0 && (config.Resources.BlkioWeight < 10 || config.Resources.BlkioWeight > 1000) { return warnings, fmt.Errorf("range of blkio weight is from 10 to 1000") } - if len(config.resources.blkioWeightDevice) > 0 && !sysInfo.BlkioWeightDevice { + if len(config.Resources.BlkioWeightDevice) > 0 && !sysInfo.BlkioWeightDevice { warnings = addWarning(warnings, "Your kernel does not support Block I/O weight_device or the cgroup is not mounted. Weight-device discarded.") - config.resources.blkioWeightDevice = []string{} + config.Resources.BlkioWeightDevice = []string{} } - if len(config.resources.deviceReadBps) > 0 && !sysInfo.BlkioReadBpsDevice { + if len(config.Resources.DeviceReadBps) > 0 && !sysInfo.BlkioReadBpsDevice { warnings = addWarning(warnings, "Your kernel does not support BPS Block I/O read limit or the cgroup is not mounted. Block I/O BPS read limit discarded") - config.resources.deviceReadBps = []string{} + config.Resources.DeviceReadBps = []string{} } - if len(config.resources.deviceWriteBps) > 0 && !sysInfo.BlkioWriteBpsDevice { + if len(config.Resources.DeviceWriteBps) > 0 && !sysInfo.BlkioWriteBpsDevice { warnings = addWarning(warnings, "Your kernel does not support BPS Block I/O write limit or the cgroup is not mounted. Block I/O BPS write limit discarded.") - config.resources.deviceWriteBps = []string{} + config.Resources.DeviceWriteBps = []string{} } - if len(config.resources.deviceReadIOps) > 0 && !sysInfo.BlkioReadIOpsDevice { + if len(config.Resources.DeviceReadIOps) > 0 && !sysInfo.BlkioReadIOpsDevice { warnings = addWarning(warnings, "Your kernel does not support IOPS Block read limit or the cgroup is not mounted. Block I/O IOPS read limit discarded.") - config.resources.deviceReadIOps = []string{} + config.Resources.DeviceReadIOps = []string{} } - if len(config.resources.deviceWriteIOps) > 0 && !sysInfo.BlkioWriteIOpsDevice { + if len(config.Resources.DeviceWriteIOps) > 0 && !sysInfo.BlkioWriteIOpsDevice { warnings = addWarning(warnings, "Your kernel does not support IOPS Block I/O write limit or the cgroup is not mounted. Block I/O IOPS write limit discarded.") - config.resources.deviceWriteIOps = []string{} + config.Resources.DeviceWriteIOps = []string{} } return warnings, nil diff --git a/cmd/kpod/images.go b/cmd/kpod/images.go index 7b020c984..1cf69c96d 100644 --- a/cmd/kpod/images.go +++ b/cmd/kpod/images.go @@ -6,7 +6,6 @@ import ( "strings" "time" - "github.com/containers/image/types" "github.com/containers/storage" "github.com/docker/go-units" digest "github.com/opencontainers/go-digest" @@ -208,18 +207,18 @@ func getImagesTemplateOutput(runtime *libpod.Runtime, images []*storage.Image, o } } - info, imageDigest, size, _ := runtime.InfoAndDigestAndSize(*img) - if info != nil { - createdTime = info.Created + imgData, _ := runtime.GetImageInspectInfo(*img) + if imgData != nil { + createdTime = *imgData.Created } params := imagesTemplateParams{ Repository: repository, Tag: tag, ID: imageID, - Digest: imageDigest, + Digest: imgData.Digest, Created: units.HumanDuration(time.Since((createdTime))) + " ago", - Size: units.HumanSizeWithPrecision(float64(size), 3), + Size: units.HumanSizeWithPrecision(float64(imgData.Size), 3), } imagesOutput = append(imagesOutput, params) } @@ -231,17 +230,17 @@ func getImagesJSONOutput(runtime *libpod.Runtime, images []*storage.Image) (imag for _, img := range images { createdTime := img.Created - info, imageDigest, size, _ := runtime.InfoAndDigestAndSize(*img) - if info != nil { - createdTime = info.Created + imgData, _ := runtime.GetImageInspectInfo(*img) + if imgData != nil { + createdTime = *imgData.Created } params := imagesJSONParams{ ID: img.ID, Name: img.Names, - Digest: imageDigest, + Digest: imgData.Digest, Created: createdTime, - Size: size, + Size: imgData.Size, } imagesOutput = append(imagesOutput, params) } @@ -274,7 +273,7 @@ func generateImagesOutput(runtime *libpod.Runtime, images []*storage.Image, opts func generateImagesFilter(params *libpod.ImageFilterParams, filterType string) libpod.ImageFilter { switch filterType { case "label": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.Label == "" { return true } @@ -291,21 +290,21 @@ func generateImagesFilter(params *libpod.ImageFilterParams, filterType string) l return false } case "before-image": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.BeforeImage.IsZero() { return true } return info.Created.Before(params.BeforeImage) } case "since-image": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.SinceImage.IsZero() { return true } return info.Created.After(params.SinceImage) } case "dangling": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.Dangling == "" { return true } @@ -318,14 +317,14 @@ func generateImagesFilter(params *libpod.ImageFilterParams, filterType string) l return false } case "reference": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.ReferencePattern == "" { return true } return libpod.MatchesReference(params.ImageName, params.ReferencePattern) } case "image-input": - return func(image *storage.Image, info *types.ImageInspectInfo) bool { + return func(image *storage.Image, info *libpod.ImageData) bool { if params == nil || params.ImageInput == "" { return true } 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"` +} diff --git a/cmd/kpod/run.go b/cmd/kpod/run.go index 7e078f66a..6142983ad 100644 --- a/cmd/kpod/run.go +++ b/cmd/kpod/run.go @@ -39,7 +39,7 @@ func runCmd(c *cli.Context) error { return err } - createImage := runtime.NewImage(createConfig.image) + createImage := runtime.NewImage(createConfig.Image) createImage.LocalName, _ = createImage.GetLocalImageName() if createImage.LocalName == "" { // The image wasnt found by the user input'd name or its fqname @@ -89,8 +89,8 @@ func runCmd(c *cli.Context) error { // Gather up the options for NewContainer which consist of With... funcs options = append(options, libpod.WithRootFSFromImage(imageID, imageName, false)) - options = append(options, libpod.WithSELinuxLabels(createConfig.processLabel, createConfig.mountLabel)) - options = append(options, libpod.WithShmDir(createConfig.shmDir)) + options = append(options, libpod.WithSELinuxLabels(createConfig.ProcessLabel, createConfig.MountLabel)) + options = append(options, libpod.WithShmDir(createConfig.ShmDir)) ctr, err := runtime.NewContainer(runtimeSpec, options...) if err != nil { return err @@ -114,7 +114,7 @@ func runCmd(c *cli.Context) error { // to finish before exiting main var wg sync.WaitGroup - if !createConfig.detach { + if !createConfig.Detach { // We increment the wg counter because we need to do the attach wg.Add(1) // Attach to the running container @@ -133,13 +133,13 @@ func runCmd(c *cli.Context) error { if err := ctr.Start(); err != nil { return errors.Wrapf(err, "unable to start container %q", ctr.ID()) } - if createConfig.detach { + if createConfig.Detach { fmt.Printf("%s\n", ctr.ID()) return nil } wg.Wait() - if createConfig.rm { + if createConfig.Rm { return runtime.RemoveContainer(ctr, true) } return ctr.CleanupStorage() diff --git a/cmd/kpod/spec.go b/cmd/kpod/spec.go index b200ed77a..4e00f04ff 100644 --- a/cmd/kpod/spec.go +++ b/cmd/kpod/spec.go @@ -20,7 +20,7 @@ import ( ) func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator) { - if !config.privileged { + if !config.Privileged { for _, mp := range []string{ "/proc/kcore", "/proc/latency_stats", @@ -47,12 +47,12 @@ func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator) } func addPidNS(config *createConfig, g *generate.Generator) error { - pidMode := config.pidMode + pidMode := config.PidMode if pidMode.IsHost() { return g.RemoveLinuxNamespace(libpod.PIDNamespace) } if pidMode.IsContainer() { - ctr, err := config.runtime.LookupContainer(pidMode.Container()) + ctr, err := config.Runtime.LookupContainer(pidMode.Container()) if err != nil { return errors.Wrapf(err, "container %q not found", pidMode.Container()) } @@ -69,7 +69,7 @@ func addPidNS(config *createConfig, g *generate.Generator) error { } func addNetNS(config *createConfig, g *generate.Generator) error { - netMode := config.netMode + netMode := config.NetMode if netMode.IsHost() { return g.RemoveLinuxNamespace(libpod.NetNamespace) } @@ -80,7 +80,7 @@ func addNetNS(config *createConfig, g *generate.Generator) error { return libpod.ErrNotImplemented } if netMode.IsContainer() { - ctr, err := config.runtime.LookupContainer(netMode.ConnectedContainer()) + ctr, err := config.Runtime.LookupContainer(netMode.ConnectedContainer()) if err != nil { return errors.Wrapf(err, "container %q not found", netMode.ConnectedContainer()) } @@ -97,7 +97,7 @@ func addNetNS(config *createConfig, g *generate.Generator) error { } func addUTSNS(config *createConfig, g *generate.Generator) error { - utsMode := config.utsMode + utsMode := config.UtsMode if utsMode.IsHost() { return g.RemoveLinuxNamespace(libpod.UTSNamespace) } @@ -105,12 +105,12 @@ func addUTSNS(config *createConfig, g *generate.Generator) error { } func addIpcNS(config *createConfig, g *generate.Generator) error { - ipcMode := config.ipcMode + ipcMode := config.IpcMode if ipcMode.IsHost() { return g.RemoveLinuxNamespace(libpod.IPCNamespace) } if ipcMode.IsContainer() { - ctr, err := config.runtime.LookupContainer(ipcMode.Container()) + ctr, err := config.Runtime.LookupContainer(ipcMode.Container()) if err != nil { return errors.Wrapf(err, "container %q not found", ipcMode.Container()) } @@ -133,7 +133,7 @@ func addRlimits(config *createConfig, g *generate.Generator) error { err error ) - for _, u := range config.resources.ulimit { + for _, u := range config.Resources.Ulimit { if ul, err = units.ParseUlimit(u); err != nil { return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u) } @@ -146,10 +146,10 @@ func addRlimits(config *createConfig, g *generate.Generator) error { func setupCapabilities(config *createConfig, configSpec *spec.Spec) error { var err error var caplist []string - if config.privileged { + if config.Privileged { caplist = caps.GetAllCapabilities() } else { - caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, config.capAdd, config.capDrop) + caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, config.CapAdd, config.CapDrop) if err != nil { return err } @@ -166,85 +166,85 @@ func setupCapabilities(config *createConfig, configSpec *spec.Spec) error { func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { g := generate.New() g.AddCgroupsMount("ro") - g.SetProcessCwd(config.workDir) - g.SetProcessArgs(config.command) - g.SetProcessTerminal(config.tty) + g.SetProcessCwd(config.WorkDir) + g.SetProcessArgs(config.Command) + g.SetProcessTerminal(config.Tty) // User and Group must go together - g.SetProcessUID(config.user) - g.SetProcessGID(config.group) - for _, gid := range config.groupAdd { + g.SetProcessUID(config.User) + g.SetProcessGID(config.Group) + for _, gid := range config.GroupAdd { g.AddProcessAdditionalGid(gid) } for key, val := range config.GetAnnotations() { g.AddAnnotation(key, val) } - g.SetRootReadonly(config.readOnlyRootfs) - g.SetHostname(config.hostname) - if config.hostname != "" { - g.AddProcessEnv("HOSTNAME", config.hostname) + g.SetRootReadonly(config.ReadOnlyRootfs) + g.SetHostname(config.Hostname) + if config.Hostname != "" { + g.AddProcessEnv("HOSTNAME", config.Hostname) } - for _, sysctl := range config.sysctl { + for _, sysctl := range config.Sysctl { s := strings.SplitN(sysctl, "=", 2) g.AddLinuxSysctl(s[0], s[1]) } // RESOURCES - MEMORY - if config.resources.memory != 0 { - g.SetLinuxResourcesMemoryLimit(config.resources.memory) + if config.Resources.Memory != 0 { + g.SetLinuxResourcesMemoryLimit(config.Resources.Memory) } - if config.resources.memoryReservation != 0 { - g.SetLinuxResourcesMemoryReservation(config.resources.memoryReservation) + if config.Resources.MemoryReservation != 0 { + g.SetLinuxResourcesMemoryReservation(config.Resources.MemoryReservation) } - if config.resources.memorySwap != 0 { - g.SetLinuxResourcesMemorySwap(config.resources.memorySwap) + if config.Resources.MemorySwap != 0 { + g.SetLinuxResourcesMemorySwap(config.Resources.MemorySwap) } - if config.resources.kernelMemory != 0 { - g.SetLinuxResourcesMemoryKernel(config.resources.kernelMemory) + if config.Resources.KernelMemory != 0 { + g.SetLinuxResourcesMemoryKernel(config.Resources.KernelMemory) } - if config.resources.memorySwappiness != -1 { - g.SetLinuxResourcesMemorySwappiness(uint64(config.resources.memorySwappiness)) + if config.Resources.MemorySwappiness != -1 { + g.SetLinuxResourcesMemorySwappiness(uint64(config.Resources.MemorySwappiness)) } - g.SetLinuxResourcesMemoryDisableOOMKiller(config.resources.disableOomKiller) - g.SetProcessOOMScoreAdj(config.resources.oomScoreAdj) + g.SetLinuxResourcesMemoryDisableOOMKiller(config.Resources.DisableOomKiller) + g.SetProcessOOMScoreAdj(config.Resources.OomScoreAdj) // RESOURCES - CPU - if config.resources.cpuShares != 0 { - g.SetLinuxResourcesCPUShares(config.resources.cpuShares) + if config.Resources.CpuShares != 0 { + g.SetLinuxResourcesCPUShares(config.Resources.CpuShares) } - if config.resources.cpuQuota != 0 { - g.SetLinuxResourcesCPUQuota(config.resources.cpuQuota) + if config.Resources.CpuQuota != 0 { + g.SetLinuxResourcesCPUQuota(config.Resources.CpuQuota) } - if config.resources.cpuPeriod != 0 { - g.SetLinuxResourcesCPUPeriod(config.resources.cpuPeriod) + if config.Resources.CpuPeriod != 0 { + g.SetLinuxResourcesCPUPeriod(config.Resources.CpuPeriod) } - if config.resources.cpuRtRuntime != 0 { - g.SetLinuxResourcesCPURealtimeRuntime(config.resources.cpuRtRuntime) + if config.Resources.CpuRtRuntime != 0 { + g.SetLinuxResourcesCPURealtimeRuntime(config.Resources.CpuRtRuntime) } - if config.resources.cpuRtPeriod != 0 { - g.SetLinuxResourcesCPURealtimePeriod(config.resources.cpuRtPeriod) + if config.Resources.CpuRtPeriod != 0 { + g.SetLinuxResourcesCPURealtimePeriod(config.Resources.CpuRtPeriod) } - if config.resources.cpus != "" { - g.SetLinuxResourcesCPUCpus(config.resources.cpus) + if config.Resources.Cpus != "" { + g.SetLinuxResourcesCPUCpus(config.Resources.Cpus) } - if config.resources.cpusetMems != "" { - g.SetLinuxResourcesCPUMems(config.resources.cpusetMems) + if config.Resources.CpusetMems != "" { + g.SetLinuxResourcesCPUMems(config.Resources.CpusetMems) } // SECURITY OPTS - g.SetProcessNoNewPrivileges(config.noNewPrivileges) - g.SetProcessApparmorProfile(config.apparmorProfile) - g.SetProcessSelinuxLabel(config.processLabel) - g.SetLinuxMountLabel(config.mountLabel) + g.SetProcessNoNewPrivileges(config.NoNewPrivileges) + g.SetProcessApparmorProfile(config.ApparmorProfile) + g.SetProcessSelinuxLabel(config.ProcessLabel) + g.SetLinuxMountLabel(config.MountLabel) blockAccessToKernelFilesystems(config, &g) // RESOURCES - PIDS - if config.resources.pidsLimit != 0 { - g.SetLinuxResourcesPidsLimit(config.resources.pidsLimit) + if config.Resources.PidsLimit != 0 { + g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit) } - for _, i := range config.tmpfs { + for _, i := range config.Tmpfs { options := []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"} spliti := strings.SplitN(i, ":", 2) if len(spliti) > 1 { @@ -257,7 +257,7 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { g.AddTmpfsMount(spliti[0], options) } - for name, val := range config.env { + for name, val := range config.Env { g.AddProcessEnv(name, val) } @@ -282,14 +282,14 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { } configSpec := g.Spec() - if config.seccompProfilePath != "" && config.seccompProfilePath != "unconfined" { - seccompProfile, err := ioutil.ReadFile(config.seccompProfilePath) + if config.SeccompProfilePath != "" && config.SeccompProfilePath != "unconfined" { + seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath) if err != nil { - return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.seccompProfilePath) + return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath) } var seccompConfig spec.LinuxSeccomp if err := json.Unmarshal(seccompProfile, &seccompConfig); err != nil { - return nil, errors.Wrapf(err, "decoding seccomp profile (%s) failed", config.seccompProfilePath) + return nil, errors.Wrapf(err, "decoding seccomp profile (%s) failed", config.SeccompProfilePath) } configSpec.Linux.Seccomp = &seccompConfig } @@ -347,10 +347,10 @@ func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) { func (c *createConfig) CreateBlockIO() (spec.LinuxBlockIO, error) { bio := spec.LinuxBlockIO{} - bio.Weight = &c.resources.blkioWeight - if len(c.resources.blkioWeightDevice) > 0 { + bio.Weight = &c.Resources.BlkioWeight + if len(c.Resources.BlkioWeightDevice) > 0 { var lwds []spec.LinuxWeightDevice - for _, i := range c.resources.blkioWeightDevice { + for _, i := range c.Resources.BlkioWeightDevice { wd, err := validateweightDevice(i) if err != nil { return bio, errors.Wrapf(err, "invalid values for blkio-weight-device") @@ -364,29 +364,29 @@ func (c *createConfig) CreateBlockIO() (spec.LinuxBlockIO, error) { lwds = append(lwds, lwd) } } - if len(c.resources.deviceReadBps) > 0 { - readBps, err := makeThrottleArray(c.resources.deviceReadBps) + if len(c.Resources.DeviceReadBps) > 0 { + readBps, err := makeThrottleArray(c.Resources.DeviceReadBps) if err != nil { return bio, err } bio.ThrottleReadBpsDevice = readBps } - if len(c.resources.deviceWriteBps) > 0 { - writeBpds, err := makeThrottleArray(c.resources.deviceWriteBps) + if len(c.Resources.DeviceWriteBps) > 0 { + writeBpds, err := makeThrottleArray(c.Resources.DeviceWriteBps) if err != nil { return bio, err } bio.ThrottleWriteBpsDevice = writeBpds } - if len(c.resources.deviceReadIOps) > 0 { - readIOps, err := makeThrottleArray(c.resources.deviceReadIOps) + if len(c.Resources.DeviceReadIOps) > 0 { + readIOps, err := makeThrottleArray(c.Resources.DeviceReadIOps) if err != nil { return bio, err } bio.ThrottleReadIOPSDevice = readIOps } - if len(c.resources.deviceWriteIOps) > 0 { - writeIOps, err := makeThrottleArray(c.resources.deviceWriteIOps) + if len(c.Resources.DeviceWriteIOps) > 0 { + writeIOps, err := makeThrottleArray(c.Resources.DeviceWriteIOps) if err != nil { return bio, err } @@ -401,7 +401,7 @@ func (c *createConfig) GetAnnotations() map[string]string { a := getDefaultAnnotations() // TODO - Which annotations do we want added by default // TODO - This should be added to the DB long term - if c.tty { + if c.Tty { a["io.kubernetes.cri-o.TTY"] = "true" } return a @@ -445,7 +445,7 @@ func getDefaultAnnotations() map[string]string { func (c *createConfig) GetVolumeMounts() ([]spec.Mount, error) { var m []spec.Mount var options []string - for _, i := range c.volumes { + for _, i := range c.Volumes { // We need to handle SELinux options better here, specifically :Z spliti := strings.Split(i, ":") if len(spliti) > 2 { @@ -472,12 +472,12 @@ func (c *createConfig) GetVolumeMounts() ([]spec.Mount, error) { options = append(options, "rw") } if foundz { - if err := label.Relabel(spliti[0], c.mountLabel, true); err != nil { + if err := label.Relabel(spliti[0], c.MountLabel, true); err != nil { return nil, errors.Wrapf(err, "relabel failed %q", spliti[0]) } } if foundZ { - if err := label.Relabel(spliti[0], c.mountLabel, false); err != nil { + if err := label.Relabel(spliti[0], c.MountLabel, false); err != nil { return nil, errors.Wrapf(err, "relabel failed %q", spliti[0]) } } @@ -495,10 +495,10 @@ func (c *createConfig) GetVolumeMounts() ([]spec.Mount, error) { return m, nil } -//GetTmpfsMounts takes user provided input for tmpfs mounts and creates Mount structs +//GetTmpfsMounts takes user provided input for Tmpfs mounts and creates Mount structs func (c *createConfig) GetTmpfsMounts() []spec.Mount { var m []spec.Mount - for _, i := range c.tmpfs { + for _, i := range c.Tmpfs { // Default options if nothing passed options := []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"} spliti := strings.Split(i, ":") @@ -522,12 +522,12 @@ func (c *createConfig) GetContainerCreateOptions() ([]libpod.CtrCreateOption, er // Uncomment after talking to mheon about unimplemented funcs // options = append(options, libpod.WithLabels(c.labels)) - if c.interactive { + if c.Interactive { options = append(options, libpod.WithStdin()) } - if c.name != "" { - logrus.Debugf("appending name %s", c.name) - options = append(options, libpod.WithName(c.name)) + if c.Name != "" { + logrus.Debugf("appending name %s", c.Name) + options = append(options, libpod.WithName(c.Name)) } return options, nil diff --git a/cmd/kpod/spec_test.go b/cmd/kpod/spec_test.go index 799d6b235..01e1a4ad3 100644 --- a/cmd/kpod/spec_test.go +++ b/cmd/kpod/spec_test.go @@ -16,7 +16,7 @@ func TestCreateConfig_GetVolumeMounts(t *testing.T) { Options: []string{"ro", "rbind", "rprivate"}, } config := createConfig{ - volumes: []string{"foobar:/foobar:ro"}, + Volumes: []string{"foobar:/foobar:ro"}, } specMount, err := config.GetVolumeMounts() assert.NoError(t, err) @@ -31,7 +31,7 @@ func TestCreateConfig_GetTmpfsMounts(t *testing.T) { Options: []string{"rw", "size=787448k", "mode=1777"}, } config := createConfig{ - tmpfs: []string{"/homer:rw,size=787448k,mode=1777"}, + Tmpfs: []string{"/homer:rw,size=787448k,mode=1777"}, } tmpfsMount := config.GetTmpfsMounts() assert.True(t, reflect.DeepEqual(data, tmpfsMount[0])) |