summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers.go50
-rw-r--r--pkg/adapter/containers_remote.go2
-rw-r--r--pkg/adapter/pods.go75
-rw-r--r--pkg/adapter/runtime.go2
-rw-r--r--pkg/adapter/terminal_linux.go3
-rw-r--r--pkg/cgroups/cpu.go4
-rw-r--r--pkg/namespaces/namespaces.go5
-rw-r--r--pkg/network/subnet.go4
-rw-r--r--pkg/rootless/rootless_linux.c14
-rw-r--r--pkg/spec/config_linux_cgo.go2
-rw-r--r--pkg/spec/spec.go21
-rw-r--r--pkg/util/utils.go14
-rw-r--r--pkg/varlinkapi/attach.go2
-rw-r--r--pkg/varlinkapi/containers.go8
14 files changed, 140 insertions, 66 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 430b6925d..a09466243 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -307,7 +307,11 @@ func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) er
if len(c.InputArgs) > 1 {
options.Multi = true
}
- logChannel := make(chan *logs.LogLine, int(c.Tail)*len(c.InputArgs)+1)
+ tailLen := int(c.Tail)
+ if tailLen < 0 {
+ tailLen = 0
+ }
+ logChannel := make(chan *logs.LogLine, tailLen*len(c.InputArgs)+1)
containers, err := shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
if err != nil {
return err
@@ -396,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
@@ -656,20 +651,25 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
return exitCode, nil
}
- if ctrRunning {
- fmt.Println(ctr.ID())
- continue
- }
- // Handle non-attach start
- // If the container is in a pod, also set to recursively start dependencies
- if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
- if lastError != nil {
- fmt.Fprintln(os.Stderr, lastError)
+ // Start the container if it's not running already.
+ if !ctrRunning {
+ // Handle non-attach start
+ // If the container is in a pod, also set to recursively start dependencies
+ if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
+ if lastError != nil {
+ fmt.Fprintln(os.Stderr, lastError)
+ }
+ lastError = errors.Wrapf(err, "unable to start container %q", container)
+ continue
}
- lastError = errors.Wrapf(err, "unable to start container %q", container)
- continue
}
- fmt.Println(ctr.ID())
+ // Check if the container is referenced by ID or by name and print
+ // it accordingly.
+ if strings.HasPrefix(ctr.ID(), container) {
+ fmt.Println(ctr.ID())
+ } else {
+ fmt.Println(container)
+ }
}
return exitCode, lastError
}
@@ -891,7 +891,7 @@ func (r *LocalRuntime) execPS(c *libpod.Container, args []string) ([]string, err
streams := new(libpod.AttachStreams)
streams.OutputStream = wPipe
streams.ErrorStream = wPipe
- streams.InputStream = os.Stdin
+ streams.InputStream = bufio.NewReader(os.Stdin)
streams.AttachOutput = true
streams.AttachError = true
streams.AttachInput = true
@@ -969,7 +969,7 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal
streams.OutputStream = os.Stdout
streams.ErrorStream = os.Stderr
if cli.Interactive {
- streams.InputStream = os.Stdin
+ streams.InputStream = bufio.NewReader(os.Stdin)
streams.AttachInput = true
}
streams.AttachOutput = true
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index f4e83a975..20471d895 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -1021,7 +1021,7 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co
func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecValues) (int, error) {
var (
oldTermState *term.State
- ec int = define.ExecErrorCodeGeneric
+ ec = define.ExecErrorCodeGeneric
)
// default invalid command exit code
// Validate given environment variables
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/adapter/runtime.go b/pkg/adapter/runtime.go
index 4f70e90f9..81a43853c 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -338,7 +338,7 @@ func (r *LocalRuntime) SaveImage(ctx context.Context, c *cliconfig.SaveValues) e
return newImage.Save(ctx, source, c.Format, c.Output, additionalTags, c.Quiet, c.Compress)
}
-// LoadImage is a wrapper function for libpod PruneVolumes
+// LoadImage is a wrapper function for libpod LoadImage
func (r *LocalRuntime) LoadImage(ctx context.Context, name string, cli *cliconfig.LoadValues) (string, error) {
var (
writer io.Writer
diff --git a/pkg/adapter/terminal_linux.go b/pkg/adapter/terminal_linux.go
index 16e552802..3dc5864e2 100644
--- a/pkg/adapter/terminal_linux.go
+++ b/pkg/adapter/terminal_linux.go
@@ -1,6 +1,7 @@
package adapter
import (
+ "bufio"
"context"
"fmt"
"os"
@@ -61,7 +62,7 @@ func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr,
streams := new(libpod.AttachStreams)
streams.OutputStream = stdout
streams.ErrorStream = stderr
- streams.InputStream = stdin
+ streams.InputStream = bufio.NewReader(stdin)
streams.AttachOutput = true
streams.AttachError = true
streams.AttachInput = true
diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go
index 03677f1ef..a43a76b22 100644
--- a/pkg/cgroups/cpu.go
+++ b/pkg/cgroups/cpu.go
@@ -81,14 +81,14 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error {
return err
}
if val, found := values["usage_usec"]; found {
- usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
+ usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
if err != nil {
return err
}
usage.Kernel *= 1000
}
if val, found := values["system_usec"]; found {
- usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
+ usage.Kernel, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
if err != nil {
return err
}
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/network/subnet.go b/pkg/network/subnet.go
index 82ab9a8c8..90f0cdfce 100644
--- a/pkg/network/subnet.go
+++ b/pkg/network/subnet.go
@@ -18,7 +18,7 @@ func incByte(subnet *net.IPNet, idx int, shift uint) error {
subnet.IP[idx] = 0
return incByte(subnet, idx-1, 0)
}
- subnet.IP[idx] += (1 << shift)
+ subnet.IP[idx] += 1 << shift
return nil
}
@@ -58,7 +58,7 @@ func LastIPInSubnet(addr *net.IPNet) (net.IP, error) { //nolint:interfacer
}
hostStart := ones / 8
// Handle the first host byte
- cidr.IP[hostStart] |= (0xff & cidr.Mask[hostStart])
+ cidr.IP[hostStart] |= 0xff & cidr.Mask[hostStart]
// Fill the rest with ones
for i := hostStart; i < len(cidr.IP); i++ {
cidr.IP[i] = 0xff
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/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go
index e6e92a7cc..a1527752a 100644
--- a/pkg/spec/config_linux_cgo.go
+++ b/pkg/spec/config_linux_cgo.go
@@ -5,9 +5,9 @@ package createconfig
import (
"io/ioutil"
- "github.com/docker/docker/profiles/seccomp"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
+ seccomp "github.com/seccomp/containers-golang"
)
func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index da5c14948..33e9ec076 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -5,6 +5,8 @@ import (
"strings"
"github.com/containers/libpod/libpod"
+ libpodconfig "github.com/containers/libpod/libpod/config"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/sysinfo"
@@ -300,7 +302,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
blockAccessToKernelFilesystems(config, &g)
- var runtimeConfig *libpod.RuntimeConfig
+ var runtimeConfig *libpodconfig.Config
if runtime != nil {
runtimeConfig, err = runtime.GetConfig()
@@ -321,7 +323,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if err != nil {
return nil, err
}
- if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ if (!cgroup2 || (runtimeConfig != nil && runtimeConfig.CgroupManager != define.SystemdCgroupsManager)) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
setPidLimit = false
}
}
@@ -417,7 +419,7 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
configSpec.Linux.Resources = &spec.LinuxResources{}
}
- canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == libpod.SystemdCgroupsManager)
+ canUseResources := cgroup2 && runtimeConfig != nil && (runtimeConfig.CgroupManager == define.SystemdCgroupsManager)
if addedResources && !canUseResources {
return nil, errors.New("invalid configuration, cannot specify resource limits without cgroups v2 and --cgroup-manager=systemd")
@@ -629,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/util/utils.go b/pkg/util/utils.go
index 71f3e26dc..633d8a124 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -3,6 +3,7 @@ package util
import (
"fmt"
"os"
+ "os/user"
"path/filepath"
"regexp"
"strings"
@@ -440,3 +441,16 @@ func ExitCode(err error) int {
return 126
}
+
+// HomeDir returns the home directory for the current user.
+func HomeDir() (string, error) {
+ home := os.Getenv("HOME")
+ if home == "" {
+ usr, err := user.LookupId(fmt.Sprintf("%d", rootless.GetRootlessUID()))
+ if err != nil {
+ return "", errors.Wrapf(err, "unable to resolve HOME directory")
+ }
+ home = usr.HomeDir
+ }
+ return home, nil
+}
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index 37adbbf55..5beca3c6f 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -32,7 +32,7 @@ func setupStreams(call iopodman.VarlinkCall) (*bufio.Reader, *bufio.Writer, *io.
streams := libpod.AttachStreams{
OutputStream: stdoutWriter,
- InputStream: pr,
+ InputStream: bufio.NewReader(pr),
// Runc eats the error stream
ErrorStream: stdoutWriter,
AttachInput: true,
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index b471ee2cf..94726bbbd 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -739,7 +739,7 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string,
options := logs.LogOptions{
Follow: follow,
Since: sinceTime,
- Tail: uint64(tail),
+ Tail: tail,
Timestamps: timestamps,
}
@@ -747,7 +747,11 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string,
if len(names) > 1 {
options.Multi = true
}
- logChannel := make(chan *logs.LogLine, int(tail)*len(names)+1)
+ tailLen := int(tail)
+ if tailLen < 0 {
+ tailLen = 0
+ }
+ logChannel := make(chan *logs.LogLine, tailLen*len(names)+1)
containers, err := shortcuts.GetContainersByContext(false, latest, names, i.Runtime)
if err != nil {
return call.ReplyErrorOccurred(err.Error())