diff options
author | cdoern <cdoern@redhat.com> | 2021-07-14 16:30:28 -0400 |
---|---|---|
committer | cdoern <cdoern@redhat.com> | 2021-08-26 16:05:16 -0400 |
commit | d28e85741fedb89be48a03d4f05687e970eb71b9 (patch) | |
tree | 0b79a6757b0fc7ad3caa33ad94f721d8296d9c1a /libpod/pod.go | |
parent | 94c37d7d470871f9d63b32c97094f5faab1e8a08 (diff) | |
download | podman-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.go | 169 |
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 } |