From 331b3c216d68337ba9285542e0663f742dd5af5e Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 6 Sep 2023 21:35:57 +0200 Subject: [PATCH] cmd, specgen: allow cgroup resources without --infra When the infra container is not created, we can still set limits on the pod cgroup. Signed-off-by: Giuseppe Scrivano --- cmd/podman/pods/create.go | 24 +++++++ pkg/specgen/generate/pod_create.go | 102 ++++++++++++++--------------- 2 files changed, 73 insertions(+), 53 deletions(-) diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 5cc4505ff2..79c3524a6c 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -154,6 +154,15 @@ func create(cmd *cobra.Command, args []string) error { return fmt.Errorf("cannot set share(%s) namespaces without an infra container", cmd.Flag("share").Value) } createOptions.Share = nil + + infraOptions, err = containers.CreateInit(cmd, infraOptions, true) + if err != nil { + return err + } + err = common.ContainerToPodOptions(&infraOptions, &createOptions) + if err != nil { + return err + } } else { // reassign certain options for lbpod api, these need to be populated in spec flags := cmd.Flags() @@ -280,6 +289,21 @@ func create(cmd *cobra.Command, args []string) error { return err } podSpec.Name = podName + } else { + ctrSpec := specgen.NewSpecGenerator("", false) + err = specgenutil.FillOutSpecGen(ctrSpec, &infraOptions, []string{}) + if err != nil { + return err + } + // Marshall and Unmarshal the spec in order to map similar entities + wrapped, err := json.Marshal(ctrSpec) + if err != nil { + return err + } + err = json.Unmarshal(wrapped, podSpec) + if err != nil { + return err + } } PodSpec := entities.PodSpec{PodSpecGen: *podSpec} response, err := registry.ContainerEngine().PodCreate(context.Background(), PodSpec) diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index a8136ba490..e14ed00d66 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -44,28 +44,18 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (_ *libpod.Pod, finalErr e p.PodSpecGen.InfraContainerSpec.RawImageName = imageName } - if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil { - var err error - p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen) - if err != nil { - return nil, err - } + spec, err := MapSpec(&p.PodSpecGen) + if err != nil { + return nil, err } - - if !p.PodSpecGen.NoInfra { - err := specgen.FinishThrottleDevices(p.PodSpecGen.InfraContainerSpec) - if err != nil { - return nil, err - } - if p.PodSpecGen.InfraContainerSpec.ResourceLimits != nil && - p.PodSpecGen.InfraContainerSpec.ResourceLimits.BlockIO != nil { - p.PodSpecGen.ResourceLimits.BlockIO = p.PodSpecGen.InfraContainerSpec.ResourceLimits.BlockIO - } - err = specgen.WeightDevices(p.PodSpecGen.InfraContainerSpec) - if err != nil { - return nil, err - } - p.PodSpecGen.ResourceLimits = p.PodSpecGen.InfraContainerSpec.ResourceLimits + if err := specgen.FinishThrottleDevices(spec); err != nil { + return nil, err + } + if err := specgen.WeightDevices(spec); err != nil { + return nil, err + } + if spec.ResourceLimits != nil && spec.ResourceLimits.BlockIO != nil { + p.PodSpecGen.ResourceLimits.BlockIO = spec.ResourceLimits.BlockIO } options, err := createPodOptions(&p.PodSpecGen) @@ -177,12 +167,18 @@ func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, er // MapSpec modifies the already filled Infra specgenerator, // replacing necessary values with those specified in pod creation func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { + var spec *specgen.SpecGenerator + if p.InfraContainerSpec != nil { + spec = p.InfraContainerSpec + } else { + spec = &specgen.SpecGenerator{} + } if len(p.PortMappings) > 0 { ports, err := ParsePortMapping(p.PortMappings, nil) if err != nil { return nil, err } - p.InfraContainerSpec.PortMappings = ports + spec.PortMappings = ports } switch p.NetNS.NSMode { case specgen.Default, "": @@ -191,90 +187,90 @@ func MapSpec(p *specgen.PodSpecGenerator) (*specgen.SpecGenerator, error) { break } case specgen.Bridge: - p.InfraContainerSpec.NetNS.NSMode = specgen.Bridge + spec.NetNS.NSMode = specgen.Bridge logrus.Debugf("Pod using bridge network mode") case specgen.Private: - p.InfraContainerSpec.NetNS.NSMode = specgen.Private + spec.NetNS.NSMode = specgen.Private logrus.Debugf("Pod will use default network mode") case specgen.Host: logrus.Debugf("Pod will use host networking") - if len(p.InfraContainerSpec.PortMappings) > 0 || - len(p.InfraContainerSpec.Networks) > 0 || - p.InfraContainerSpec.NetNS.NSMode == specgen.NoNetwork { + if len(spec.PortMappings) > 0 || + len(spec.Networks) > 0 || + spec.NetNS.NSMode == specgen.NoNetwork { return nil, fmt.Errorf("cannot set host network if network-related configuration is specified: %w", define.ErrInvalidArg) } - p.InfraContainerSpec.NetNS.NSMode = specgen.Host + spec.NetNS.NSMode = specgen.Host case specgen.Slirp: logrus.Debugf("Pod will use slirp4netns") - if p.InfraContainerSpec.NetNS.NSMode != specgen.Host { - p.InfraContainerSpec.NetworkOptions = p.NetworkOptions - p.InfraContainerSpec.NetNS.NSMode = specgen.Slirp + if spec.NetNS.NSMode != specgen.Host { + spec.NetworkOptions = p.NetworkOptions + spec.NetNS.NSMode = specgen.Slirp } case specgen.Pasta: logrus.Debugf("Pod will use pasta") - if p.InfraContainerSpec.NetNS.NSMode != specgen.Host { - p.InfraContainerSpec.NetworkOptions = p.NetworkOptions - p.InfraContainerSpec.NetNS.NSMode = specgen.Pasta + if spec.NetNS.NSMode != specgen.Host { + spec.NetworkOptions = p.NetworkOptions + spec.NetNS.NSMode = specgen.Pasta } case specgen.Path: logrus.Debugf("Pod will use namespace path networking") - p.InfraContainerSpec.NetNS.NSMode = specgen.Path - p.InfraContainerSpec.NetNS.Value = p.PodNetworkConfig.NetNS.Value + spec.NetNS.NSMode = specgen.Path + spec.NetNS.Value = p.PodNetworkConfig.NetNS.Value case specgen.NoNetwork: logrus.Debugf("Pod will not use networking") - if len(p.InfraContainerSpec.PortMappings) > 0 || - len(p.InfraContainerSpec.Networks) > 0 || - p.InfraContainerSpec.NetNS.NSMode == specgen.Host { + if len(spec.PortMappings) > 0 || + len(spec.Networks) > 0 || + spec.NetNS.NSMode == specgen.Host { return nil, fmt.Errorf("cannot disable pod network if network-related configuration is specified: %w", define.ErrInvalidArg) } - p.InfraContainerSpec.NetNS.NSMode = specgen.NoNetwork + spec.NetNS.NSMode = specgen.NoNetwork default: return nil, fmt.Errorf("pods presently do not support network mode %s", p.NetNS.NSMode) } if len(p.InfraCommand) > 0 { - p.InfraContainerSpec.Entrypoint = p.InfraCommand + spec.Entrypoint = p.InfraCommand } if len(p.HostAdd) > 0 { - p.InfraContainerSpec.HostAdd = p.HostAdd + spec.HostAdd = p.HostAdd } if len(p.DNSServer) > 0 { var dnsServers []net.IP dnsServers = append(dnsServers, p.DNSServer...) - p.InfraContainerSpec.DNSServers = dnsServers + spec.DNSServers = dnsServers } if len(p.DNSOption) > 0 { - p.InfraContainerSpec.DNSOptions = p.DNSOption + spec.DNSOptions = p.DNSOption } if len(p.DNSSearch) > 0 { - p.InfraContainerSpec.DNSSearch = p.DNSSearch + spec.DNSSearch = p.DNSSearch } if p.NoManageResolvConf { - p.InfraContainerSpec.UseImageResolvConf = true + spec.UseImageResolvConf = true } if len(p.Networks) > 0 { - p.InfraContainerSpec.Networks = p.Networks + spec.Networks = p.Networks } // deprecated cni networks for api users if len(p.CNINetworks) > 0 { - p.InfraContainerSpec.CNINetworks = p.CNINetworks + spec.CNINetworks = p.CNINetworks } if p.NoManageHosts { - p.InfraContainerSpec.UseImageHosts = p.NoManageHosts + spec.UseImageHosts = p.NoManageHosts } if len(p.InfraConmonPidFile) > 0 { - p.InfraContainerSpec.ConmonPidFile = p.InfraConmonPidFile + spec.ConmonPidFile = p.InfraConmonPidFile } if p.Sysctl != nil && len(p.Sysctl) > 0 { - p.InfraContainerSpec.Sysctl = p.Sysctl + spec.Sysctl = p.Sysctl } - p.InfraContainerSpec.Image = p.InfraImage - return p.InfraContainerSpec, nil + spec.Image = p.InfraImage + return spec, nil } func PodConfigToSpec(rt *libpod.Runtime, spec *specgen.PodSpecGenerator, infraOptions *entities.ContainerCreateOptions, id string) (p *libpod.Pod, err error) {