diff options
Diffstat (limited to 'libpod/container_inspect.go')
-rw-r--r-- | libpod/container_inspect.go | 297 |
1 files changed, 6 insertions, 291 deletions
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index b72d843b6..e4089efa6 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -3,20 +3,15 @@ package libpod import ( "errors" "fmt" - "sort" "strings" - "github.com/containers/common/pkg/config" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/driver" "github.com/containers/podman/v4/pkg/util" "github.com/containers/storage/types" units "github.com/docker/go-units" spec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/runtime-tools/generate" - "github.com/opencontainers/runtime-tools/validate" "github.com/sirupsen/logrus" - "github.com/syndtr/gocapability/capability" ) // inspectLocked inspects a container for low-level information. @@ -163,8 +158,6 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver Driver: driverData.Name, MountLabel: config.MountLabel, ProcessLabel: config.ProcessLabel, - EffectiveCaps: ctrSpec.Process.Capabilities.Effective, - BoundingCaps: ctrSpec.Process.Capabilities.Bounding, AppArmorProfile: ctrSpec.Process.ApparmorProfile, ExecIDs: execIDs, GraphDriver: driverData, @@ -173,6 +166,10 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver IsInfra: c.IsInfra(), IsService: c.IsService(), } + if ctrSpec.Process.Capabilities != nil { + data.EffectiveCaps = ctrSpec.Process.Capabilities.Effective + data.BoundingCaps = ctrSpec.Process.Capabilities.Bounding + } if c.state.ConfigPath != "" { data.OCIConfigPath = c.state.ConfigPath @@ -484,11 +481,6 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named hostConfig.ShmSize = c.config.ShmSize hostConfig.Runtime = "oci" - // This is very expensive to initialize. - // So we don't want to initialize it unless we absolutely have to - IE, - // there are things that require a major:minor to path translation. - var deviceNodes map[string]string - // Annotations if ctrSpec.Annotations != nil { hostConfig.ContainerIDFile = ctrSpec.Annotations[define.InspectAnnotationCIDFile] @@ -506,109 +498,8 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named } } - // Resource limits - if ctrSpec.Linux != nil { - if ctrSpec.Linux.Resources != nil { - if ctrSpec.Linux.Resources.CPU != nil { - if ctrSpec.Linux.Resources.CPU.Shares != nil { - hostConfig.CpuShares = *ctrSpec.Linux.Resources.CPU.Shares - } - if ctrSpec.Linux.Resources.CPU.Period != nil { - hostConfig.CpuPeriod = *ctrSpec.Linux.Resources.CPU.Period - } - if ctrSpec.Linux.Resources.CPU.Quota != nil { - hostConfig.CpuQuota = *ctrSpec.Linux.Resources.CPU.Quota - } - if ctrSpec.Linux.Resources.CPU.RealtimePeriod != nil { - hostConfig.CpuRealtimePeriod = *ctrSpec.Linux.Resources.CPU.RealtimePeriod - } - if ctrSpec.Linux.Resources.CPU.RealtimeRuntime != nil { - hostConfig.CpuRealtimeRuntime = *ctrSpec.Linux.Resources.CPU.RealtimeRuntime - } - hostConfig.CpusetCpus = ctrSpec.Linux.Resources.CPU.Cpus - hostConfig.CpusetMems = ctrSpec.Linux.Resources.CPU.Mems - } - if ctrSpec.Linux.Resources.Memory != nil { - if ctrSpec.Linux.Resources.Memory.Limit != nil { - hostConfig.Memory = *ctrSpec.Linux.Resources.Memory.Limit - } - if ctrSpec.Linux.Resources.Memory.Reservation != nil { - hostConfig.MemoryReservation = *ctrSpec.Linux.Resources.Memory.Reservation - } - if ctrSpec.Linux.Resources.Memory.Swap != nil { - hostConfig.MemorySwap = *ctrSpec.Linux.Resources.Memory.Swap - } - if ctrSpec.Linux.Resources.Memory.Swappiness != nil { - hostConfig.MemorySwappiness = int64(*ctrSpec.Linux.Resources.Memory.Swappiness) - } else { - // Swappiness has a default of -1 - hostConfig.MemorySwappiness = -1 - } - if ctrSpec.Linux.Resources.Memory.DisableOOMKiller != nil { - hostConfig.OomKillDisable = *ctrSpec.Linux.Resources.Memory.DisableOOMKiller - } - } - if ctrSpec.Linux.Resources.Pids != nil { - hostConfig.PidsLimit = ctrSpec.Linux.Resources.Pids.Limit - } - hostConfig.CgroupConf = ctrSpec.Linux.Resources.Unified - if ctrSpec.Linux.Resources.BlockIO != nil { - if ctrSpec.Linux.Resources.BlockIO.Weight != nil { - hostConfig.BlkioWeight = *ctrSpec.Linux.Resources.BlockIO.Weight - } - hostConfig.BlkioWeightDevice = []define.InspectBlkioWeightDevice{} - for _, dev := range ctrSpec.Linux.Resources.BlockIO.WeightDevice { - key := fmt.Sprintf("%d:%d", dev.Major, dev.Minor) - // TODO: how do we handle LeafWeight vs - // Weight? For now, ignore anything - // without Weight set. - if dev.Weight == nil { - logrus.Infof("Ignoring weight device %s as it lacks a weight", key) - continue - } - if deviceNodes == nil { - nodes, err := util.FindDeviceNodes() - if err != nil { - return nil, err - } - deviceNodes = nodes - } - path, ok := deviceNodes[key] - if !ok { - logrus.Infof("Could not locate weight device %s in system devices", key) - continue - } - weightDev := define.InspectBlkioWeightDevice{} - weightDev.Path = path - weightDev.Weight = *dev.Weight - hostConfig.BlkioWeightDevice = append(hostConfig.BlkioWeightDevice, weightDev) - } - - readBps, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleReadBpsDevice) - if err != nil { - return nil, err - } - hostConfig.BlkioDeviceReadBps = readBps - - writeBps, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleWriteBpsDevice) - if err != nil { - return nil, err - } - hostConfig.BlkioDeviceWriteBps = writeBps - - readIops, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleReadIOPSDevice) - if err != nil { - return nil, err - } - hostConfig.BlkioDeviceReadIOps = readIops - - writeIops, err := blkioDeviceThrottle(deviceNodes, ctrSpec.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice) - if err != nil { - return nil, err - } - hostConfig.BlkioDeviceWriteIOps = writeIops - } - } + if err := c.platformInspectContainerHostConfig(ctrSpec, hostConfig); err != nil { + return nil, err } // NanoCPUs. @@ -659,182 +550,6 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named hostConfig.PortBindings = make(map[string][]define.InspectHostPort) } - // Cap add and cap drop. - // We need a default set of capabilities to compare against. - // The OCI generate package has one, and is commonly used, so we'll - // use it. - // Problem: there are 5 sets of capabilities. - // Use the bounding set for this computation, it's the most encompassing - // (but still not perfect). - capAdd := []string{} - capDrop := []string{} - // No point in continuing if we got a spec without a Process block... - if ctrSpec.Process != nil { - // Max an O(1) lookup table for default bounding caps. - boundingCaps := make(map[string]bool) - g, err := generate.New("linux") - if err != nil { - return nil, err - } - if !hostConfig.Privileged { - for _, cap := range g.Config.Process.Capabilities.Bounding { - boundingCaps[cap] = true - } - } else { - // If we are privileged, use all caps. - for _, cap := range capability.List() { - if g.HostSpecific && cap > validate.LastCap() { - continue - } - boundingCaps[fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))] = true - } - } - // Iterate through spec caps. - // If it's not in default bounding caps, it was added. - // If it is, delete from the default set. Whatever remains after - // we finish are the dropped caps. - for _, cap := range ctrSpec.Process.Capabilities.Bounding { - if _, ok := boundingCaps[cap]; ok { - delete(boundingCaps, cap) - } else { - capAdd = append(capAdd, cap) - } - } - for cap := range boundingCaps { - capDrop = append(capDrop, cap) - } - // Sort CapDrop so it displays in consistent order (GH #9490) - sort.Strings(capDrop) - } - hostConfig.CapAdd = capAdd - hostConfig.CapDrop = capDrop - switch { - case c.config.IPCNsCtr != "": - hostConfig.IpcMode = fmt.Sprintf("container:%s", c.config.IPCNsCtr) - case ctrSpec.Linux != nil: - // Locate the spec's IPC namespace. - // If there is none, it's ipc=host. - // If there is one and it has a path, it's "ns:". - // If no path, it's default - the empty string. - for _, ns := range ctrSpec.Linux.Namespaces { - if ns.Type == spec.IPCNamespace { - if ns.Path != "" { - hostConfig.IpcMode = fmt.Sprintf("ns:%s", ns.Path) - } else { - break - } - } - } - case c.config.NoShm: - hostConfig.IpcMode = "none" - case c.config.NoShmShare: - hostConfig.IpcMode = "private" - } - if hostConfig.IpcMode == "" { - hostConfig.IpcMode = "shareable" - } - - // Cgroup namespace mode - cgroupMode := "" - if c.config.CgroupNsCtr != "" { - cgroupMode = fmt.Sprintf("container:%s", c.config.CgroupNsCtr) - } else if ctrSpec.Linux != nil { - // Locate the spec's cgroup namespace - // If there is none, it's cgroup=host. - // If there is one and it has a path, it's "ns:". - // If there is no path, it's private. - for _, ns := range ctrSpec.Linux.Namespaces { - if ns.Type == spec.CgroupNamespace { - if ns.Path != "" { - cgroupMode = fmt.Sprintf("ns:%s", ns.Path) - } else { - cgroupMode = "private" - } - } - } - if cgroupMode == "" { - cgroupMode = "host" - } - } - hostConfig.CgroupMode = cgroupMode - - // Cgroup parent - // Need to check if it's the default, and not print if so. - defaultCgroupParent := "" - switch c.CgroupManager() { - case config.CgroupfsCgroupsManager: - defaultCgroupParent = CgroupfsDefaultCgroupParent - case config.SystemdCgroupsManager: - defaultCgroupParent = SystemdDefaultCgroupParent - } - if c.config.CgroupParent != defaultCgroupParent { - hostConfig.CgroupParent = c.config.CgroupParent - } - hostConfig.CgroupManager = c.CgroupManager() - - // PID namespace mode - pidMode := "" - if c.config.PIDNsCtr != "" { - pidMode = fmt.Sprintf("container:%s", c.config.PIDNsCtr) - } else if ctrSpec.Linux != nil { - // Locate the spec's PID namespace. - // If there is none, it's pid=host. - // If there is one and it has a path, it's "ns:". - // If there is no path, it's default - the empty string. - for _, ns := range ctrSpec.Linux.Namespaces { - if ns.Type == spec.PIDNamespace { - if ns.Path != "" { - pidMode = fmt.Sprintf("ns:%s", ns.Path) - } else { - pidMode = "private" - } - break - } - } - if pidMode == "" { - pidMode = "host" - } - } - hostConfig.PidMode = pidMode - - // UTS namespace mode - utsMode := c.NamespaceMode(spec.UTSNamespace, ctrSpec) - - hostConfig.UTSMode = utsMode - - // User namespace mode - usernsMode := "" - if c.config.UserNsCtr != "" { - usernsMode = fmt.Sprintf("container:%s", c.config.UserNsCtr) - } else if ctrSpec.Linux != nil { - // Locate the spec's user namespace. - // If there is none, it's default - the empty string. - // If there is one, it's "private" if no path, or "ns:" if - // there's a path. - - for _, ns := range ctrSpec.Linux.Namespaces { - if ns.Type == spec.UserNamespace { - if ns.Path != "" { - usernsMode = fmt.Sprintf("ns:%s", ns.Path) - } else { - usernsMode = "private" - } - } - } - } - hostConfig.UsernsMode = usernsMode - if c.config.IDMappings.UIDMap != nil && c.config.IDMappings.GIDMap != nil { - hostConfig.IDMappings = generateIDMappings(c.config.IDMappings) - } - // Devices - // Do not include if privileged - assumed that all devices will be - // included. - var err error - hostConfig.Devices, err = c.GetDevices(hostConfig.Privileged, *ctrSpec, deviceNodes) - if err != nil { - return nil, err - } - // Ulimits hostConfig.Ulimits = []define.InspectUlimit{} if ctrSpec.Process != nil { |