diff options
Diffstat (limited to 'pkg/specgen/generate')
-rw-r--r-- | pkg/specgen/generate/container.go | 4 | ||||
-rw-r--r-- | pkg/specgen/generate/container_create.go | 129 | ||||
-rw-r--r-- | pkg/specgen/generate/namespaces.go | 40 | ||||
-rw-r--r-- | pkg/specgen/generate/oci.go | 45 | ||||
-rw-r--r-- | pkg/specgen/generate/pod_create.go | 18 | ||||
-rw-r--r-- | pkg/specgen/generate/validate.go | 4 |
6 files changed, 158 insertions, 82 deletions
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 40a18a6ac..57676db10 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -156,7 +156,9 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat // Add annotations from the image for k, v := range inspectData.Annotations { - annotations[k] = v + if !define.IsReservedAnnotation(k) { + annotations[k] = v + } } } diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index df5d2e8ff..7d792b3b1 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -2,13 +2,15 @@ package generate import ( "context" - "fmt" + "encoding/json" "path/filepath" "strings" cdi "github.com/container-orchestrated-devices/container-device-interface/pkg" "github.com/containers/common/libimage" "github.com/containers/podman/v3/libpod" + "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/pkg/namespaces" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" spec "github.com/opencontainers/runtime-spec/specs-go" @@ -28,43 +30,30 @@ 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 infraConfig *libpod.ContainerConfig + var infra *libpod.Container 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() { - infra, err := pod.InfraContainer() + infra, err = pod.InfraContainer() if err != nil { return nil, nil, nil, err } - infraConfig = infra.Config() } } - 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) - } - if infraConfig != nil && infraConfig.Spec.Linux.Resources != nil && infraConfig.Spec.Linux.Resources.BlockIO != nil && len(infraConfig.Spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice) > 0 { - tempDev := make(map[string]spec.LinuxThrottleDevice) - for _, val := range infraConfig.Spec.Linux.Resources.BlockIO.ThrottleReadBpsDevice { - nodes, err := util.FindDeviceNodes() - if err != nil { - return nil, nil, nil, err - } - key := fmt.Sprintf("%d:%d", val.Major, val.Minor) - tempDev[nodes[key]] = spec.LinuxThrottleDevice{Rate: uint64(val.Rate)} - } - for i, dev := range s.ThrottleReadBpsDevice { - tempDev[i] = dev + options := []libpod.CtrCreateOption{} + compatibleOptions := &libpod.InfraInherit{} + var infraSpec *spec.Spec + if infra != nil { + options, infraSpec, compatibleOptions, err = Inherit(*infra) + if err != nil { + return nil, nil, nil, err } - s.ThrottleReadBpsDevice = tempDev } + if err := FinishThrottleDevices(s); err != nil { return nil, nil, nil, err } @@ -96,6 +85,12 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener return nil, nil, nil, err } s.UserNS = defaultNS + + mappings, err := util.ParseIDMapping(namespaces.UsernsMode(s.UserNS.NSMode), nil, nil, "", "") + if err != nil { + return nil, nil, nil, err + } + s.IDMappings = mappings } if s.NetNS.IsDefault() { defaultNS, err := GetDefaultNamespaceMode("net", rtc, pod) @@ -112,8 +107,6 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener s.CgroupNS = defaultNS } - options := []libpod.CtrCreateOption{} - if s.ContainerCreateCommand != nil { options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand)) } @@ -149,21 +142,22 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener return nil, nil, nil, err } + if len(s.HostUsers) > 0 { + options = append(options, libpod.WithHostUsers(s.HostUsers)) + } + command, err := makeCommand(ctx, s, imageData, rtc) if err != nil { return nil, nil, nil, err } - opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command) + infraVolumes := (len(compatibleOptions.InfraVolumes) > 0 || len(compatibleOptions.InfraUserVolumes) > 0 || len(compatibleOptions.InfraImageVolumes) > 0) + opts, err := createContainerOptions(ctx, rt, s, pod, finalVolumes, finalOverlays, imageData, command, infraVolumes, *compatibleOptions) if err != nil { return nil, nil, nil, err } options = append(options, opts...) - if len(s.Aliases) > 0 { - options = append(options, libpod.WithNetworkAliases(s.Aliases)) - } - if containerType := s.InitContainerType; len(containerType) > 0 { options = append(options, libpod.WithInitCtrType(containerType)) } @@ -171,27 +165,29 @@ 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) + opts = ExtractCDIDevices(s) options = append(options, opts...) } - runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command) + runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command, compatibleOptions) if err != nil { return nil, nil, nil, err } if len(s.HostDeviceList) > 0 { options = append(options, libpod.WithHostDevice(s.HostDeviceList)) } + if infraSpec != nil && infraSpec.Linux != nil { // if we are inheriting Linux info from a pod... + // Pass Security annotations + if len(infraSpec.Annotations[define.InspectAnnotationLabel]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationLabel]) == 0 { + runtimeSpec.Annotations[define.InspectAnnotationLabel] = infraSpec.Annotations[define.InspectAnnotationLabel] + } + if len(infraSpec.Annotations[define.InspectAnnotationSeccomp]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationSeccomp]) == 0 { + runtimeSpec.Annotations[define.InspectAnnotationSeccomp] = infraSpec.Annotations[define.InspectAnnotationSeccomp] + } + if len(infraSpec.Annotations[define.InspectAnnotationApparmor]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationApparmor]) == 0 { + runtimeSpec.Annotations[define.InspectAnnotationApparmor] = infraSpec.Annotations[define.InspectAnnotationApparmor] + } + } 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) { @@ -203,7 +199,7 @@ func ExecuteCreate(ctx context.Context, rt *libpod.Runtime, runtimeSpec *spec.Sp return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr) } -func extractCDIDevices(s *specgen.SpecGenerator) []libpod.CtrCreateOption { +func ExtractCDIDevices(s *specgen.SpecGenerator) []libpod.CtrCreateOption { devs := make([]spec.LinuxDevice, 0, len(s.Devices)) var cdiDevs []string var options []libpod.CtrCreateOption @@ -217,19 +213,16 @@ func extractCDIDevices(s *specgen.SpecGenerator) []libpod.CtrCreateOption { cdiDevs = append(cdiDevs, device.Path) continue } - devs = append(devs, device) } - s.Devices = devs if len(cdiDevs) > 0 { options = append(options, libpod.WithCDI(cdiDevs)) } - return options } -func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, overlays []*specgen.OverlayVolume, imageData *libimage.ImageData, command []string) ([]libpod.CtrCreateOption, error) { +func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, pod *libpod.Pod, volumes []*specgen.NamedVolume, overlays []*specgen.OverlayVolume, imageData *libimage.ImageData, command []string, infraVolumes bool, compatibleOptions libpod.InfraInherit) ([]libpod.CtrCreateOption, error) { var options []libpod.CtrCreateOption var err error @@ -310,7 +303,10 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. for _, imageVolume := range s.ImageVolumes { destinations = append(destinations, imageVolume.Destination) } - options = append(options, libpod.WithUserVolumes(destinations)) + + if len(destinations) > 0 || !infraVolumes { + options = append(options, libpod.WithUserVolumes(destinations)) + } if len(volumes) != 0 { var vols []*libpod.ContainerNamedVolume @@ -398,7 +394,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. if len(s.SelinuxOpts) > 0 { options = append(options, libpod.WithSecLabels(s.SelinuxOpts)) } else { - if pod != nil { + if pod != nil && len(compatibleOptions.InfraLabels) == 0 { // duplicate the security options from the pod processLabel, err := pod.ProcessLabel() if err != nil { @@ -486,5 +482,38 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. if s.PidFile != "" { options = append(options, libpod.WithPidFile(s.PidFile)) } + + options = append(options, libpod.WithSelectedPasswordManagement(s.Passwd)) + return options, nil } + +func Inherit(infra libpod.Container) (opts []libpod.CtrCreateOption, infraS *spec.Spec, compat *libpod.InfraInherit, err error) { + options := []libpod.CtrCreateOption{} + compatibleOptions := &libpod.InfraInherit{} + infraConf := infra.Config() + infraSpec := infraConf.Spec + + config, err := json.Marshal(infraConf) + if err != nil { + return nil, nil, nil, err + } + err = json.Unmarshal(config, compatibleOptions) + if err != nil { + return nil, nil, nil, err + } + if infraSpec.Linux != nil && infraSpec.Linux.Resources != nil { + resources, err := json.Marshal(infraSpec.Linux.Resources) + if err != nil { + return nil, nil, nil, err + } + err = json.Unmarshal(resources, &compatibleOptions.InfraResources) + if err != nil { + return nil, nil, nil, err + } + } + if compatibleOptions != nil { + options = append(options, libpod.WithInfraConfig(*compatibleOptions)) + } + return options, infraSpec, compatibleOptions, nil +} diff --git a/pkg/specgen/generate/namespaces.go b/pkg/specgen/generate/namespaces.go index 7d63fc10f..a2bc37e34 100644 --- a/pkg/specgen/generate/namespaces.go +++ b/pkg/specgen/generate/namespaces.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" + "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/specgen" "github.com/containers/podman/v3/pkg/util" @@ -66,7 +67,7 @@ func GetDefaultNamespaceMode(nsType string, cfg *config.Config, pod *libpod.Pod) case "cgroup": return specgen.ParseCgroupNamespace(cfg.Containers.CgroupNS) case "net": - ns, _, err := specgen.ParseNetworkNamespace(cfg.Containers.NetNS, cfg.Containers.RootlessNetworking == "cni") + ns, _, _, err := specgen.ParseNetworkFlag(nil) return ns, err } @@ -250,7 +251,7 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. if s.NetNS.Value != "" { val = fmt.Sprintf("slirp4netns:%s", s.NetNS.Value) } - toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, s.CNINetworks)) + toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, val, nil)) case specgen.Private: fallthrough case specgen.Bridge: @@ -258,7 +259,34 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. if err != nil { return nil, err } - toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.CNINetworks)) + + rtConfig, err := rt.GetConfigNoCopy() + if err != nil { + return nil, err + } + // if no network was specified use add the default + if len(s.Networks) == 0 { + // backwards config still allow the old cni networks list and convert to new format + if len(s.CNINetworks) > 0 { + logrus.Warn(`specgen "cni_networks" option is deprecated use the "networks" map instead`) + networks := make(map[string]types.PerNetworkOptions, len(s.CNINetworks)) + for _, net := range s.CNINetworks { + networks[net] = types.PerNetworkOptions{} + } + s.Networks = networks + } else { + // no networks given but bridge is set so use default network + s.Networks = map[string]types.PerNetworkOptions{ + rtConfig.Network.DefaultNetwork: {}, + } + } + } + // rename the "default" network to the correct default name + if opts, ok := s.Networks["default"]; ok { + s.Networks[rtConfig.Network.DefaultNetwork] = opts + delete(s.Networks, "default") + } + toReturn = append(toReturn, libpod.WithNetNS(portMappings, expose, postConfigureNetNS, "bridge", s.Networks)) } if s.UseImageHosts { @@ -281,12 +309,6 @@ func namespaceOptions(ctx context.Context, s *specgen.SpecGenerator, rt *libpod. if len(s.DNSOptions) > 0 { toReturn = append(toReturn, libpod.WithDNSOption(s.DNSOptions)) } - if s.StaticIP != nil { - toReturn = append(toReturn, libpod.WithStaticIP(*s.StaticIP)) - } - if s.StaticMAC != nil { - toReturn = append(toReturn, libpod.WithStaticMAC(*s.StaticMAC)) - } if s.NetworkOptions != nil { toReturn = append(toReturn, libpod.WithNetworkOptions(s.NetworkOptions)) } diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 9f8807915..ee3a990fc 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -2,6 +2,7 @@ package generate import ( "context" + "encoding/json" "path" "strings" @@ -174,7 +175,7 @@ func getCGroupPermissons(unmask []string) string { } // SpecGenToOCI returns the base configuration for the container. -func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *libimage.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string) (*spec.Spec, error) { +func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runtime, rtc *config.Config, newImage *libimage.Image, mounts []spec.Mount, pod *libpod.Pod, finalCmd []string, compatibleOptions *libpod.InfraInherit) (*spec.Spec, error) { cgroupPerm := getCGroupPermissons(s.Unmask) g, err := generate.New("linux") @@ -299,9 +300,32 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt g.AddAnnotation(key, val) } - g.Config.Linux.Resources = s.ResourceLimits + if compatibleOptions.InfraResources == nil && s.ResourceLimits != nil { + g.Config.Linux.Resources = s.ResourceLimits + } else if s.ResourceLimits != nil { // if we have predefined resource limits we need to make sure we keep the infra and container limits + originalResources, err := json.Marshal(s.ResourceLimits) + if err != nil { + return nil, err + } + infraResources, err := json.Marshal(compatibleOptions.InfraResources) + if err != nil { + return nil, err + } + err = json.Unmarshal(infraResources, s.ResourceLimits) // put infra's resource limits in the container + if err != nil { + return nil, err + } + err = json.Unmarshal(originalResources, s.ResourceLimits) // make sure we did not override anything + if err != nil { + return nil, err + } + g.Config.Linux.Resources = s.ResourceLimits + } else { + g.Config.Linux.Resources = compatibleOptions.InfraResources + } // Devices + var userDevices []spec.LinuxDevice 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 @@ -316,17 +340,26 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt return nil, err } } + if len(compatibleOptions.InfraDevices) > 0 && len(s.Devices) == 0 { + userDevices = compatibleOptions.InfraDevices + } else { + userDevices = s.Devices + } // add default devices specified by caller - for _, device := range s.Devices { + for _, device := range userDevices { if err = DevicesFromPath(&g, device.Path); err != nil { return nil, err } } } - s.HostDeviceList = s.Devices + s.HostDeviceList = userDevices - for _, dev := range s.DeviceCGroupRule { - g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access) + // set the devices cgroup when not running in a user namespace + if !inUserNS && !s.Privileged { + g.AddLinuxResourcesDevice(false, "", nil, nil, "rwm") + for _, dev := range s.DeviceCGroupRule { + g.AddLinuxResourcesDevice(true, dev.Type, dev.Major, dev.Minor, dev.Access) + } } for k, v := range s.WeightDevice { diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index 72dd249e7..0a797c571 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -218,9 +218,7 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { case specgen.Host: logrus.Debugf("Pod will use host networking") if len(p.InfraContainerSpec.PortMappings) > 0 || - p.InfraContainerSpec.StaticIP != nil || - p.InfraContainerSpec.StaticMAC != nil || - len(p.InfraContainerSpec.CNINetworks) > 0 || + len(p.InfraContainerSpec.Networks) > 0 || p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork { return nil, errors.Wrapf(define.ErrInvalidArg, "cannot set host network if network-related configuration is specified") } @@ -234,9 +232,7 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { case specgen.NoNetwork: logrus.Debugf("Pod will not use networking") if len(p.InfraContainerSpec.PortMappings) > 0 || - p.InfraContainerSpec.StaticIP != nil || - p.InfraContainerSpec.StaticMAC != nil || - len(p.InfraContainerSpec.CNINetworks) > 0 || + len(p.InfraContainerSpec.Networks) > 0 || p.InfraContainerSpec.NetNS.NSMode == "host" { return nil, errors.Wrapf(define.ErrInvalidArg, "cannot disable pod network if network-related configuration is specified") } @@ -264,15 +260,13 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { if len(p.DNSSearch) > 0 { p.InfraContainerSpec.DNSSearch = p.DNSSearch } - if p.StaticIP != nil { - p.InfraContainerSpec.StaticIP = p.StaticIP - } - if p.StaticMAC != nil { - p.InfraContainerSpec.StaticMAC = p.StaticMAC - } if p.NoManageResolvConf { p.InfraContainerSpec.UseImageResolvConf = true } + if len(p.Networks) > 0 { + p.InfraContainerSpec.Networks = p.Networks + } + // deprecated cni networks for api users if len(p.CNINetworks) > 0 { p.InfraContainerSpec.CNINetworks = p.CNINetworks } diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index a44bf9979..c74db7325 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -60,10 +60,6 @@ func verifyContainerResourcesCgroupV1(s *specgen.SpecGenerator) ([]string, error if memory.Limit != nil && memory.Reservation != nil && *memory.Limit < *memory.Reservation { return warnings, errors.New("minimum memory limit cannot be less than memory reservation limit, see usage") } - if memory.Kernel != nil && !sysInfo.KernelMemory { - warnings = append(warnings, "Your kernel does not support kernel memory limit capabilities or the cgroup is not mounted. Limitation discarded.") - memory.Kernel = nil - } if memory.DisableOOMKiller != nil && *memory.DisableOOMKiller && !sysInfo.OomKillDisable { warnings = append(warnings, "Your kernel does not support OomKillDisable. OomKillDisable discarded.") memory.DisableOOMKiller = nil |