summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_config.go4
-rw-r--r--libpod/container_internal_linux.go43
-rw-r--r--libpod/container_path_resolution.go2
-rw-r--r--libpod/define/container.go9
-rw-r--r--libpod/define/container_inspect.go2
-rw-r--r--libpod/kube.go49
-rw-r--r--libpod/options.go22
-rw-r--r--libpod/pod_internal.go7
-rw-r--r--libpod/runtime_ctr.go5
-rw-r--r--libpod/runtime_pod_linux.go25
10 files changed, 133 insertions, 35 deletions
diff --git a/libpod/container_config.go b/libpod/container_config.go
index da732c05b..904c03f9b 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -301,7 +301,7 @@ type ContainerMiscConfig struct {
StopSignal uint `json:"stopSignal,omitempty"`
// StopTimeout is the signal that will be used to stop the container
StopTimeout uint `json:"stopTimeout,omitempty"`
- // Timeout is maximimum time a container will run before getting the kill signal
+ // Timeout is maximum time a container will run before getting the kill signal
Timeout uint `json:"timeout,omitempty"`
// Time container was created
CreatedTime time.Time `json:"createdTime"`
@@ -373,4 +373,6 @@ type ContainerMiscConfig struct {
PidFile string `json:"pid_file,omitempty"`
// CDIDevices contains devices that use the CDI
CDIDevices []string `json:"cdiDevices,omitempty"`
+ // EnvSecrets are secrets that are set as environment variables
+ EnvSecrets map[string]*secrets.Secret `json:"secret_env,omitempty"`
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index f87e845cb..7d57e8965 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -29,6 +29,7 @@ import (
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/chown"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/secrets"
"github.com/containers/common/pkg/subscriptions"
"github.com/containers/common/pkg/umask"
"github.com/containers/podman/v3/libpod/define"
@@ -377,14 +378,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
case "z":
fallthrough
case "Z":
- if c.MountLabel() != "" {
- if c.ProcessLabel() != "" {
- if err := label.Relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil {
- return nil, err
- }
- } else {
- logrus.Infof("Not relabeling volume %q in container %s as SELinux is disabled", m.Source, c.ID())
- }
+ if err := label.Relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil {
+ return nil, err
}
default:
@@ -763,6 +758,19 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
if c.state.ExtensionStageHooks, err = c.setupOCIHooks(ctx, g.Config); err != nil {
return nil, errors.Wrapf(err, "error setting up OCI Hooks")
}
+ if len(c.config.EnvSecrets) > 0 {
+ manager, err := secrets.NewManager(c.runtime.GetSecretsStorageDir())
+ if err != nil {
+ return nil, err
+ }
+ for name, secr := range c.config.EnvSecrets {
+ _, data, err := manager.LookupSecretData(secr.Name)
+ if err != nil {
+ return nil, err
+ }
+ g.AddProcessEnv(name, string(data))
+ }
+ }
return g.Config, nil
}
@@ -2216,6 +2224,17 @@ func (c *Container) generatePasswdAndGroup() (string, string, error) {
return passwdPath, groupPath, nil
}
+func isRootlessCgroupSet(cgroup string) bool {
+ // old versions of podman were setting the CgroupParent to CgroupfsDefaultCgroupParent
+ // by default. Avoid breaking these versions and check whether the cgroup parent is
+ // set to the default and in this case enable the old behavior. It should not be a real
+ // problem because the default CgroupParent is usually owned by root so rootless users
+ // cannot access it.
+ // This check might be lifted in a future version of Podman.
+ // Check both that the cgroup or its parent is set to the default value (used by pods).
+ return cgroup != CgroupfsDefaultCgroupParent && filepath.Dir(cgroup) != CgroupfsDefaultCgroupParent
+}
+
// Get cgroup path in a format suitable for the OCI spec
func (c *Container) getOCICgroupPath() (string, error) {
unified, err := cgroups.IsCgroup2UnifiedMode()
@@ -2227,13 +2246,7 @@ func (c *Container) getOCICgroupPath() (string, error) {
case c.config.NoCgroups:
return "", nil
case (rootless.IsRootless() && (cgroupManager == config.CgroupfsCgroupsManager || !unified)):
- if c.config.CgroupParent == CgroupfsDefaultCgroupParent {
- // old versions of podman were setting the CgroupParent to CgroupfsDefaultCgroupParent
- // by default. Avoid breaking these versions and check whether the cgroup parent is
- // set to the default and in this case enable the old behavior. It should not be a real
- // problem because the default CgroupParent is usually owned by root so rootless users
- // cannot access it.
- // This check might be lifted in a future version of Podman.
+ if !isRootlessCgroupSet(c.config.CgroupParent) {
return "", nil
}
return c.config.CgroupParent, nil
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index d798963b1..ec7306ca1 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -128,7 +128,7 @@ func isPathOnVolume(c *Container, containerPath string) bool {
if cleanedContainerPath == filepath.Clean(vol.Dest) {
return true
}
- for dest := vol.Dest; dest != "/"; dest = filepath.Dir(dest) {
+ for dest := vol.Dest; dest != "/" && dest != "."; dest = filepath.Dir(dest) {
if cleanedContainerPath == dest {
return true
}
diff --git a/libpod/define/container.go b/libpod/define/container.go
index 5a2ff026f..f3125afa9 100644
--- a/libpod/define/container.go
+++ b/libpod/define/container.go
@@ -17,3 +17,12 @@ const (
// handling of system restart, which Podman does not yet support.
RestartPolicyUnlessStopped = "unless-stopped"
)
+
+// RestartPolicyMap maps between restart-policy valid values to restart policy types
+var RestartPolicyMap = map[string]string{
+ "none": RestartPolicyNone,
+ RestartPolicyNo: RestartPolicyNo,
+ RestartPolicyAlways: RestartPolicyAlways,
+ RestartPolicyOnFailure: RestartPolicyOnFailure,
+ RestartPolicyUnlessStopped: RestartPolicyUnlessStopped,
+}
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index c236f35b0..5283946fa 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -66,7 +66,7 @@ type InspectContainerConfig struct {
Secrets []*InspectSecret `json:"Secrets,omitempty"`
// Timeout is time before container is killed by conmon
Timeout uint `json:"Timeout"`
- // StopTimeout is time before container is stoped when calling stop
+ // StopTimeout is time before container is stopped when calling stop
StopTimeout uint `json:"StopTimeout"`
}
diff --git a/libpod/kube.go b/libpod/kube.go
index adcfe92c9..a3f49bfe8 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -218,9 +218,15 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
deDupPodVolumes := make(map[string]*v1.Volume)
first := true
podContainers := make([]v1.Container, 0, len(containers))
+ podAnnotations := make(map[string]string)
dnsInfo := v1.PodDNSConfig{}
for _, ctr := range containers {
if !ctr.IsInfra() {
+ // Convert auto-update labels into kube annotations
+ for k, v := range getAutoUpdateAnnotations(removeUnderscores(ctr.Name()), ctr.Labels()) {
+ podAnnotations[k] = v
+ }
+
ctr, volumes, _, err := containerToV1Container(ctr)
if err != nil {
return nil, err
@@ -267,10 +273,16 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
podVolumes = append(podVolumes, *vol)
}
- return addContainersAndVolumesToPodObject(podContainers, podVolumes, p.Name(), &dnsInfo, hostNetwork), nil
+ return newPodObject(
+ p.Name(),
+ podAnnotations,
+ podContainers,
+ podVolumes,
+ &dnsInfo,
+ hostNetwork), nil
}
-func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.Volume, podName string, dnsOptions *v1.PodDNSConfig, hostNetwork bool) *v1.Pod {
+func newPodObject(podName string, annotations map[string]string, containers []v1.Container, volumes []v1.Volume, dnsOptions *v1.PodDNSConfig, hostNetwork bool) *v1.Pod {
tm := v12.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
@@ -287,6 +299,7 @@ func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.
// will reflect time this is run (not container create time) because the conversion
// of the container create time to v1 Time is probably not warranted nor worthwhile.
CreationTimestamp: v12.Now(),
+ Annotations: annotations,
}
ps := v1.PodSpec{
Containers: containers,
@@ -311,7 +324,13 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
kubeVolumes := make([]v1.Volume, 0)
hostNetwork := true
podDNS := v1.PodDNSConfig{}
+ kubeAnnotations := make(map[string]string)
for _, ctr := range ctrs {
+ // Convert auto-update labels into kube annotations
+ for k, v := range getAutoUpdateAnnotations(removeUnderscores(ctr.Name()), ctr.Labels()) {
+ kubeAnnotations[k] = v
+ }
+
if !ctr.HostNetwork() {
hostNetwork = false
}
@@ -355,7 +374,13 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
}
} // end if ctrDNS
}
- return addContainersAndVolumesToPodObject(kubeCtrs, kubeVolumes, strings.ReplaceAll(ctrs[0].Name(), "_", ""), &podDNS, hostNetwork), nil
+ return newPodObject(
+ strings.ReplaceAll(ctrs[0].Name(), "_", ""),
+ kubeAnnotations,
+ kubeCtrs,
+ kubeVolumes,
+ &podDNS,
+ hostNetwork), nil
}
// containerToV1Container converts information we know about a libpod container
@@ -792,3 +817,21 @@ func generateKubeVolumeDeviceFromLinuxDevice(devices []specs.LinuxDevice) []v1.V
func removeUnderscores(s string) string {
return strings.Replace(s, "_", "", -1)
}
+
+// getAutoUpdateAnnotations searches for auto-update container labels
+// and returns them as kube annotations
+func getAutoUpdateAnnotations(ctrName string, ctrLabels map[string]string) map[string]string {
+ autoUpdateLabel := "io.containers.autoupdate"
+ annotations := make(map[string]string)
+
+ for k, v := range ctrLabels {
+ if strings.Contains(k, autoUpdateLabel) {
+ // since labels can variate between containers within a pod, they will be
+ // identified with the container name when converted into kube annotations
+ kc := fmt.Sprintf("%s/%s", k, ctrName)
+ annotations[kc] = v
+ }
+ }
+
+ return annotations
+}
diff --git a/libpod/options.go b/libpod/options.go
index 391cf0147..be26ced99 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1716,6 +1716,28 @@ func WithSecrets(secretNames []string) CtrCreateOption {
}
}
+// WithSecrets adds environment variable secrets to the container
+func WithEnvSecrets(envSecrets map[string]string) CtrCreateOption {
+ return func(ctr *Container) error {
+ ctr.config.EnvSecrets = make(map[string]*secrets.Secret)
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+ manager, err := secrets.NewManager(ctr.runtime.GetSecretsStorageDir())
+ if err != nil {
+ return err
+ }
+ for target, src := range envSecrets {
+ secr, err := manager.Lookup(src)
+ if err != nil {
+ return err
+ }
+ ctr.config.EnvSecrets[target] = secr
+ }
+ return nil
+ }
+}
+
// WithPidFile adds pidFile to the container
func WithPidFile(pidFile string) CtrCreateOption {
return func(ctr *Container) error {
diff --git a/libpod/pod_internal.go b/libpod/pod_internal.go
index 31b4ba443..e81bd7b16 100644
--- a/libpod/pod_internal.go
+++ b/libpod/pod_internal.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/storage/pkg/stringid"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -74,9 +75,11 @@ func (p *Pod) refresh() error {
}
p.state.CgroupPath = cgroupPath
case config.CgroupfsCgroupsManager:
- p.state.CgroupPath = filepath.Join(p.config.CgroupParent, p.ID())
+ if rootless.IsRootless() && isRootlessCgroupSet(p.config.CgroupParent) {
+ p.state.CgroupPath = filepath.Join(p.config.CgroupParent, p.ID())
- logrus.Debugf("setting pod cgroup to %s", p.state.CgroupPath)
+ logrus.Debugf("setting pod cgroup to %s", p.state.CgroupPath)
+ }
default:
return errors.Wrapf(define.ErrInvalidArg, "unknown cgroups manager %s specified", p.runtime.config.Engine.CgroupManager)
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 328f47c12..7d31e392f 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -295,7 +295,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if podCgroup == "" {
return nil, errors.Wrapf(define.ErrInternal, "pod %s cgroup is not set", pod.ID())
}
- ctr.config.CgroupParent = podCgroup
+ canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(podCgroup)
+ if canUseCgroup {
+ ctr.config.CgroupParent = podCgroup
+ }
} else if !rootless.IsRootless() {
ctr.config.CgroupParent = CgroupfsDefaultCgroupParent
}
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index cf48a9453..4ede23cac 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -75,17 +75,20 @@ func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (_ *Po
// Check CGroup parent sanity, and set it if it was not set
switch r.config.Engine.CgroupManager {
case config.CgroupfsCgroupsManager:
- if pod.config.CgroupParent == "" {
- pod.config.CgroupParent = CgroupfsDefaultCgroupParent
- } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
- return nil, errors.Wrapf(define.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs")
- }
- // If we are set to use pod cgroups, set the cgroup parent that
- // all containers in the pod will share
- // No need to create it with cgroupfs - the first container to
- // launch should do it for us
- if pod.config.UsePodCgroup {
- pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
+ canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(pod.config.CgroupParent)
+ if canUseCgroup {
+ if pod.config.CgroupParent == "" {
+ pod.config.CgroupParent = CgroupfsDefaultCgroupParent
+ } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs")
+ }
+ // If we are set to use pod cgroups, set the cgroup parent that
+ // all containers in the pod will share
+ // No need to create it with cgroupfs - the first container to
+ // launch should do it for us
+ if pod.config.UsePodCgroup {
+ pod.state.CgroupPath = filepath.Join(pod.config.CgroupParent, pod.ID())
+ }
}
case config.SystemdCgroupsManager:
if pod.config.CgroupParent == "" {