summaryrefslogtreecommitdiff
path: root/cmd/podman/spec.go
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-05-16 12:38:17 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-05-21 19:26:56 +0000
commit82feafecdda8040432c008d9b79e4f973009adfc (patch)
tree8edffbe531bcf47c40b34cd003e4063142fbc84f /cmd/podman/spec.go
parent687b165a737742e1f1930cd9782002d857e07aaf (diff)
downloadpodman-82feafecdda8040432c008d9b79e4f973009adfc.tar.gz
podman-82feafecdda8040432c008d9b79e4f973009adfc.tar.bz2
podman-82feafecdda8040432c008d9b79e4f973009adfc.zip
podman create, start, getattachsocket
First pass at implement API endpoints for create and start. Signed-off-by: baude <bbaude@redhat.com> Closes: #805 Approved by: baude
Diffstat (limited to 'cmd/podman/spec.go')
-rw-r--r--cmd/podman/spec.go821
1 files changed, 0 insertions, 821 deletions
diff --git a/cmd/podman/spec.go b/cmd/podman/spec.go
deleted file mode 100644
index 747d76359..000000000
--- a/cmd/podman/spec.go
+++ /dev/null
@@ -1,821 +0,0 @@
-package main
-
-import (
- "io/ioutil"
- "os"
- "strconv"
- "strings"
-
- "github.com/cri-o/ocicni/pkg/ocicni"
- "github.com/docker/docker/daemon/caps"
- "github.com/docker/docker/pkg/mount"
- "github.com/docker/docker/profiles/seccomp"
- "github.com/docker/go-units"
- "github.com/opencontainers/runc/libcontainer/configs"
- "github.com/opencontainers/runc/libcontainer/devices"
- spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/opencontainers/runtime-tools/generate"
- "github.com/opencontainers/selinux/go-selinux/label"
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/libpod"
- ann "github.com/projectatomic/libpod/pkg/annotations"
- "github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
-)
-
-const cpuPeriod = 100000
-
-func u32Ptr(i int64) *uint32 { u := uint32(i); return &u }
-func fmPtr(i int64) *os.FileMode { fm := os.FileMode(i); return &fm }
-
-func blockAccessToKernelFilesystems(config *createConfig, g *generate.Generator) {
- if !config.Privileged {
- for _, mp := range []string{
- "/proc/kcore",
- "/proc/latency_stats",
- "/proc/timer_list",
- "/proc/timer_stats",
- "/proc/sched_debug",
- "/proc/scsi",
- "/sys/firmware",
- } {
- g.AddLinuxMaskedPaths(mp)
- }
-
- for _, rp := range []string{
- "/proc/asound",
- "/proc/bus",
- "/proc/fs",
- "/proc/irq",
- "/proc/sys",
- "/proc/sysrq-trigger",
- } {
- g.AddLinuxReadonlyPaths(rp)
- }
- }
-}
-
-func addPidNS(config *createConfig, g *generate.Generator) error {
- pidMode := config.PidMode
- if pidMode.IsHost() {
- return g.RemoveLinuxNamespace(string(spec.PIDNamespace))
- }
- if pidMode.IsContainer() {
- logrus.Debug("using container pidmode")
- }
- return nil
-}
-
-func addUserNS(config *createConfig, g *generate.Generator) error {
- if (len(config.IDMappings.UIDMap) > 0 || len(config.IDMappings.GIDMap) > 0) && !config.UsernsMode.IsHost() {
- g.AddOrReplaceLinuxNamespace(spec.UserNamespace, "")
- }
- return nil
-}
-
-func addNetNS(config *createConfig, g *generate.Generator) error {
- netMode := config.NetMode
- if netMode.IsHost() {
- logrus.Debug("Using host netmode")
- return g.RemoveLinuxNamespace(spec.NetworkNamespace)
- } else if netMode.IsNone() {
- logrus.Debug("Using none netmode")
- return nil
- } else if netMode.IsBridge() {
- logrus.Debug("Using bridge netmode")
- return nil
- } else if netMode.IsContainer() {
- logrus.Debug("Using container netmode")
- } else {
- return errors.Errorf("unknown network mode")
- }
- return nil
-}
-
-func addUTSNS(config *createConfig, g *generate.Generator) error {
- utsMode := config.UtsMode
- if utsMode.IsHost() {
- return g.RemoveLinuxNamespace(spec.UTSNamespace)
- }
- return nil
-}
-
-func addIpcNS(config *createConfig, g *generate.Generator) error {
- ipcMode := config.IpcMode
- if ipcMode.IsHost() {
- return g.RemoveLinuxNamespace(spec.IPCNamespace)
- }
- if ipcMode.IsContainer() {
- logrus.Debug("Using container ipcmode")
- }
-
- return nil
-}
-
-func addRlimits(config *createConfig, g *generate.Generator) error {
- var (
- ul *units.Ulimit
- err error
- )
-
- 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)
- }
-
- g.AddProcessRlimits("RLIMIT_"+strings.ToUpper(ul.Name), uint64(ul.Hard), uint64(ul.Soft))
- }
- return nil
-}
-
-func setupCapabilities(config *createConfig, configSpec *spec.Spec) error {
- var err error
- var caplist []string
- caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, config.CapAdd, config.CapDrop)
- if err != nil {
- return err
- }
-
- configSpec.Process.Capabilities.Bounding = caplist
- configSpec.Process.Capabilities.Permitted = caplist
- configSpec.Process.Capabilities.Inheritable = caplist
- configSpec.Process.Capabilities.Effective = caplist
- return nil
-}
-
-func addDevice(g *generate.Generator, device string) error {
- dev, err := devices.DeviceFromPath(device, "rwm")
- if err != nil {
- return errors.Wrapf(err, "%s is not a valid device", device)
- }
- linuxdev := spec.LinuxDevice{
- Path: dev.Path,
- Type: string(dev.Type),
- Major: dev.Major,
- Minor: dev.Minor,
- FileMode: &dev.FileMode,
- UID: &dev.Uid,
- GID: &dev.Gid,
- }
- g.AddDevice(linuxdev)
- g.AddLinuxResourcesDevice(true, string(dev.Type), &dev.Major, &dev.Minor, dev.Permissions)
- return nil
-}
-
-// Parses information needed to create a container into an OCI runtime spec
-func createConfigToOCISpec(config *createConfig) (*spec.Spec, error) {
- cgroupPerm := "ro"
- g := generate.New()
- g.HostSpecific = true
- addCgroup := true
- if config.Privileged {
- cgroupPerm = "rw"
- g.RemoveMount("/sys")
- sysMnt := spec.Mount{
- Destination: "/sys",
- Type: "sysfs",
- Source: "sysfs",
- Options: []string{"nosuid", "noexec", "nodev", "rw"},
- }
- g.AddMount(sysMnt)
- } else if !config.UsernsMode.IsHost() && config.NetMode.IsHost() {
- addCgroup = false
- g.RemoveMount("/sys")
- sysMnt := spec.Mount{
- Destination: "/sys",
- Type: "bind",
- Source: "/sys",
- Options: []string{"nosuid", "noexec", "nodev", "ro", "rbind"},
- }
- g.AddMount(sysMnt)
- }
-
- if addCgroup {
- cgroupMnt := spec.Mount{
- Destination: "/sys/fs/cgroup",
- Type: "cgroup",
- Source: "cgroup",
- Options: []string{"nosuid", "noexec", "nodev", "relatime", cgroupPerm},
- }
- g.AddMount(cgroupMnt)
- }
- g.SetProcessCwd(config.WorkDir)
- g.SetProcessArgs(config.Command)
- g.SetProcessTerminal(config.Tty)
-
- 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)
- }
- for sysctlKey, sysctlVal := range config.Sysctl {
- g.AddLinuxSysctl(sysctlKey, sysctlVal)
- }
- g.AddProcessEnv("container", "podman")
-
- // 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.MemorySwap != 0 {
- g.SetLinuxResourcesMemorySwap(config.Resources.MemorySwap)
- }
- if config.Resources.KernelMemory != 0 {
- g.SetLinuxResourcesMemoryKernel(config.Resources.KernelMemory)
- }
- if config.Resources.MemorySwappiness != -1 {
- g.SetLinuxResourcesMemorySwappiness(uint64(config.Resources.MemorySwappiness))
- }
- 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.CPUQuota != 0 {
- g.SetLinuxResourcesCPUQuota(config.Resources.CPUQuota)
- }
- if config.Resources.CPUPeriod != 0 {
- g.SetLinuxResourcesCPUPeriod(config.Resources.CPUPeriod)
- }
- if config.Resources.CPUs != 0 {
- g.SetLinuxResourcesCPUPeriod(cpuPeriod)
- g.SetLinuxResourcesCPUQuota(int64(config.Resources.CPUs * cpuPeriod))
- }
- if config.Resources.CPURtRuntime != 0 {
- g.SetLinuxResourcesCPURealtimeRuntime(config.Resources.CPURtRuntime)
- }
- if config.Resources.CPURtPeriod != 0 {
- g.SetLinuxResourcesCPURealtimePeriod(config.Resources.CPURtPeriod)
- }
- if config.Resources.CPUsetCPUs != "" {
- g.SetLinuxResourcesCPUCpus(config.Resources.CPUsetCPUs)
- }
- if config.Resources.CPUsetMems != "" {
- g.SetLinuxResourcesCPUMems(config.Resources.CPUsetMems)
- }
-
- // Devices
- if config.Privileged {
- // If privileged, we need to add all the host devices to the
- // spec. We do not add the user provided ones because we are
- // already adding them all.
- if err := config.AddPrivilegedDevices(&g); err != nil {
- return nil, err
- }
- } else {
- for _, device := range config.Devices {
- if err := addDevice(&g, device); err != nil {
- return nil, err
- }
- }
- }
-
- for _, uidmap := range config.IDMappings.UIDMap {
- g.AddLinuxUIDMapping(uint32(uidmap.HostID), uint32(uidmap.ContainerID), uint32(uidmap.Size))
- }
- for _, gidmap := range config.IDMappings.GIDMap {
- g.AddLinuxGIDMapping(uint32(gidmap.HostID), uint32(gidmap.ContainerID), uint32(gidmap.Size))
- }
- // SECURITY OPTS
- g.SetProcessNoNewPrivileges(config.NoNewPrivs)
- 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)
- }
-
- for _, i := range config.Tmpfs {
- // Default options if nothing passed
- options := []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"}
- spliti := strings.SplitN(i, ":", 2)
- if len(spliti) > 1 {
- if _, _, err := mount.ParseTmpfsOptions(spliti[1]); err != nil {
- return nil, err
- }
- options = strings.Split(spliti[1], ",")
- }
- tmpfsMnt := spec.Mount{
- Destination: spliti[0],
- Type: "tmpfs",
- Source: "tmpfs",
- Options: append(options, "tmpcopyup"),
- }
- g.AddMount(tmpfsMnt)
- }
-
- for name, val := range config.Env {
- g.AddProcessEnv(name, val)
- }
-
- if err := addRlimits(config, &g); err != nil {
- return nil, err
- }
-
- if err := addPidNS(config, &g); err != nil {
- return nil, err
- }
-
- if err := addUserNS(config, &g); err != nil {
- return nil, err
- }
-
- if err := addNetNS(config, &g); err != nil {
- return nil, err
- }
-
- if err := addUTSNS(config, &g); err != nil {
- return nil, err
- }
-
- if err := addIpcNS(config, &g); err != nil {
- return nil, err
- }
- configSpec := g.Spec()
-
- // HANDLE CAPABILITIES
- // NOTE: Must happen before SECCOMP
- if !config.Privileged {
- if err := setupCapabilities(config, configSpec); err != nil {
- return nil, err
- }
- } else {
- g.SetupPrivileged(true)
- }
-
- // HANDLE SECCOMP
- if config.SeccompProfilePath != "unconfined" {
- if config.SeccompProfilePath != "" {
- seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
- if err != nil {
- return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- seccompConfig, err := seccomp.LoadProfile(string(seccompProfile), configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- configSpec.Linux.Seccomp = seccompConfig
- } else {
- seccompConfig, err := seccomp.GetDefaultProfile(configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- configSpec.Linux.Seccomp = seccompConfig
- }
- }
-
- // Clear default Seccomp profile from Generator for privileged containers
- if config.SeccompProfilePath == "unconfined" || config.Privileged {
- configSpec.Linux.Seccomp = nil
- }
-
- // BIND MOUNTS
- mounts, err := config.GetVolumeMounts(configSpec.Mounts)
- if err != nil {
- return nil, errors.Wrapf(err, "error getting volume mounts")
- }
- configSpec.Mounts = append(configSpec.Mounts, mounts...)
- for _, mount := range configSpec.Mounts {
- for _, opt := range mount.Options {
- switch opt {
- case "private", "rprivate", "slave", "rslave", "shared", "rshared":
- if err := g.SetLinuxRootPropagation(opt); err != nil {
- return nil, errors.Wrapf(err, "error setting root propagation for %q", mount.Destination)
- }
- }
- }
- }
-
- // BLOCK IO
- blkio, err := config.createBlockIO()
- if err != nil {
- return nil, errors.Wrapf(err, "error creating block io")
- }
- if blkio != nil {
- configSpec.Linux.Resources.BlockIO = blkio
- }
-
- /*
- //Annotations
- Resources: &configSpec.LinuxResources{
- BlockIO: &blkio,
- //HugepageLimits:
- Network: &configSpec.LinuxNetwork{
- // ClassID *uint32
- // Priorites []LinuxInterfacePriority
- },
- },
- //CgroupsPath:
- //Namespaces: []LinuxNamespace
- // DefaultAction:
- // Architectures
- // Syscalls:
- },
- // RootfsPropagation
- // MaskedPaths
- // ReadonlyPaths:
- // IntelRdt
- },
- }
- */
- return configSpec, nil
-}
-
-const (
- bps = iota
- iops
-)
-
-func (c *createConfig) createBlockIO() (*spec.LinuxBlockIO, error) {
- bio := &spec.LinuxBlockIO{}
- bio.Weight = &c.Resources.BlkioWeight
- if len(c.Resources.BlkioWeightDevice) > 0 {
- var lwds []spec.LinuxWeightDevice
- for _, i := range c.Resources.BlkioWeightDevice {
- wd, err := validateweightDevice(i)
- if err != nil {
- return bio, errors.Wrapf(err, "invalid values for blkio-weight-device")
- }
- wdStat, err := getStatFromPath(wd.path)
- if err != nil {
- return bio, errors.Wrapf(err, "error getting stat from path %q", wd.path)
- }
- lwd := spec.LinuxWeightDevice{
- Weight: &wd.weight,
- }
- lwd.Major = int64(unix.Major(wdStat.Rdev))
- lwd.Minor = int64(unix.Minor(wdStat.Rdev))
- lwds = append(lwds, lwd)
- }
- bio.WeightDevice = lwds
- }
- if len(c.Resources.DeviceReadBps) > 0 {
- readBps, err := makeThrottleArray(c.Resources.DeviceReadBps, bps)
- if err != nil {
- return bio, err
- }
- bio.ThrottleReadBpsDevice = readBps
- }
- if len(c.Resources.DeviceWriteBps) > 0 {
- writeBpds, err := makeThrottleArray(c.Resources.DeviceWriteBps, bps)
- if err != nil {
- return bio, err
- }
- bio.ThrottleWriteBpsDevice = writeBpds
- }
- if len(c.Resources.DeviceReadIOps) > 0 {
- readIOps, err := makeThrottleArray(c.Resources.DeviceReadIOps, iops)
- if err != nil {
- return bio, err
- }
- bio.ThrottleReadIOPSDevice = readIOps
- }
- if len(c.Resources.DeviceWriteIOps) > 0 {
- writeIOps, err := makeThrottleArray(c.Resources.DeviceWriteIOps, iops)
- if err != nil {
- return bio, err
- }
- bio.ThrottleWriteIOPSDevice = writeIOps
- }
- return bio, nil
-}
-
-func makeThrottleArray(throttleInput []string, rateType int) ([]spec.LinuxThrottleDevice, error) {
- var (
- ltds []spec.LinuxThrottleDevice
- t *throttleDevice
- err error
- )
- for _, i := range throttleInput {
- if rateType == bps {
- t, err = validateBpsDevice(i)
- } else {
- t, err = validateIOpsDevice(i)
- }
- if err != nil {
- return []spec.LinuxThrottleDevice{}, err
- }
- ltdStat, err := getStatFromPath(t.path)
- if err != nil {
- return ltds, errors.Wrapf(err, "error getting stat from path %q", t.path)
- }
- ltd := spec.LinuxThrottleDevice{
- Rate: t.rate,
- }
- ltd.Major = int64(unix.Major(ltdStat.Rdev))
- ltd.Minor = int64(unix.Minor(ltdStat.Rdev))
- ltds = append(ltds, ltd)
- }
- return ltds, nil
-}
-
-// GetAnnotations returns the all the annotations for the container
-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 {
- a["io.kubernetes.cri-o.TTY"] = "true"
- }
- return a
-}
-
-func getDefaultAnnotations() map[string]string {
- var annotations map[string]string
- annotations = make(map[string]string)
- annotations[ann.Annotations] = ""
- annotations[ann.ContainerID] = ""
- annotations[ann.ContainerName] = ""
- annotations[ann.ContainerType] = "sandbox"
- annotations[ann.Created] = ""
- annotations[ann.HostName] = ""
- annotations[ann.IP] = ""
- annotations[ann.Image] = ""
- annotations[ann.ImageName] = ""
- annotations[ann.ImageRef] = ""
- annotations[ann.KubeName] = ""
- annotations[ann.Labels] = ""
- annotations[ann.LogPath] = ""
- annotations[ann.Metadata] = ""
- annotations[ann.Name] = ""
- annotations[ann.PrivilegedRuntime] = ""
- annotations[ann.ResolvPath] = ""
- annotations[ann.HostnamePath] = ""
- annotations[ann.SandboxID] = ""
- annotations[ann.SandboxName] = ""
- annotations[ann.ShmPath] = ""
- annotations[ann.MountPoint] = ""
- annotations[ann.TrustedSandbox] = ""
- annotations[ann.TTY] = "false"
- annotations[ann.Stdin] = ""
- annotations[ann.StdinOnce] = ""
- annotations[ann.Volumes] = ""
-
- return annotations
-}
-
-//GetVolumeMounts takes user provided input for bind mounts and creates Mount structs
-func (c *createConfig) GetVolumeMounts(specMounts []spec.Mount) ([]spec.Mount, error) {
- var m []spec.Mount
- var options []string
- for _, i := range c.Volumes {
- // We need to handle SELinux options better here, specifically :Z
- spliti := strings.Split(i, ":")
- if len(spliti) > 2 {
- options = strings.Split(spliti[2], ",")
- }
- if libpod.MountExists(specMounts, spliti[1]) {
- continue
- }
- options = append(options, "rbind")
- var foundrw, foundro, foundz, foundZ bool
- var rootProp string
- for _, opt := range options {
- switch opt {
- case "rw":
- foundrw = true
- case "ro":
- foundro = true
- case "z":
- foundz = true
- case "Z":
- foundZ = true
- case "private", "rprivate", "slave", "rslave", "shared", "rshared":
- rootProp = opt
- }
- }
- if !foundrw && !foundro {
- options = append(options, "rw")
- }
- if foundz {
- 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 {
- return nil, errors.Wrapf(err, "relabel failed %q", spliti[0])
- }
- }
- if rootProp == "" {
- options = append(options, "private")
- }
-
- m = append(m, spec.Mount{
- Destination: spliti[1],
- Type: string(TypeBind),
- Source: spliti[0],
- Options: options,
- })
- }
-
- // volumes from image config
- if c.ImageVolumeType != "tmpfs" {
- return m, nil
- }
- for vol := range c.BuiltinImgVolumes {
- if libpod.MountExists(specMounts, vol) {
- continue
- }
- mount := spec.Mount{
- Destination: vol,
- Type: string(TypeTmpfs),
- Source: string(TypeTmpfs),
- Options: []string{"rw", "noexec", "nosuid", "nodev", "tmpcopyup"},
- }
- m = append(m, mount)
- }
- return m, nil
-}
-
-//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 {
- // Default options if nothing passed
- options := []string{"rw", "noexec", "nosuid", "nodev", "size=65536k"}
- spliti := strings.Split(i, ":")
- destPath := spliti[0]
- if len(spliti) > 1 {
- options = strings.Split(spliti[1], ",")
- }
- m = append(m, spec.Mount{
- Destination: destPath,
- Type: string(TypeTmpfs),
- Options: options,
- Source: string(TypeTmpfs),
- })
- }
- return m
-}
-
-func (c *createConfig) GetContainerCreateOptions() ([]libpod.CtrCreateOption, error) {
- var options []libpod.CtrCreateOption
- var portBindings []ocicni.PortMapping
- var err error
-
- // Uncomment after talking to mheon about unimplemented funcs
- // options = append(options, libpod.WithLabels(c.labels))
-
- 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 len(c.PortBindings) > 0 {
- portBindings, err = c.CreatePortBindings()
- if err != nil {
- return nil, errors.Wrapf(err, "unable to create port bindings")
- }
- }
-
- if len(c.Volumes) != 0 {
- // Volumes consist of multiple, comma-delineated fields
- // The image spec only includes one part of that, so drop the
- // others, if they are included
- volumes := make([]string, 0, len(c.Volumes))
- for _, vol := range c.Volumes {
- volumes = append(volumes, strings.SplitN(vol, ":", 2)[0])
- }
-
- options = append(options, libpod.WithUserVolumes(volumes))
- }
-
- if len(c.Command) != 0 {
- options = append(options, libpod.WithCommand(c.Command))
- }
-
- // Add entrypoint unconditionally
- // If it's empty it's because it was explicitly set to "" or the image
- // does not have one
- options = append(options, libpod.WithEntrypoint(c.Entrypoint))
-
- if c.NetMode.IsContainer() {
- connectedCtr, err := c.Runtime.LookupContainer(c.NetMode.ConnectedContainer())
- if err != nil {
- return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
- }
- options = append(options, libpod.WithNetNSFrom(connectedCtr))
- } else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
- postConfigureNetNS := (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
- options = append(options, libpod.WithNetNS([]ocicni.PortMapping{}, postConfigureNetNS))
- options = append(options, libpod.WithNetNS(portBindings, postConfigureNetNS))
- }
-
- if c.PidMode.IsContainer() {
- connectedCtr, err := c.Runtime.LookupContainer(c.PidMode.Container())
- if err != nil {
- return nil, errors.Wrapf(err, "container %q not found", c.PidMode.Container())
- }
-
- options = append(options, libpod.WithPIDNSFrom(connectedCtr))
- }
- if c.IpcMode.IsContainer() {
- connectedCtr, err := c.Runtime.LookupContainer(c.IpcMode.Container())
- if err != nil {
- return nil, errors.Wrapf(err, "container %q not found", c.IpcMode.Container())
- }
-
- options = append(options, libpod.WithIPCNSFrom(connectedCtr))
- }
-
- options = append(options, libpod.WithStopSignal(c.StopSignal))
- options = append(options, libpod.WithStopTimeout(c.StopTimeout))
- if len(c.DNSSearch) > 0 {
- options = append(options, libpod.WithDNSSearch(c.DNSSearch))
- }
- if len(c.DNSServers) > 0 {
- options = append(options, libpod.WithDNS(c.DNSServers))
- }
- if len(c.DNSOpt) > 0 {
- options = append(options, libpod.WithDNSOption(c.DNSOpt))
- }
- if len(c.HostAdd) > 0 {
- options = append(options, libpod.WithHosts(c.HostAdd))
- }
- logPath := getLoggingPath(c.LogDriverOpt)
- if logPath != "" {
- options = append(options, libpod.WithLogPath(logPath))
- }
-
- options = append(options, libpod.WithPrivileged(c.Privileged))
- return options, nil
-}
-
-func getStatFromPath(path string) (unix.Stat_t, error) {
- s := unix.Stat_t{}
- err := unix.Stat(path, &s)
- return s, err
-}
-
-// CreatePortBindings iterates ports mappings and exposed ports into a format CNI understands
-func (c *createConfig) CreatePortBindings() ([]ocicni.PortMapping, error) {
- var portBindings []ocicni.PortMapping
- for containerPb, hostPb := range c.PortBindings {
- var pm ocicni.PortMapping
- pm.ContainerPort = int32(containerPb.Int())
- for _, i := range hostPb {
- var hostPort int
- var err error
- pm.HostIP = i.HostIP
- if i.HostPort == "" {
- hostPort = containerPb.Int()
- } else {
- hostPort, err = strconv.Atoi(i.HostPort)
- if err != nil {
- return nil, errors.Wrapf(err, "unable to convert host port to integer")
- }
- }
-
- pm.HostPort = int32(hostPort)
- // CNI requires us to make both udp and tcp structs
- pm.Protocol = "udp"
- portBindings = append(portBindings, pm)
- pm.Protocol = "tcp"
- portBindings = append(portBindings, pm)
- }
- }
- return portBindings, nil
-}
-
-// AddPrivilegedDevices iterates through host devices and adds all
-// host devices to the spec
-func (c *createConfig) AddPrivilegedDevices(g *generate.Generator) error {
- hostDevices, err := devices.HostDevices()
- if err != nil {
- return err
- }
- g.ClearLinuxDevices()
- for _, d := range hostDevices {
- g.AddDevice(Device(d))
- }
- g.AddLinuxResourcesDevice(true, "", nil, nil, "rwm")
- return nil
-}
-
-// Device transforms a libcontainer configs.Device to a specs.LinuxDevice object.
-func Device(d *configs.Device) spec.LinuxDevice {
- return spec.LinuxDevice{
- Type: string(d.Type),
- Path: d.Path,
- Major: d.Major,
- Minor: d.Minor,
- FileMode: fmPtr(int64(d.FileMode)),
- UID: u32Ptr(int64(d.Uid)),
- GID: u32Ptr(int64(d.Gid)),
- }
-}