diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/pods.go | 2 | ||||
-rw-r--r-- | pkg/apparmor/apparmor_linux.go | 13 | ||||
-rw-r--r-- | pkg/apparmor/apparmor_linux_test.go | 17 | ||||
-rw-r--r-- | pkg/apparmor/apparmor_unsupported.go | 5 | ||||
-rw-r--r-- | pkg/cgroups/cgroups.go | 8 | ||||
-rw-r--r-- | pkg/spec/spec.go | 106 | ||||
-rw-r--r-- | pkg/spec/spec_linux.go | 42 | ||||
-rw-r--r-- | pkg/spec/spec_unsupported.go | 7 | ||||
-rw-r--r-- | pkg/spec/storage.go | 7 | ||||
-rw-r--r-- | pkg/util/utils_linux.go | 43 | ||||
-rw-r--r-- | pkg/util/utils_unsupported.go | 12 | ||||
-rw-r--r-- | pkg/varlinkapi/containers.go | 24 | ||||
-rw-r--r-- | pkg/varlinkapi/transfers.go | 5 |
13 files changed, 186 insertions, 105 deletions
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go index b45b02d09..2ca4f228f 100644 --- a/pkg/adapter/pods.go +++ b/pkg/adapter/pods.go @@ -676,7 +676,7 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container if imageData != nil && imageData.Config != nil { containerConfig.Command = append(containerConfig.Command, imageData.Config.Entrypoint...) } - if len(containerConfig.Command) != 0 { + if len(containerYAML.Command) != 0 { containerConfig.Command = append(containerConfig.Command, containerYAML.Command...) } else if imageData != nil && imageData.Config != nil { containerConfig.Command = append(containerConfig.Command, imageData.Config.Cmd...) diff --git a/pkg/apparmor/apparmor_linux.go b/pkg/apparmor/apparmor_linux.go index 0d01f41e9..479600408 100644 --- a/pkg/apparmor/apparmor_linux.go +++ b/pkg/apparmor/apparmor_linux.go @@ -4,6 +4,7 @@ package apparmor import ( "bufio" + "bytes" "fmt" "io" "os" @@ -104,6 +105,18 @@ func InstallDefault(name string) error { return cmd.Wait() } +// DefaultContent returns the default profile content as byte slice. The +// profile is named as the provided `name`. The function errors if the profile +// generation fails. +func DefaultContent(name string) ([]byte, error) { + p := profileData{Name: name} + var bytes bytes.Buffer + if err := p.generateDefault(&bytes); err != nil { + return nil, err + } + return bytes.Bytes(), nil +} + // IsLoaded checks if a profile with the given name has been loaded into the // kernel. func IsLoaded(name string) (bool, error) { diff --git a/pkg/apparmor/apparmor_linux_test.go b/pkg/apparmor/apparmor_linux_test.go index ac3260723..e94293d87 100644 --- a/pkg/apparmor/apparmor_linux_test.go +++ b/pkg/apparmor/apparmor_linux_test.go @@ -78,10 +78,12 @@ Copyright 2009-2012 Canonical Ltd. } } -func TestInstallDefault(t *testing.T) { - profile := "libpod-default-testing" - aapath := "/sys/kernel/security/apparmor/" +const ( + aapath = "/sys/kernel/security/apparmor/" + profile = "libpod-default-testing" +) +func TestInstallDefault(t *testing.T) { if _, err := os.Stat(aapath); err != nil { t.Skip("AppArmor isn't available in this environment") } @@ -127,3 +129,12 @@ func TestInstallDefault(t *testing.T) { } checkLoaded(false) } + +func TestDefaultContent(t *testing.T) { + if _, err := os.Stat(aapath); err != nil { + t.Skip("AppArmor isn't available in this environment") + } + if err := DefaultContent(profile); err != nil { + t.Fatalf("Couldn't retrieve default AppArmor profile content '%s': %v", profile, err) + } +} diff --git a/pkg/apparmor/apparmor_unsupported.go b/pkg/apparmor/apparmor_unsupported.go index b2b4de5f5..13469f1b6 100644 --- a/pkg/apparmor/apparmor_unsupported.go +++ b/pkg/apparmor/apparmor_unsupported.go @@ -24,3 +24,8 @@ func CheckProfileAndLoadDefault(name string) (string, error) { } return "", ErrApparmorUnsupported } + +// DefaultContent dummy. +func DefaultContent(name string) ([]byte, error) { + return nil, nil +} diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go index 081db772f..fda19bff8 100644 --- a/pkg/cgroups/cgroups.go +++ b/pkg/cgroups/cgroups.go @@ -187,8 +187,12 @@ func createCgroupv2Path(path string) (Err error) { }() } } - if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { - return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + // We enable the controllers for all the path components except the last one. It is not allowed to add + // PIDs if there are already enabled controllers. + if i < len(elements[3:])-1 { + if err := ioutil.WriteFile(filepath.Join(current, "cgroup.subtree_control"), resByte, 0755); err != nil { + return errors.Wrapf(err, "write %s", filepath.Join(current, "cgroup.subtree_control")) + } } } return nil diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index d44beb3e4..41054633f 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -20,12 +20,6 @@ import ( const cpuPeriod = 100000 -type systemUlimit struct { - name string - max uint64 - cur uint64 -} - func getAvailableGids() (int64, error) { idMap, err := user.ParseIDMapFile("/proc/self/gid_map") if err != nil { @@ -86,23 +80,41 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM g.AddLinuxMaskedPaths("/sys/kernel") } } + gid5Available := true if isRootless { nGids, err := getAvailableGids() if err != nil { return nil, err } - if nGids < 5 { - // If we have no GID mappings, the gid=5 default option would fail, so drop it. - g.RemoveMount("/dev/pts") - devPts := spec.Mount{ - Destination: "/dev/pts", - Type: "devpts", - Source: "devpts", - Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + gid5Available = nGids >= 5 + } + // When using a different user namespace, check that the GID 5 is mapped inside + // the container. + if gid5Available && len(config.IDMappings.GIDMap) > 0 { + mappingFound := false + for _, r := range config.IDMappings.GIDMap { + if r.ContainerID <= 5 && 5 < r.ContainerID+r.Size { + mappingFound = true + break } - g.AddMount(devPts) } + if !mappingFound { + gid5Available = false + } + + } + if !gid5Available { + // If we have no GID mappings, the gid=5 default option would fail, so drop it. + g.RemoveMount("/dev/pts") + devPts := spec.Mount{ + Destination: "/dev/pts", + Type: "devpts", + Source: "devpts", + Options: []string{"rprivate", "nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + } + g.AddMount(devPts) } + if inUserNS && config.IpcMode.IsHost() { g.RemoveMount("/dev/mqueue") devMqueue := spec.Mount{ @@ -406,6 +418,62 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM } } + // Add annotations + if configSpec.Annotations == nil { + configSpec.Annotations = make(map[string]string) + } + + if config.CidFile != "" { + configSpec.Annotations[libpod.InspectAnnotationCIDFile] = config.CidFile + } + + if config.Rm { + configSpec.Annotations[libpod.InspectAnnotationAutoremove] = libpod.InspectResponseTrue + } else { + configSpec.Annotations[libpod.InspectAnnotationAutoremove] = libpod.InspectResponseFalse + } + + if len(config.VolumesFrom) > 0 { + configSpec.Annotations[libpod.InspectAnnotationVolumesFrom] = strings.Join(config.VolumesFrom, ",") + } + + if config.Privileged { + configSpec.Annotations[libpod.InspectAnnotationPrivileged] = libpod.InspectResponseTrue + } else { + configSpec.Annotations[libpod.InspectAnnotationPrivileged] = libpod.InspectResponseFalse + } + + if config.PublishAll { + configSpec.Annotations[libpod.InspectAnnotationPublishAll] = libpod.InspectResponseTrue + } else { + configSpec.Annotations[libpod.InspectAnnotationPublishAll] = libpod.InspectResponseFalse + } + + if config.Init { + configSpec.Annotations[libpod.InspectAnnotationInit] = libpod.InspectResponseTrue + } else { + configSpec.Annotations[libpod.InspectAnnotationInit] = libpod.InspectResponseFalse + } + + for _, opt := range config.SecurityOpts { + // Split on both : and = + splitOpt := strings.Split(opt, "=") + if len(splitOpt) == 1 { + splitOpt = strings.Split(opt, ":") + } + if len(splitOpt) < 2 { + continue + } + switch splitOpt[0] { + case "label": + configSpec.Annotations[libpod.InspectAnnotationLabel] = splitOpt[1] + case "seccomp": + configSpec.Annotations[libpod.InspectAnnotationSeccomp] = splitOpt[1] + case "apparmor": + configSpec.Annotations[libpod.InspectAnnotationApparmor] = splitOpt[1] + } + } + return configSpec, nil } @@ -567,13 +635,7 @@ func addRlimits(config *CreateConfig, g *generate.Generator) error { if len(config.Resources.Ulimit) != 1 { return errors.New("ulimit can use host only once") } - hostLimits, err := getHostRlimits() - if err != nil { - return err - } - for _, i := range hostLimits { - g.AddProcessRlimits(i.name, i.max, i.cur) - } + g.Config.Process.Rlimits = nil break } diff --git a/pkg/spec/spec_linux.go b/pkg/spec/spec_linux.go deleted file mode 100644 index fcdfc5c4e..000000000 --- a/pkg/spec/spec_linux.go +++ /dev/null @@ -1,42 +0,0 @@ -//+build linux - -package createconfig - -import ( - "syscall" - - "github.com/pkg/errors" -) - -type systemRlimit struct { - name string - value int -} - -var systemLimits = []systemRlimit{ - {"RLIMIT_AS", syscall.RLIMIT_AS}, - {"RLIMIT_CORE", syscall.RLIMIT_CORE}, - {"RLIMIT_CPU", syscall.RLIMIT_CPU}, - {"RLIMIT_DATA", syscall.RLIMIT_DATA}, - {"RLIMIT_FSIZE", syscall.RLIMIT_FSIZE}, - {"RLIMIT_NOFILE", syscall.RLIMIT_NOFILE}, - {"RLIMIT_STACK", syscall.RLIMIT_STACK}, -} - -func getHostRlimits() ([]systemUlimit, error) { - ret := []systemUlimit{} - for _, i := range systemLimits { - var l syscall.Rlimit - if err := syscall.Getrlimit(i.value, &l); err != nil { - return nil, errors.Wrapf(err, "cannot read limits for %s", i.name) - } - s := systemUlimit{ - name: i.name, - max: l.Max, - cur: l.Cur, - } - ret = append(ret, s) - } - return ret, nil - -} diff --git a/pkg/spec/spec_unsupported.go b/pkg/spec/spec_unsupported.go deleted file mode 100644 index 0f6a9acdc..000000000 --- a/pkg/spec/spec_unsupported.go +++ /dev/null @@ -1,7 +0,0 @@ -//+build !linux - -package createconfig - -func getHostRlimits() ([]systemUlimit, error) { - return nil, nil -} diff --git a/pkg/spec/storage.go b/pkg/spec/storage.go index ed767f5ba..88f1f6dc1 100644 --- a/pkg/spec/storage.go +++ b/pkg/spec/storage.go @@ -211,6 +211,13 @@ func (config *CreateConfig) parseVolumes(runtime *libpod.Runtime) ([]spec.Mount, } mount.Options = opts } + if mount.Type == TypeBind { + absSrc, err := filepath.Abs(mount.Source) + if err != nil { + return nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source) + } + mount.Source = absSrc + } finalMounts = append(finalMounts, mount) } finalVolumes := make([]*libpod.ContainerNamedVolume, 0, len(baseVolumes)) diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go index 47fa1031f..318bd2b1b 100644 --- a/pkg/util/utils_linux.go +++ b/pkg/util/utils_linux.go @@ -1,7 +1,14 @@ package util import ( + "fmt" + "os" + "path/filepath" + "syscall" + "github.com/containers/psgo" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // GetContainerPidInformationDescriptors returns a string slice of all supported @@ -9,3 +16,39 @@ import ( func GetContainerPidInformationDescriptors() ([]string, error) { return psgo.ListDescriptors(), nil } + +// FindDeviceNodes parses /dev/ into a set of major:minor -> path, where +// [major:minor] is the device's major and minor numbers formatted as, for +// example, 2:0 and path is the path to the device node. +// Symlinks to nodes are ignored. +func FindDeviceNodes() (map[string]string, error) { + nodes := make(map[string]string) + err := filepath.Walk("/dev", func(path string, info os.FileInfo, err error) error { + if err != nil { + logrus.Warnf("Error descending into path %s: %v", path, err) + return filepath.SkipDir + } + + // If we aren't a device node, do nothing. + if info.Mode()&(os.ModeDevice|os.ModeCharDevice) == 0 { + return nil + } + + // We are a device node. Get major/minor. + sysstat, ok := info.Sys().(*syscall.Stat_t) + if !ok { + return errors.Errorf("Could not convert stat output for use") + } + major := uint64(sysstat.Rdev / 256) + minor := uint64(sysstat.Rdev % 256) + + nodes[fmt.Sprintf("%d:%d", major, minor)] = path + + return nil + }) + if err != nil { + return nil, err + } + + return nodes, nil +} diff --git a/pkg/util/utils_unsupported.go b/pkg/util/utils_unsupported.go new file mode 100644 index 000000000..62805d7c8 --- /dev/null +++ b/pkg/util/utils_unsupported.go @@ -0,0 +1,12 @@ +// +build darwin windows + +package util + +import ( + "github.com/pkg/errors" +) + +// FindDeviceNodes is not implemented anywhere except Linux. +func FindDeviceNodes() (map[string]string, error) { + return nil, errors.Errorf("not supported on non-Linux OSes") +} diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index 6855a7231..700e02b0c 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -19,7 +19,6 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/adapter/shortcuts" - cc "github.com/containers/libpod/pkg/spec" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" ) @@ -170,16 +169,7 @@ func (i *LibpodAPI) InspectContainer(call iopodman.VarlinkCall, name string) err if err != nil { return call.ReplyContainerNotFound(name, err.Error()) } - inspectInfo, err := ctr.Inspect(true) - if err != nil { - return call.ReplyErrorOccurred(err.Error()) - } - artifact, err := getArtifact(ctr) - if err != nil { - return call.ReplyErrorOccurred(err.Error()) - } - - data, err := shared.GetCtrInspectInfo(ctr.Config(), inspectInfo, artifact) + data, err := ctr.Inspect(true) if err != nil { return call.ReplyErrorOccurred(err.Error()) } @@ -587,18 +577,6 @@ func (i *LibpodAPI) ContainerRestore(call iopodman.VarlinkCall, name string, kee return call.ReplyContainerRestore(ctr.ID()) } -func getArtifact(ctr *libpod.Container) (*cc.CreateConfig, error) { - var createArtifact cc.CreateConfig - artifact, err := ctr.GetArtifact("create-config") - if err != nil { - return nil, err - } - if err := json.Unmarshal(artifact, &createArtifact); err != nil { - return nil, err - } - return &createArtifact, nil -} - // ContainerConfig returns just the container.config struct func (i *LibpodAPI) ContainerConfig(call iopodman.VarlinkCall, name string) error { ctr, err := i.Runtime.LookupContainer(name) diff --git a/pkg/varlinkapi/transfers.go b/pkg/varlinkapi/transfers.go index 24a91a86f..31d26c3aa 100644 --- a/pkg/varlinkapi/transfers.go +++ b/pkg/varlinkapi/transfers.go @@ -26,11 +26,6 @@ func (i *LibpodAPI) SendFile(call iopodman.VarlinkCall, ftype string, length int defer outputFile.Close() if err = call.ReplySendFile(outputFile.Name()); err != nil { - return call.ReplyErrorOccurred(err.Error()) - } - - // FIXME return parameter - if err = call.ReplySendFile("FIXME_file_handle"); err != nil { // If an error occurs while sending the reply, return the error return err } |