summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers.go24
-rw-r--r--pkg/adapter/pods.go75
-rw-r--r--pkg/namespaces/namespaces.go5
-rw-r--r--pkg/rootless/rootless_linux.c14
-rw-r--r--pkg/spec/createconfig.go8
-rw-r--r--pkg/spec/spec.go13
-rw-r--r--pkg/spec/storage.go8
-rw-r--r--pkg/util/mountOpts.go31
8 files changed, 125 insertions, 53 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 64550f545..287bd8474 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -400,17 +400,8 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
}
- config, err := r.Runtime.GetConfig()
- if err != nil {
- return exitCode, err
- }
- detachKeys := c.String("detach-keys")
- if detachKeys == "" {
- detachKeys = config.DetachKeys
- }
-
// if the container was created as part of a pod, also start its dependencies, if any.
- if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, detachKeys, c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
+ if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
// We've manually detached from the container
// Do not perform cleanup, or wait for container exit code
// Just exit immediately
@@ -547,12 +538,13 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues)
)
options := libpod.ContainerCheckpointOptions{
- Keep: c.Keep,
- TCPEstablished: c.TcpEstablished,
- TargetFile: c.Import,
- Name: c.Name,
- IgnoreRootfs: c.IgnoreRootfs,
- IgnoreStaticIP: c.IgnoreStaticIP,
+ Keep: c.Keep,
+ TCPEstablished: c.TcpEstablished,
+ TargetFile: c.Import,
+ Name: c.Name,
+ IgnoreRootfs: c.IgnoreRootfs,
+ IgnoreStaticIP: c.IgnoreStaticIP,
+ IgnoreStaticMAC: c.IgnoreStaticMAC,
}
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go
index d8d5b884f..6648edc82 100644
--- a/pkg/adapter/pods.go
+++ b/pkg/adapter/pods.go
@@ -666,6 +666,58 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
return infraPorts
}
+func setupSecurityContext(containerConfig *createconfig.CreateConfig, containerYAML v1.Container) {
+ if containerYAML.SecurityContext == nil {
+ return
+ }
+ if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
+ containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
+ }
+ if containerYAML.SecurityContext.Privileged != nil {
+ containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
+ }
+
+ if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
+ containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
+ }
+
+ if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil {
+ if seopt.User != "" {
+ containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=user:%s", seopt.User))
+ containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("user:%s", seopt.User))
+ }
+ if seopt.Role != "" {
+ containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=role:%s", seopt.Role))
+ containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("role:%s", seopt.Role))
+ }
+ if seopt.Type != "" {
+ containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=type:%s", seopt.Type))
+ containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("type:%s", seopt.Type))
+ }
+ if seopt.Level != "" {
+ containerConfig.SecurityOpts = append(containerConfig.SecurityOpts, fmt.Sprintf("label=level:%s", seopt.Level))
+ containerConfig.LabelOpts = append(containerConfig.LabelOpts, fmt.Sprintf("level:%s", seopt.Level))
+ }
+ }
+ if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
+ for _, capability := range caps.Add {
+ containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability))
+ }
+ for _, capability := range caps.Drop {
+ containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
+ }
+ }
+ if containerYAML.SecurityContext.RunAsUser != nil {
+ containerConfig.User = fmt.Sprintf("%d", *containerYAML.SecurityContext.RunAsUser)
+ }
+ if containerYAML.SecurityContext.RunAsGroup != nil {
+ if containerConfig.User == "" {
+ containerConfig.User = "0"
+ }
+ containerConfig.User = fmt.Sprintf("%s:%d", containerConfig.User, *containerYAML.SecurityContext.RunAsGroup)
+ }
+}
+
// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) {
var (
@@ -690,29 +742,8 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
containerConfig.User = imageData.Config.User
}
- if containerYAML.SecurityContext != nil {
- if containerConfig.SecurityOpts != nil {
- if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
- containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
- }
- if containerYAML.SecurityContext.Privileged != nil {
- containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
- }
-
- if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
- containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
- }
+ setupSecurityContext(&containerConfig, containerYAML)
- }
- if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
- for _, capability := range caps.Add {
- containerConfig.CapAdd = append(containerConfig.CapAdd, string(capability))
- }
- for _, capability := range caps.Drop {
- containerConfig.CapDrop = append(containerConfig.CapDrop, string(capability))
- }
- }
- }
var err error
containerConfig.SeccompProfilePath, err = libpod.DefaultSeccompPath()
if err != nil {
diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go
index 9d1033b93..78b55bb2a 100644
--- a/pkg/namespaces/namespaces.go
+++ b/pkg/namespaces/namespaces.go
@@ -25,6 +25,11 @@ func (n CgroupMode) IsHost() bool {
return n == hostType
}
+// IsDefaultValue indicates whether the cgroup namespace has the default value.
+func (n CgroupMode) IsDefaultValue() bool {
+ return n == ""
+}
+
// IsNS indicates a cgroup namespace passed in by path (ns:<path>)
func (n CgroupMode) IsNS() bool {
return strings.HasPrefix(string(n), nsType)
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index 94933ddd0..9604de638 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -24,12 +24,16 @@
int renameat2 (int olddirfd, const char *oldpath, int newdirfd, const char *newpath, unsigned int flags)
{
-# ifdef __NR_renameat2
- return (int) syscall (__NR_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
+# ifdef SYS_renameat2
+ return (int) syscall (SYS_renameat2, olddirfd, oldpath, newdirfd, newpath, flags);
# else
- /* no way to implement it atomically. */
- errno = ENOSYS;
- return -1;
+ /* This might be an issue if another process is trying to read the file while it is empty. */
+ int fd = open (newpath, O_EXCL|O_CREAT, 0700);
+ if (fd < 0)
+ return fd;
+ close (fd);
+ /* We are sure we created the file, let's overwrite it. */
+ return rename (oldpath, newpath);
# endif
}
#endif
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 2a8fe7332..e054b3b13 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -396,6 +396,14 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
options = append(options, libpod.WithStaticIP(ip))
}
+ if c.MacAddress != "" {
+ mac, err := net.ParseMAC(c.MacAddress)
+ if err != nil {
+ return nil, errors.Wrapf(define.ErrInvalidArg, "cannot parse %s as MAC address: %v", c.MacAddress, err)
+ }
+ options = append(options, libpod.WithStaticMAC(mac))
+ }
+
options = append(options, libpod.WithPrivileged(c.Privileged))
useImageVolumes := c.ImageVolumeType == TypeBind
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 86d701f7e..33e9ec076 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -631,6 +631,19 @@ func addIpcNS(config *CreateConfig, g *generate.Generator) error {
func addCgroupNS(config *CreateConfig, g *generate.Generator) error {
cgroupMode := config.CgroupMode
+
+ if cgroupMode.IsDefaultValue() {
+ // If the value is not specified, default to "private" on cgroups v2 and "host" on cgroups v1.
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return err
+ }
+ if unified {
+ cgroupMode = "private"
+ } else {
+ cgroupMode = "host"
+ }
+ }
if cgroupMode.IsNS() {
return g.AddOrReplaceLinuxNamespace(string(spec.CgroupNamespace), NS(string(cgroupMode)))
}
diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go
index 095534589..e30bdfc67 100644
--- a/pkg/spec/storage.go
+++ b/pkg/spec/storage.go
@@ -514,11 +514,17 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
Source: TypeTmpfs,
}
- var setDest, setRORW, setSuid, setDev, setExec bool
+ var setDest, setRORW, setSuid, setDev, setExec, setTmpcopyup bool
for _, val := range args {
kv := strings.Split(val, "=")
switch kv[0] {
+ case "tmpcopyup", "notmpcopyup":
+ if setTmpcopyup {
+ return newMount, errors.Wrapf(optionArgError, "cannot pass 'tmpcopyup' and 'notmpcopyup' options more than once")
+ }
+ setTmpcopyup = true
+ newMount.Options = append(newMount.Options, kv[0])
case "ro", "rw":
if setRORW {
return newMount, errors.Wrapf(optionArgError, "cannot pass 'ro' and 'rw' options more than once")
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index 670daeaf9..d21800bc3 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -30,6 +30,8 @@ func ProcessOptions(options []string, isTmpfs bool, defaults *DefaultMountOption
foundWrite, foundSize, foundProp, foundMode, foundExec, foundSuid, foundDev, foundCopyUp, foundBind, foundZ bool
)
+ var newOptions []string
+
for _, opt := range options {
// Some options have parameters - size, mode
splitOpt := strings.SplitN(opt, "=", 2)
@@ -80,9 +82,19 @@ func ProcessOptions(options []string, isTmpfs bool, defaults *DefaultMountOption
return nil, errors.Wrapf(ErrBadMntOption, "the 'tmpcopyup' option is only allowed with tmpfs mounts")
}
if foundCopyUp {
- return nil, errors.Wrapf(ErrDupeMntOption, "the 'tmpcopyup' option can only be set once")
+ return nil, errors.Wrapf(ErrDupeMntOption, "the 'tmpcopyup' or 'notmpcopyup' option can only be set once")
+ }
+ foundCopyUp = true
+ case "notmpcopyup":
+ if !isTmpfs {
+ return nil, errors.Wrapf(ErrBadMntOption, "the 'notmpcopyup' option is only allowed with tmpfs mounts")
+ }
+ if foundCopyUp {
+ return nil, errors.Wrapf(ErrDupeMntOption, "the 'tmpcopyup' or 'notmpcopyup' option can only be set once")
}
foundCopyUp = true
+ // do not propagate notmpcopyup to the OCI runtime
+ continue
case "bind", "rbind":
if isTmpfs {
return nil, errors.Wrapf(ErrBadMntOption, "the 'bind' and 'rbind' options are not allowed with tmpfs mounts")
@@ -101,29 +113,30 @@ func ProcessOptions(options []string, isTmpfs bool, defaults *DefaultMountOption
default:
return nil, errors.Wrapf(ErrBadMntOption, "unknown mount option %q", opt)
}
+ newOptions = append(newOptions, opt)
}
if !foundWrite {
- options = append(options, "rw")
+ newOptions = append(newOptions, "rw")
}
if !foundProp {
- options = append(options, "rprivate")
+ newOptions = append(newOptions, "rprivate")
}
if !foundExec && (defaults == nil || defaults.Noexec) {
- options = append(options, "noexec")
+ newOptions = append(newOptions, "noexec")
}
if !foundSuid && (defaults == nil || defaults.Nosuid) {
- options = append(options, "nosuid")
+ newOptions = append(newOptions, "nosuid")
}
if !foundDev && (defaults == nil || defaults.Nodev) {
- options = append(options, "nodev")
+ newOptions = append(newOptions, "nodev")
}
if isTmpfs && !foundCopyUp {
- options = append(options, "tmpcopyup")
+ newOptions = append(newOptions, "tmpcopyup")
}
if !isTmpfs && !foundBind {
- options = append(options, "rbind")
+ newOptions = append(newOptions, "rbind")
}
- return options, nil
+ return newOptions, nil
}