summaryrefslogtreecommitdiff
path: root/libpod/pod.go
diff options
context:
space:
mode:
authorcdoern <cdoern@redhat.com>2021-07-14 16:30:28 -0400
committercdoern <cdoern@redhat.com>2021-08-26 16:05:16 -0400
commitd28e85741fedb89be48a03d4f05687e970eb71b9 (patch)
tree0b79a6757b0fc7ad3caa33ad94f721d8296d9c1a /libpod/pod.go
parent94c37d7d470871f9d63b32c97094f5faab1e8a08 (diff)
downloadpodman-d28e85741fedb89be48a03d4f05687e970eb71b9.tar.gz
podman-d28e85741fedb89be48a03d4f05687e970eb71b9.tar.bz2
podman-d28e85741fedb89be48a03d4f05687e970eb71b9.zip
InfraContainer Rework
InfraContainer should go through the same creation process as regular containers. This change was from the cmd level down, involving new container CLI opts and specgen creating functions. What now happens is that both container and pod cli options are populated in cmd and used to create a podSpecgen and a containerSpecgen. The process then goes as follows FillOutSpecGen (infra) -> MapSpec (podOpts -> infraOpts) -> PodCreate -> MakePod -> createPodOptions -> NewPod -> CompleteSpec (infra) -> MakeContainer -> NewContainer -> newContainer -> AddInfra (to pod state) Signed-off-by: cdoern <cdoern@redhat.com>
Diffstat (limited to 'libpod/pod.go')
-rw-r--r--libpod/pod.go169
1 files changed, 98 insertions, 71 deletions
diff --git a/libpod/pod.go b/libpod/pod.go
index 7df15df7b..e4516b354 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -2,14 +2,12 @@ package libpod
import (
"context"
- "net"
+ "fmt"
"sort"
"time"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/lock"
- "github.com/containers/podman/v3/pkg/specgen"
- "github.com/cri-o/ocicni/pkg/ocicni"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -63,7 +61,7 @@ type PodConfig struct {
UsePodUTS bool `json:"sharesUts,omitempty"`
UsePodCgroupNS bool `json:"sharesCgroupNS,omitempty"`
- InfraContainer *InfraContainerConfig `json:"infraConfig"`
+ HasInfra bool `json:"hasInfra,omitempty"`
// Time pod was created
CreatedTime time.Time `json:"created"`
@@ -85,41 +83,6 @@ type podState struct {
InfraContainerID string
}
-// InfraContainerConfig is the configuration for the pod's infra container.
-// Generally speaking, these are equivalent to container configuration options
-// you will find in container_config.go (and even named identically), save for
-// HasInfraContainer (which determines if an infra container is even created -
-// if it is false, no other options in this struct will be used) and HostNetwork
-// (this involves the created OCI spec, and as such is not represented directly
-// in container_config.go).
-// Generally speaking, aside from those two exceptions, these options will set
-// the equivalent field in the container's configuration.
-type InfraContainerConfig struct {
- ConmonPidFile string `json:"conmonPidFile"`
- HasInfraContainer bool `json:"makeInfraContainer"`
- NoNetwork bool `json:"noNetwork,omitempty"`
- HostNetwork bool `json:"infraHostNetwork,omitempty"`
- PidNS specgen.Namespace `json:"infraPid,omitempty"`
- PortBindings []ocicni.PortMapping `json:"infraPortBindings"`
- StaticIP net.IP `json:"staticIP,omitempty"`
- StaticMAC net.HardwareAddr `json:"staticMAC,omitempty"`
- UseImageResolvConf bool `json:"useImageResolvConf,omitempty"`
- DNSServer []string `json:"dnsServer,omitempty"`
- DNSSearch []string `json:"dnsSearch,omitempty"`
- DNSOption []string `json:"dnsOption,omitempty"`
- UseImageHosts bool `json:"useImageHosts,omitempty"`
- HostAdd []string `json:"hostsAdd,omitempty"`
- Networks []string `json:"networks,omitempty"`
- ExitCommand []string `json:"exitCommand,omitempty"`
- InfraImage string `json:"infraImage,omitempty"`
- InfraCommand []string `json:"infraCommand,omitempty"`
- InfraName string `json:"infraName,omitempty"`
- Slirp4netns bool `json:"slirp4netns,omitempty"`
- NetworkOptions map[string][]string `json:"network_options,omitempty"`
- ResourceLimits *specs.LinuxResources `json:"resource_limits,omitempty"`
- Userns specgen.Namespace `json:"userns,omitempty"`
-}
-
// ID retrieves the pod's ID
func (p *Pod) ID() string {
return p.config.ID
@@ -139,45 +102,104 @@ func (p *Pod) Namespace() string {
// ResourceLim returns the cpuset resource limits for the pod
func (p *Pod) ResourceLim() *specs.LinuxResources {
resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ empty := &specs.LinuxResources{
+ CPU: &specs.LinuxCPU{},
+ }
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return empty
+ }
+ conf := infra.config.Spec
+ if err != nil {
+ return empty
+ }
+ if conf.Linux == nil || conf.Linux.Resources == nil {
+ return empty
+ }
+ if err = JSONDeepCopy(conf.Linux.Resources, resCopy); err != nil {
return nil
}
- if resCopy != nil && resCopy.CPU != nil {
+ if resCopy.CPU != nil {
return resCopy
}
- empty := &specs.LinuxResources{
- CPU: &specs.LinuxCPU{},
- }
+
return empty
}
// CPUPeriod returns the pod CPU period
func (p *Pod) CPUPeriod() uint64 {
- resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ if p.state.InfraContainerID == "" {
return 0
}
- if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Period != nil {
- return *resCopy.CPU.Period
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return 0
+ }
+ conf := infra.config.Spec
+ if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Period != nil {
+ return *conf.Linux.Resources.CPU.Period
}
return 0
}
// CPUQuota returns the pod CPU quota
func (p *Pod) CPUQuota() int64 {
- resCopy := &specs.LinuxResources{}
- if err := JSONDeepCopy(p.config.InfraContainer.ResourceLimits, resCopy); err != nil {
+ if p.state.InfraContainerID == "" {
+ return 0
+ }
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
return 0
}
- if resCopy != nil && resCopy.CPU != nil && resCopy.CPU.Quota != nil {
- return *resCopy.CPU.Quota
+ conf := infra.config.Spec
+ if conf != nil && conf.Linux != nil && conf.Linux.Resources != nil && conf.Linux.Resources.CPU != nil && conf.Linux.Resources.CPU.Quota != nil {
+ return *conf.Linux.Resources.CPU.Quota
}
return 0
}
// PidMode returns the PID mode given by the user ex: pod, private...
func (p *Pod) PidMode() string {
- return string(p.config.InfraContainer.PidNS.NSMode)
+ infra, err := p.runtime.GetContainer(p.state.InfraContainerID)
+ if err != nil {
+ return ""
+ }
+ conf := infra.Config()
+ ctrSpec := conf.Spec
+ if ctrSpec != nil && ctrSpec.Linux != nil {
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == specs.PIDNamespace {
+ if ns.Path != "" {
+ return fmt.Sprintf("ns:%s", ns.Path)
+ }
+ return "private"
+ }
+ }
+ return "host"
+ }
+ return ""
+}
+
+// PidMode returns the PID mode given by the user ex: pod, private...
+func (p *Pod) UserNSMode() string {
+ infra, err := p.infraContainer()
+ if err != nil {
+ return ""
+ }
+ conf := infra.Config()
+ ctrSpec := conf.Spec
+ if ctrSpec != nil && ctrSpec.Linux != nil {
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == specs.UserNamespace {
+ if ns.Path != "" {
+ return fmt.Sprintf("ns:%s", ns.Path)
+ }
+ return "private"
+ }
+ }
+ return "host"
+ }
+ return ""
}
// Labels returns the pod's labels
@@ -263,20 +285,24 @@ func (p *Pod) CgroupPath() (string, error) {
if p.state.CgroupPath != "" {
return p.state.CgroupPath, nil
}
- if !p.HasInfraContainer() {
+ if p.state.InfraContainerID == "" {
return "", errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
}
- id := p.state.InfraContainerID
+ id, err := p.infraContainerID()
+ if err != nil {
+ return "", err
+ }
if id != "" {
- ctr, err := p.runtime.state.Container(id)
+ ctr, err := p.infraContainer()
if err != nil {
return "", errors.Wrapf(err, "could not get infra")
}
if ctr != nil {
- ctr.Start(context.Background(), false)
+ ctr.Start(context.Background(), true)
cgroupPath, err := ctr.CGroupPath()
+ fmt.Println(cgroupPath)
if err != nil {
return "", errors.Wrapf(err, "could not get container cgroup")
}
@@ -325,7 +351,7 @@ func (p *Pod) allContainers() ([]*Container, error) {
// HasInfraContainer returns whether the pod will create an infra container
func (p *Pod) HasInfraContainer() bool {
- return p.config.InfraContainer.HasInfraContainer
+ return p.config.HasInfra
}
// SharesNamespaces checks if the pod has any kernel namespaces set as shared. An infra container will not be
@@ -350,19 +376,26 @@ func (p *Pod) InfraContainerID() (string, error) {
return p.infraContainerID()
}
-// InfraContainer returns the infra container.
-func (p *Pod) InfraContainer() (*Container, error) {
- if !p.HasInfraContainer() {
- return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
- }
- id, err := p.InfraContainerID()
+// infraContainer is the unlocked versio of InfraContainer which returns the infra container
+func (p *Pod) infraContainer() (*Container, error) {
+ id, err := p.infraContainerID()
if err != nil {
return nil, err
}
+ if id == "" {
+ return nil, errors.Wrap(define.ErrNoSuchCtr, "pod has no infra container")
+ }
return p.runtime.state.Container(id)
}
+// InfraContainer returns the infra container.
+func (p *Pod) InfraContainer() (*Container, error) {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+ return p.infraContainer()
+}
+
// TODO add pod batching
// Lock pod to avoid lock contention
// Store and lock all containers (no RemoveContainer in batch guarantees cache will not become stale)
@@ -412,13 +445,7 @@ func (p *Pod) ProcessLabel() (string, error) {
if !p.HasInfraContainer() {
return "", nil
}
-
- id, err := p.InfraContainerID()
- if err != nil {
- return "", err
- }
-
- ctr, err := p.runtime.state.Container(id)
+ ctr, err := p.infraContainer()
if err != nil {
return "", err
}