diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/pods.go | 4 | ||||
-rw-r--r-- | pkg/domain/entities/pods.go | 67 | ||||
-rw-r--r-- | pkg/env/env.go | 5 | ||||
-rw-r--r-- | pkg/specgen/generate/config_linux.go | 1 | ||||
-rw-r--r-- | pkg/specgen/generate/container_create.go | 28 | ||||
-rw-r--r-- | pkg/specgen/generate/oci.go | 7 | ||||
-rw-r--r-- | pkg/specgen/podspecgen.go | 2 | ||||
-rw-r--r-- | pkg/specgen/specgen.go | 4 |
8 files changed, 72 insertions, 46 deletions
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 1f03e121e..9f46ecc52 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -41,8 +41,8 @@ func PodCreate(w http.ResponseWriter, r *http.Request) { return } if !psg.NoInfra { - infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}} // options for pulling the image and FillOutSpec - err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings) + infraOptions := &entities.ContainerCreateOptions{ImageVolume: "bind", IsInfra: true, Net: &entities.NetOptions{}, Devices: psg.Devices} // options for pulling the image and FillOutSpec + err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen")) return diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go index a74725c63..f0c88d77e 100644 --- a/pkg/domain/entities/pods.go +++ b/pkg/domain/entities/pods.go @@ -112,26 +112,28 @@ type PodSpec struct { PodSpecGen specgen.PodSpecGenerator } -// PodCreateOptions provides all possible options for creating a pod and its infra container +// PodCreateOptions provides all possible options for creating a pod and its infra container. +// The JSON tags below are made to match the respective field in ContainerCreateOptions for the purpose of mapping. // swagger:model PodCreateOptions type PodCreateOptions struct { - CGroupParent string - CreateCommand []string - Hostname string - Infra bool - InfraImage string - InfraName string - InfraCommand string - InfraConmonPidFile string - Labels map[string]string - Name string - Net *NetOptions - Share []string - Pid string - Cpus float64 - CpusetCpus string - Userns specgen.Namespace - Volume []string + CGroupParent string `json:"cgroup_parent,omitempty"` + CreateCommand []string `json:"create_command,omitempty"` + Devices []string `json:"devices,omitempty"` + Hostname string `json:"hostname,omitempty"` + Infra bool `json:"infra,omitempty"` + InfraImage string `json:"infra_image,omitempty"` + InfraName string `json:"container_name,omitempty"` + InfraCommand *string `json:"container_command,omitempty"` + InfraConmonPidFile string `json:"container_conmon_pidfile,omitempty"` + Labels map[string]string `json:"labels,omitempty"` + Name string `json:"name,omitempty"` + Net *NetOptions `json:"net,omitempty"` + Share []string `json:"share,omitempty"` + Pid string `json:"pid,omitempty"` + Cpus float64 `json:"cpus,omitempty"` + CpusetCpus string `json:"cpuset_cpus,omitempty"` + Userns specgen.Namespace `json:"-"` + Volume []string `json:"volume,omitempty"` } // PodLogsOptions describes the options to extract pod logs. @@ -152,24 +154,24 @@ type ContainerCreateOptions struct { CapDrop []string CgroupNS string CGroupsMode string - CGroupParent string + CGroupParent string `json:"cgroup_parent,omitempty"` CIDFile string - ConmonPIDFile string + ConmonPIDFile string `json:"container_conmon_pidfile,omitempty"` CPUPeriod uint64 CPUQuota int64 CPURTPeriod uint64 CPURTRuntime int64 CPUShares uint64 - CPUS float64 - CPUSetCPUs string + CPUS float64 `json:"cpus,omitempty"` + CPUSetCPUs string `json:"cpuset_cpus,omitempty"` CPUSetMems string - Devices []string + Devices []string `json:"devices,omitempty"` DeviceCGroupRule []string DeviceReadBPs []string DeviceReadIOPs []string DeviceWriteBPs []string DeviceWriteIOPs []string - Entrypoint *string + Entrypoint *string `json:"container_command,omitempty"` Env []string EnvHost bool EnvFile []string @@ -181,7 +183,7 @@ type ContainerCreateOptions struct { HealthRetries uint HealthStartPeriod string HealthTimeout string - Hostname string + Hostname string `json:"hostname,omitempty"` HTTPProxy bool ImageVolume string Init bool @@ -198,14 +200,14 @@ type ContainerCreateOptions struct { MemoryReservation string MemorySwap string MemorySwappiness int64 - Name string + Name string `json:"container_name,omitempty"` NoHealthCheck bool OOMKillDisable bool OOMScoreAdj int Arch string OS string Variant string - PID string + PID string `json:"pid,omitempty"` PIDsLimit *int64 Platform string Pod string @@ -244,17 +246,17 @@ type ContainerCreateOptions struct { UIDMap []string Ulimit []string User string - UserNS string + UserNS string `json:"-"` UTS string Mount []string - Volume []string + Volume []string `json:"volume,omitempty"` VolumesFrom []string Workdir string SeccompPolicy string PidFile string IsInfra bool - Net *NetOptions + Net *NetOptions `json:"net,omitempty"` CgroupConf []string } @@ -294,9 +296,10 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod s.Pid = out s.Hostname = p.Hostname s.Labels = p.Labels + s.Devices = p.Devices s.NoInfra = !p.Infra - if len(p.InfraCommand) > 0 { - s.InfraCommand = strings.Split(p.InfraCommand, " ") + if p.InfraCommand != nil && len(*p.InfraCommand) > 0 { + s.InfraCommand = strings.Split(*p.InfraCommand, " ") } if len(p.InfraConmonPidFile) > 0 { s.InfraConmonPidFile = p.InfraConmonPidFile diff --git a/pkg/env/env.go b/pkg/env/env.go index 0d55e5560..ecd2d62a5 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -17,8 +17,9 @@ const whiteSpaces = " \t" // DefaultEnvVariables returns a default environment, with $PATH and $TERM set. func DefaultEnvVariables() map[string]string { return map[string]string{ - "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM": "xterm", + "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "TERM": "xterm", + "container": "podman", } } diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go index 6b9e9c4bf..2d1e2b288 100644 --- a/pkg/specgen/generate/config_linux.go +++ b/pkg/specgen/generate/config_linux.go @@ -132,7 +132,6 @@ func DevicesFromPath(g *generate.Generator, devicePath string) error { } return nil } - return addDevice(g, strings.Join(append([]string{resolvedDevicePath}, devs[1:]...), ":")) } diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 91230338e..fefa9b4a9 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -30,24 +30,27 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener // If joining a pod, retrieve the pod for use, and its infra container var pod *libpod.Pod - var cont *libpod.Container - var config *libpod.ContainerConfig + var infraConfig *libpod.ContainerConfig if s.Pod != "" { pod, err = rt.LookupPod(s.Pod) if err != nil { return nil, nil, nil, errors.Wrapf(err, "error retrieving pod %s", s.Pod) } if pod.HasInfraContainer() { - cont, err = pod.InfraContainer() + infra, err := pod.InfraContainer() if err != nil { return nil, nil, nil, err } - config = cont.Config() + infraConfig = infra.Config() } } - if config != nil && (len(config.NamedVolumes) > 0 || len(config.UserVolumes) > 0 || len(config.ImageVolumes) > 0 || len(config.OverlayVolumes) > 0) { - s.VolumesFrom = append(s.VolumesFrom, config.ID) + if infraConfig != nil && (len(infraConfig.NamedVolumes) > 0 || len(infraConfig.UserVolumes) > 0 || len(infraConfig.ImageVolumes) > 0 || len(infraConfig.OverlayVolumes) > 0) { + s.VolumesFrom = append(s.VolumesFrom, infraConfig.ID) + } + + if infraConfig != nil && len(infraConfig.Spec.Linux.Devices) > 0 { + s.DevicesFrom = append(s.DevicesFrom, infraConfig.ID) } // Set defaults for unset namespaces if s.PidNS.IsDefault() { @@ -166,6 +169,16 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener logrus.Debugf("setting container name %s", s.Name) options = append(options, libpod.WithName(s.Name)) } + if len(s.DevicesFrom) > 0 { + for _, dev := range s.DevicesFrom { + ctr, err := rt.GetContainer(dev) + if err != nil { + return nil, nil, nil, err + } + devices := ctr.DeviceHostSrc() + s.Devices = append(s.Devices, devices...) + } + } if len(s.Devices) > 0 { opts = extractCDIDevices(s) options = append(options, opts...) @@ -174,6 +187,9 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener if err != nil { return nil, nil, nil, err } + if len(s.HostDeviceList) > 0 { + options = append(options, libpod.WithHostDevice(s.HostDeviceList)) + } return runtimeSpec, s, options, err } func ExecuteCreate(ctx context.Context, rt *libpod.Runtime, runtimeSpec *spec.Spec, s *specgen.SpecGenerator, infra bool, options ...libpod.CtrCreateOption) (*libpod.Container, error) { diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 80c7f112f..55010f716 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -301,8 +301,8 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt g.AddProcessEnv("container", "podman") g.Config.Linux.Resources = s.ResourceLimits - // Devices + if s.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 @@ -313,17 +313,18 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt } else { // add default devices from containers.conf for _, device := range rtc.Containers.Devices { - if err := DevicesFromPath(&g, device); err != nil { + if err = DevicesFromPath(&g, device); err != nil { return nil, err } } // add default devices specified by caller for _, device := range s.Devices { - if err := DevicesFromPath(&g, device.Path); err != nil { + if err = DevicesFromPath(&g, device.Path); err != nil { return nil, err } } } + s.HostDeviceList = s.Devices for _, dev := range s.DeviceCGroupRule { g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access) diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go index 5f72fc47d..83fa9426c 100644 --- a/pkg/specgen/podspecgen.go +++ b/pkg/specgen/podspecgen.go @@ -88,6 +88,8 @@ type PodBasicConfig struct { // Image volumes bind-mount a container-image mount into the pod's infra container. // Optional. ImageVolumes []*ImageVolume `json:"image_volumes,omitempty"` + // Devices contains user specified Devices to be added to the Pod + Devices []string `json:"pod_devices,omitempty"` } // PodNetworkConfig contains networking configuration for a pod. diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index e0609c5bc..7aa27487a 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -254,6 +254,10 @@ type ContainerStorageConfig struct { // DeviceCGroupRule are device cgroup rules that allow containers // to use additional types of devices. DeviceCGroupRule []spec.LinuxDeviceCgroup `json:"device_cgroup_rule,omitempty"` + // DevicesFrom is a way to ensure your container inherits device specific information from another container + DevicesFrom []string `json:"devices_from,omitempty"` + // HostDeviceList is used to recreate the mounted device on inherited containers + HostDeviceList []spec.LinuxDevice `json:"host_device_list,omitempty"` // IpcNS is the container's IPC namespace. // Default is private. // Conflicts with ShmSize if not set to private. |