14
"github.com/containers/common/libimage"
15
"github.com/containers/common/libnetwork/pasta"
16
"github.com/containers/common/libnetwork/slirp4netns"
17
"github.com/containers/podman/v5/libpod"
18
"github.com/containers/podman/v5/libpod/define"
19
"github.com/containers/podman/v5/pkg/namespaces"
20
"github.com/containers/podman/v5/pkg/rootless"
21
"github.com/containers/podman/v5/pkg/specgen"
22
"github.com/containers/podman/v5/pkg/specgenutil"
23
"github.com/containers/podman/v5/pkg/util"
24
"github.com/opencontainers/runtime-spec/specs-go"
25
"github.com/opencontainers/selinux/go-selinux/label"
26
"github.com/sirupsen/logrus"
27
"tags.cncf.io/container-device-interface/pkg/parser"
30
// MakeContainer creates a container based on the SpecGenerator.
31
// Returns the created, container and any warnings resulting from creating the
32
// container, or an error.
33
func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGenerator, clone bool, c *libpod.Container) (*specs.Spec, *specgen.SpecGenerator, []libpod.CtrCreateOption, error) {
34
rtc, err := rt.GetConfigNoCopy()
36
return nil, nil, nil, err
39
rlimits, err := specgenutil.GenRlimits(rtc.Ulimits())
41
return nil, nil, nil, err
43
s.Rlimits = append(rlimits, s.Rlimits...)
45
if s.OOMScoreAdj == nil {
46
s.OOMScoreAdj = rtc.Containers.OOMScoreAdj
49
if len(rtc.Containers.CgroupConf.Get()) > 0 {
50
if s.ResourceLimits == nil {
51
s.ResourceLimits = &specs.LinuxResources{}
53
if s.ResourceLimits.Unified == nil {
54
s.ResourceLimits.Unified = make(map[string]string)
56
for _, cgroupConf := range rtc.Containers.CgroupConf.Get() {
57
key, val, hasVal := strings.Cut(cgroupConf, "=")
59
return nil, nil, nil, fmt.Errorf("CgroupConf %s from containers.conf invalid, must be name=value", cgroupConf)
61
if _, ok := s.ResourceLimits.Unified[key]; !ok {
62
s.ResourceLimits.Unified[key] = val
67
// If joining a pod, retrieve the pod for use, and its infra container
69
var infra *libpod.Container
71
pod, err = rt.LookupPod(s.Pod)
73
return nil, nil, nil, fmt.Errorf("retrieving pod %s: %w", s.Pod, err)
75
if pod.HasInfraContainer() {
76
infra, err = pod.InfraContainer()
78
return nil, nil, nil, err
83
options := []libpod.CtrCreateOption{}
84
compatibleOptions := &libpod.InfraInherit{}
85
var infraSpec *specs.Spec
87
options, infraSpec, compatibleOptions, err = Inherit(infra, s, rt)
89
return nil, nil, nil, err
93
if err := specgen.FinishThrottleDevices(s); err != nil {
94
return nil, nil, nil, err
97
// Set defaults for unset namespaces
98
if s.PidNS.IsDefault() {
99
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
101
return nil, nil, nil, err
105
if s.IpcNS.IsDefault() {
106
defaultNS, err := GetDefaultNamespaceMode("ipc", rtc, pod)
108
return nil, nil, nil, err
112
if s.UtsNS.IsDefault() {
113
defaultNS, err := GetDefaultNamespaceMode("uts", rtc, pod)
115
return nil, nil, nil, err
119
if s.UserNS.IsDefault() {
120
defaultNS, err := GetDefaultNamespaceMode("user", rtc, pod)
122
return nil, nil, nil, err
125
value := string(s.UserNS.NSMode)
126
if s.UserNS.Value != "" {
127
value = value + ":" + s.UserNS.Value
129
mappings, err := util.ParseIDMapping(namespaces.UsernsMode(value), nil, nil, "", "")
131
return nil, nil, nil, err
133
s.IDMappings = mappings
135
if s.NetNS.IsDefault() {
136
defaultNS, err := GetDefaultNamespaceMode("net", rtc, pod)
138
return nil, nil, nil, err
142
if s.CgroupNS.IsDefault() {
143
defaultNS, err := GetDefaultNamespaceMode("cgroup", rtc, pod)
145
return nil, nil, nil, err
147
s.CgroupNS = defaultNS
150
if s.ContainerCreateCommand != nil {
151
options = append(options, libpod.WithCreateCommand(s.ContainerCreateCommand))
155
rootfsOverlay := false
156
if s.RootfsOverlay != nil {
157
rootfsOverlay = *s.RootfsOverlay
159
options = append(options, libpod.WithRootFS(s.Rootfs, rootfsOverlay, s.RootfsMapping))
162
newImage, resolvedImageName, imageData, err := getImageFromSpec(ctx, rt, s)
164
return nil, nil, nil, err
167
if imageData != nil {
168
ociRuntimeVariant := rtc.Engine.ImagePlatformToRuntime(imageData.Os, imageData.Architecture)
169
// Don't unnecessarily set and invoke additional libpod
170
// option if OCI runtime is still default.
171
if ociRuntimeVariant != rtc.Engine.OCIRuntime {
172
options = append(options, libpod.WithCtrOCIRuntime(ociRuntimeVariant))
177
// If the input name changed, we could properly resolve the
178
// image. Otherwise, it must have been an ID where we're
179
// defaulting to the first name or an empty one if no names are
181
if strings.HasPrefix(newImage.ID(), resolvedImageName) {
182
names := newImage.Names()
184
resolvedImageName = names[0]
188
options = append(options, libpod.WithRootFSFromImage(newImage.ID(), resolvedImageName, s.RawImageName))
191
_, err = rt.LookupPod(s.Hostname)
192
if len(s.Hostname) > 0 && !s.UtsNS.IsPrivate() && err == nil {
193
// ok, we are incorrectly setting the pod as the hostname, let's undo that before validation
197
// Set defaults if network info is not provided
198
if s.NetNS.IsPrivate() || s.NetNS.IsDefault() {
199
if rootless.IsRootless() {
200
// when we are rootless we default to default_rootless_network_cmd from containers.conf
201
conf, err := rt.GetConfigNoCopy()
203
return nil, nil, nil, err
205
switch conf.Network.DefaultRootlessNetworkCmd {
206
case slirp4netns.BinaryName, "":
207
s.NetNS.NSMode = specgen.Slirp
208
case pasta.BinaryName:
209
s.NetNS.NSMode = specgen.Pasta
211
return nil, nil, nil, fmt.Errorf("invalid default_rootless_network_cmd option %q",
212
conf.Network.DefaultRootlessNetworkCmd)
215
// as root default to bridge
216
s.NetNS.NSMode = specgen.Bridge
220
if err := s.Validate(); err != nil {
221
return nil, nil, nil, fmt.Errorf("invalid config provided: %w", err)
224
finalMounts, finalVolumes, finalOverlays, err := finalizeMounts(ctx, s, rt, rtc, newImage)
226
return nil, nil, nil, err
229
if len(s.HostUsers) > 0 {
230
options = append(options, libpod.WithHostUsers(s.HostUsers))
233
command := makeCommand(s, imageData)
235
infraVol := len(compatibleOptions.Mounts) > 0 || len(compatibleOptions.Volumes) > 0 || len(compatibleOptions.ImageVolumes) > 0 || len(compatibleOptions.OverlayVolumes) > 0
236
opts, err := createContainerOptions(rt, s, pod, finalVolumes, finalOverlays, imageData, command, infraVol, *compatibleOptions)
238
return nil, nil, nil, err
240
options = append(options, opts...)
242
if containerType := s.InitContainerType; len(containerType) > 0 {
243
options = append(options, libpod.WithInitCtrType(containerType))
246
logrus.Debugf("setting container name %s", s.Name)
247
options = append(options, libpod.WithName(s.Name))
249
if len(s.Devices) > 0 {
250
opts = ExtractCDIDevices(s)
251
options = append(options, opts...)
253
runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts, pod, command, compatibleOptions)
255
return nil, nil, nil, err
257
if clone { // the container fails to start if cloned due to missing Linux spec entries
259
return nil, nil, nil, errors.New("the given container could not be retrieved")
262
if conf != nil && conf.Spec != nil && conf.Spec.Linux != nil {
263
out, err := json.Marshal(conf.Spec.Linux)
265
return nil, nil, nil, err
267
resources := runtimeSpec.Linux.Resources
269
// resources get overwritten similarly to pod inheritance, manually assign here if there is a new value
270
marshalRes, err := json.Marshal(resources)
272
return nil, nil, nil, err
275
err = json.Unmarshal(out, runtimeSpec.Linux)
277
return nil, nil, nil, err
280
err = json.Unmarshal(marshalRes, runtimeSpec.Linux.Resources)
282
return nil, nil, nil, err
285
if s.ResourceLimits != nil {
287
case s.ResourceLimits.CPU != nil:
288
runtimeSpec.Linux.Resources.CPU = s.ResourceLimits.CPU
289
case s.ResourceLimits.Memory != nil:
290
runtimeSpec.Linux.Resources.Memory = s.ResourceLimits.Memory
291
case s.ResourceLimits.BlockIO != nil:
292
runtimeSpec.Linux.Resources.BlockIO = s.ResourceLimits.BlockIO
293
case s.ResourceLimits.Devices != nil:
294
runtimeSpec.Linux.Resources.Devices = s.ResourceLimits.Devices
298
if len(s.HostDeviceList) > 0 {
299
options = append(options, libpod.WithHostDevice(s.HostDeviceList))
301
if infraSpec != nil && infraSpec.Linux != nil { // if we are inheriting Linux info from a pod...
302
// Pass Security annotations
303
if len(infraSpec.Annotations[define.InspectAnnotationLabel]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationLabel]) == 0 {
304
runtimeSpec.Annotations[define.InspectAnnotationLabel] = infraSpec.Annotations[define.InspectAnnotationLabel]
306
if len(infraSpec.Annotations[define.InspectAnnotationSeccomp]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationSeccomp]) == 0 {
307
runtimeSpec.Annotations[define.InspectAnnotationSeccomp] = infraSpec.Annotations[define.InspectAnnotationSeccomp]
309
if len(infraSpec.Annotations[define.InspectAnnotationApparmor]) > 0 && len(runtimeSpec.Annotations[define.InspectAnnotationApparmor]) == 0 {
310
runtimeSpec.Annotations[define.InspectAnnotationApparmor] = infraSpec.Annotations[define.InspectAnnotationApparmor]
313
return runtimeSpec, s, options, err
315
func ExecuteCreate(ctx context.Context, rt *libpod.Runtime, runtimeSpec *specs.Spec, s *specgen.SpecGenerator, infra bool, options ...libpod.CtrCreateOption) (*libpod.Container, error) {
316
ctr, err := rt.NewContainer(ctx, runtimeSpec, s, infra, options...)
321
return ctr, rt.PrepareVolumeOnCreateContainer(ctx, ctr)
324
// ExtractCDIDevices process the list of Devices in the spec and determines if any of these are CDI devices.
325
// The CDI devices are added to the list of CtrCreateOptions.
326
// Note that this may modify the device list associated with the spec, which should then only contain non-CDI devices.
327
func ExtractCDIDevices(s *specgen.SpecGenerator) []libpod.CtrCreateOption {
328
devs := make([]specs.LinuxDevice, 0, len(s.Devices))
330
var options []libpod.CtrCreateOption
332
for _, device := range s.Devices {
333
if isCDIDevice(device.Path) {
334
logrus.Debugf("Identified CDI device %v", device.Path)
335
cdiDevs = append(cdiDevs, device.Path)
338
logrus.Debugf("Non-CDI device %v; assuming standard device", device.Path)
339
devs = append(devs, device)
342
if len(cdiDevs) > 0 {
343
options = append(options, libpod.WithCDI(cdiDevs))
348
// isCDIDevice checks whether the specified device is a CDI device.
349
func isCDIDevice(device string) bool {
350
return parser.IsQualifiedName(device)
353
func createContainerOptions(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) {
354
var options []libpod.CtrCreateOption
357
if s.PreserveFDs > 0 {
358
options = append(options, libpod.WithPreserveFDs(s.PreserveFDs))
361
if s.PreserveFD != nil {
362
options = append(options, libpod.WithPreserveFD(s.PreserveFD))
365
if s.Stdin != nil && *s.Stdin {
366
options = append(options, libpod.WithStdin())
369
if s.Timezone != "" {
370
options = append(options, libpod.WithTimezone(s.Timezone))
373
options = append(options, libpod.WithUmask(s.Umask))
375
if s.Volatile != nil && *s.Volatile {
376
options = append(options, libpod.WithVolatile())
378
if s.PasswdEntry != "" {
379
options = append(options, libpod.WithPasswdEntry(s.PasswdEntry))
381
if s.GroupEntry != "" {
382
options = append(options, libpod.WithGroupEntry(s.GroupEntry))
384
if s.BaseHostsFile != "" {
385
options = append(options, libpod.WithBaseHostsFile(s.BaseHostsFile))
388
if s.IsPrivileged() {
389
options = append(options, libpod.WithMountAllDevices())
399
if len(command) == 0 && imageData != nil {
400
command = imageData.Config.Cmd
403
if len(command) > 0 {
404
useSystemdCommands := map[string]bool{
406
"/usr/sbin/init": true,
407
"/usr/local/sbin/init": true,
409
// Grab last command in case this is launched from a shell
411
if len(command) > 2 {
412
// Podman build will add "/bin/sh" "-c" to
413
// Entrypoint. Remove and search for systemd
414
if command[0] == "/bin/sh" && command[1] == "-c" {
418
if useSystemdCommands[cmd[0]] || (filepath.Base(cmd[0]) == "systemd") {
423
return nil, fmt.Errorf("invalid value %q systemd option requires 'true, false, always': %w", s.Systemd, err)
425
logrus.Debugf("using systemd mode: %t", useSystemd)
427
// is StopSignal was not set by the user then set it to systemd
428
// expected StopSigal
429
if s.StopSignal == nil {
430
stopSignal, err := util.ParseSignal("RTMIN+3")
432
return nil, fmt.Errorf("parsing systemd signal: %w", err)
434
s.StopSignal = &stopSignal
437
options = append(options, libpod.WithSystemd())
439
if len(s.SdNotifyMode) > 0 {
440
options = append(options, libpod.WithSdNotifyMode(s.SdNotifyMode))
441
if s.SdNotifyMode != define.SdNotifyModeIgnore {
442
if notify, ok := os.LookupEnv("NOTIFY_SOCKET"); ok {
443
options = append(options, libpod.WithSdNotifySocket(notify))
449
logrus.Debugf("adding container to pod %s", pod.Name())
450
options = append(options, rt.WithPod(pod))
452
destinations := []string{}
453
// Take all mount and named volume destinations.
454
for _, mount := range s.Mounts {
455
destinations = append(destinations, mount.Destination)
457
for _, volume := range volumes {
458
destinations = append(destinations, volume.Dest)
460
for _, overlayVolume := range overlays {
461
destinations = append(destinations, overlayVolume.Destination)
463
for _, imageVolume := range s.ImageVolumes {
464
destinations = append(destinations, imageVolume.Destination)
467
if len(destinations) > 0 || !infraVolumes {
468
options = append(options, libpod.WithUserVolumes(destinations))
471
if len(volumes) != 0 {
472
var vols []*libpod.ContainerNamedVolume
473
for _, v := range volumes {
474
vols = append(vols, &libpod.ContainerNamedVolume{
478
IsAnonymous: v.IsAnonymous,
482
options = append(options, libpod.WithNamedVolumes(vols))
485
if len(overlays) != 0 {
486
var vols []*libpod.ContainerOverlayVolume
487
for _, v := range overlays {
488
vols = append(vols, &libpod.ContainerOverlayVolume{
494
options = append(options, libpod.WithOverlayVolumes(vols))
497
if len(s.ImageVolumes) != 0 {
498
var vols []*libpod.ContainerImageVolume
499
for _, v := range s.ImageVolumes {
500
vols = append(vols, &libpod.ContainerImageVolume{
503
ReadWrite: v.ReadWrite,
506
options = append(options, libpod.WithImageVolumes(vols))
509
if s.Command != nil {
510
options = append(options, libpod.WithCommand(s.Command))
512
if s.Entrypoint != nil {
513
options = append(options, libpod.WithEntrypoint(s.Entrypoint))
515
if len(s.ContainerStorageConfig.StorageOpts) > 0 {
516
options = append(options, libpod.WithStorageOpts(s.StorageOpts))
518
// If the user did not specify a workdir on the CLI, let's extract it
520
if s.WorkDir == "" && imageData != nil {
521
options = append(options, libpod.WithCreateWorkingDir())
522
s.WorkDir = imageData.Config.WorkingDir
527
if s.CreateWorkingDir != nil && *s.CreateWorkingDir {
528
options = append(options, libpod.WithCreateWorkingDir())
530
if s.StopSignal != nil {
531
options = append(options, libpod.WithStopSignal(*s.StopSignal))
533
if s.StopTimeout != nil {
534
options = append(options, libpod.WithStopTimeout(*s.StopTimeout))
537
options = append(options, libpod.WithTimeout(s.Timeout))
539
if s.LogConfiguration != nil {
540
if len(s.LogConfiguration.Path) > 0 {
541
options = append(options, libpod.WithLogPath(s.LogConfiguration.Path))
543
if s.LogConfiguration.Size > 0 {
544
options = append(options, libpod.WithMaxLogSize(s.LogConfiguration.Size))
546
if len(s.LogConfiguration.Options) > 0 && s.LogConfiguration.Options["tag"] != "" {
547
options = append(options, libpod.WithLogTag(s.LogConfiguration.Options["tag"]))
550
if len(s.LogConfiguration.Driver) > 0 {
551
options = append(options, libpod.WithLogDriver(s.LogConfiguration.Driver))
554
if s.LabelNested != nil {
555
options = append(options, libpod.WithLabelNested(*s.LabelNested))
558
if len(s.SelinuxOpts) > 0 {
559
options = append(options, libpod.WithSecLabels(s.SelinuxOpts))
560
} else if pod != nil && len(compatibleOptions.SelinuxOpts) == 0 {
561
// duplicate the security options from the pod
562
processLabel, err := pod.ProcessLabel()
566
if processLabel != "" {
567
selinuxOpts, err := label.DupSecOpt(processLabel)
571
options = append(options, libpod.WithSecLabels(selinuxOpts))
574
options = append(options, libpod.WithPrivileged(s.IsPrivileged()))
575
if s.ReadWriteTmpfs != nil {
576
options = append(options, libpod.WithReadWriteTmpfs(*s.ReadWriteTmpfs))
579
// Get namespace related options
580
namespaceOpts, err := namespaceOptions(s, rt, pod, imageData)
584
options = append(options, namespaceOpts...)
586
if len(s.ConmonPidFile) > 0 {
587
options = append(options, libpod.WithConmonPidFile(s.ConmonPidFile))
589
options = append(options, libpod.WithLabels(s.Labels))
590
if s.ShmSize != nil {
591
options = append(options, libpod.WithShmSize(*s.ShmSize))
593
if s.ShmSizeSystemd != nil {
594
options = append(options, libpod.WithShmSizeSystemd(*s.ShmSizeSystemd))
597
rootfsOverlay := false
598
if s.RootfsOverlay != nil {
599
rootfsOverlay = *s.RootfsOverlay
601
options = append(options, libpod.WithRootFS(s.Rootfs, rootfsOverlay, s.RootfsMapping))
603
// Default used if not overridden on command line
609
// If the container is running in a pod, use the pod's restart policy for all the containers
610
if pod != nil && !s.IsInitContainer() && s.RestartPolicy == "" {
611
podConfig := pod.ConfigNoCopy()
612
if podConfig.RestartRetries != nil {
613
retries = *podConfig.RestartRetries
615
restartPolicy = podConfig.RestartPolicy
616
} else if s.RestartPolicy != "" {
617
if s.RestartRetries != nil {
618
retries = *s.RestartRetries
620
restartPolicy = s.RestartPolicy
622
if restartPolicy != "" {
623
options = append(options, libpod.WithRestartPolicy(restartPolicy))
626
options = append(options, libpod.WithRestartRetries(retries))
629
healthCheckSet := false
630
if s.ContainerHealthCheckConfig.HealthConfig != nil {
631
options = append(options, libpod.WithHealthCheck(s.ContainerHealthCheckConfig.HealthConfig))
632
logrus.Debugf("New container has a health check")
633
healthCheckSet = true
635
if s.ContainerHealthCheckConfig.StartupHealthConfig != nil {
636
options = append(options, libpod.WithStartupHealthcheck(s.ContainerHealthCheckConfig.StartupHealthConfig))
637
healthCheckSet = true
640
if s.ContainerHealthCheckConfig.HealthCheckOnFailureAction != define.HealthCheckOnFailureActionNone {
641
options = append(options, libpod.WithHealthCheckOnFailureAction(s.ContainerHealthCheckConfig.HealthCheckOnFailureAction))
644
if s.SdNotifyMode == define.SdNotifyModeHealthy && !healthCheckSet {
645
return nil, fmt.Errorf("%w: sdnotify policy %q requires a healthcheck to be set", define.ErrInvalidArg, s.SdNotifyMode)
648
if len(s.Secrets) != 0 {
649
manager, err := rt.SecretsManager()
653
var secrs []*libpod.ContainerSecret
654
for _, s := range s.Secrets {
655
secr, err := manager.Lookup(s.Source)
659
secrs = append(secrs, &libpod.ContainerSecret{
667
options = append(options, libpod.WithSecrets(secrs))
670
if len(s.EnvSecrets) != 0 {
671
options = append(options, libpod.WithEnvSecrets(s.EnvSecrets))
674
if len(s.DependencyContainers) > 0 {
675
deps := make([]*libpod.Container, 0, len(s.DependencyContainers))
676
for _, ctr := range s.DependencyContainers {
677
depCtr, err := rt.LookupContainer(ctr)
679
return nil, fmt.Errorf("%q is not a valid container, cannot be used as a dependency: %w", ctr, err)
681
deps = append(deps, depCtr)
683
options = append(options, libpod.WithDependencyCtrs(deps))
686
options = append(options, libpod.WithPidFile(s.PidFile))
689
if len(s.ChrootDirs) != 0 {
690
options = append(options, libpod.WithChrootDirs(s.ChrootDirs))
693
options = append(options, libpod.WithSelectedPasswordManagement(s.Passwd))
698
func Inherit(infra *libpod.Container, s *specgen.SpecGenerator, rt *libpod.Runtime) (opts []libpod.CtrCreateOption, infraS *specs.Spec, compat *libpod.InfraInherit, err error) {
699
inheritSpec := &specgen.SpecGenerator{}
700
_, compatibleOptions, err := ConfigToSpec(rt, inheritSpec, infra.ID())
702
return nil, nil, nil, err
704
options := []libpod.CtrCreateOption{}
705
infraConf := infra.Config()
706
infraSpec := infraConf.Spec
708
// need to set compatOptions to the currently filled specgenOptions so we do not overwrite
709
compatibleOptions.CapAdd = append(compatibleOptions.CapAdd, s.CapAdd...)
710
compatibleOptions.CapDrop = append(compatibleOptions.CapDrop, s.CapDrop...)
711
compatibleOptions.HostDeviceList = append(compatibleOptions.HostDeviceList, s.HostDeviceList...)
712
compatibleOptions.ImageVolumes = append(compatibleOptions.ImageVolumes, s.ImageVolumes...)
713
compatibleOptions.Mounts = append(compatibleOptions.Mounts, s.Mounts...)
714
compatibleOptions.OverlayVolumes = append(compatibleOptions.OverlayVolumes, s.OverlayVolumes...)
715
compatibleOptions.SelinuxOpts = append(compatibleOptions.SelinuxOpts, s.SelinuxOpts...)
716
compatibleOptions.Volumes = append(compatibleOptions.Volumes, s.Volumes...)
718
compatByte, err := json.Marshal(compatibleOptions)
720
return nil, nil, nil, err
722
err = json.Unmarshal(compatByte, s)
724
return nil, nil, nil, err
727
// podman pod container can override pod ipc NS
728
if !s.IpcNS.IsDefault() {
729
inheritSpec.IpcNS = s.IpcNS
732
// this causes errors when shmSize is the default value, it will still get passed down unless we manually override.
733
if inheritSpec.IpcNS.NSMode == specgen.Host && (compatibleOptions.ShmSize != nil && compatibleOptions.IsDefaultShmSize()) {
736
return options, infraSpec, compatibleOptions, nil