2017-04-11 22:27:05 +08:00
|
|
|
package buildah
|
|
|
|
|
|
|
|
import (
|
2019-05-30 12:22:53 +08:00
|
|
|
"archive/tar"
|
2018-03-17 05:19:29 +08:00
|
|
|
"io"
|
2019-06-08 06:02:50 +08:00
|
|
|
"io/ioutil"
|
2018-04-24 03:55:46 +08:00
|
|
|
"os"
|
2019-05-30 12:22:53 +08:00
|
|
|
"path/filepath"
|
2018-04-24 03:55:46 +08:00
|
|
|
|
2019-05-30 12:22:53 +08:00
|
|
|
"github.com/containers/buildah/util"
|
2018-06-02 07:33:32 +08:00
|
|
|
"github.com/containers/image/docker/reference"
|
2018-08-03 04:55:17 +08:00
|
|
|
"github.com/containers/image/pkg/sysregistriesv2"
|
2018-06-02 07:33:32 +08:00
|
|
|
"github.com/containers/image/types"
|
2018-09-27 10:23:37 +08:00
|
|
|
"github.com/containers/storage"
|
2018-03-17 05:19:29 +08:00
|
|
|
"github.com/containers/storage/pkg/archive"
|
2017-10-10 03:05:56 +08:00
|
|
|
"github.com/containers/storage/pkg/chrootarchive"
|
2018-03-08 07:11:43 +08:00
|
|
|
"github.com/containers/storage/pkg/idtools"
|
2019-05-30 12:22:53 +08:00
|
|
|
"github.com/containers/storage/pkg/pools"
|
2017-04-11 22:27:05 +08:00
|
|
|
"github.com/containers/storage/pkg/reexec"
|
2019-05-30 12:22:53 +08:00
|
|
|
"github.com/containers/storage/pkg/system"
|
2019-07-18 16:42:09 +08:00
|
|
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
2018-03-08 07:11:43 +08:00
|
|
|
rspec "github.com/opencontainers/runtime-spec/specs-go"
|
2018-09-27 10:23:37 +08:00
|
|
|
"github.com/opencontainers/selinux/go-selinux"
|
|
|
|
"github.com/opencontainers/selinux/go-selinux/label"
|
2018-04-24 03:55:46 +08:00
|
|
|
"github.com/pkg/errors"
|
2018-10-03 02:48:11 +08:00
|
|
|
"github.com/sirupsen/logrus"
|
2017-04-11 22:27:05 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
// InitReexec is a wrapper for reexec.Init(). It should be called at
|
|
|
|
// the start of main(), and if it returns true, main() should return
|
|
|
|
// immediately.
|
|
|
|
func InitReexec() bool {
|
|
|
|
return reexec.Init()
|
|
|
|
}
|
Maintain multiple working container configs
Maintain the container configuration in multiple formats in the Buildah
object, initializing one based on the other, depending on which format
the source image used for its configuration.
Replace directly manipulated fields in the Buildah object (Annotations,
CreatedBy, OS, Architecture, Maintainer, User, Workdir, Env, Cmd,
Entrypoint, Expose, Labels, and Volumes) with accessor functions which
update both configurations and which read from whichever one we consider
to be authoritative. Drop Args because we weren't using them.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
Closes: #102
Approved by: rhatdan
2017-05-16 23:08:52 +08:00
|
|
|
|
|
|
|
func copyStringStringMap(m map[string]string) map[string]string {
|
|
|
|
n := map[string]string{}
|
|
|
|
for k, v := range m {
|
|
|
|
n[k] = v
|
|
|
|
}
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
func copyStringSlice(s []string) []string {
|
|
|
|
t := make([]string, len(s))
|
|
|
|
copy(t, s)
|
|
|
|
return t
|
2018-04-14 06:20:25 +08:00
|
|
|
}
|
|
|
|
|
2019-01-19 04:39:58 +08:00
|
|
|
func copyHistory(history []v1.History) []v1.History {
|
|
|
|
if len(history) == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
h := make([]v1.History, 0, len(history))
|
|
|
|
for _, entry := range history {
|
|
|
|
created := entry.Created
|
|
|
|
if created != nil {
|
|
|
|
timestamp := *created
|
|
|
|
created = ×tamp
|
|
|
|
}
|
|
|
|
h = append(h, v1.History{
|
|
|
|
Created: created,
|
|
|
|
CreatedBy: entry.CreatedBy,
|
|
|
|
Author: entry.Author,
|
|
|
|
Comment: entry.Comment,
|
|
|
|
EmptyLayer: entry.EmptyLayer,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return h
|
|
|
|
}
|
|
|
|
|
2018-03-08 07:11:43 +08:00
|
|
|
func convertStorageIDMaps(UIDMap, GIDMap []idtools.IDMap) ([]rspec.LinuxIDMapping, []rspec.LinuxIDMapping) {
|
|
|
|
uidmap := make([]rspec.LinuxIDMapping, 0, len(UIDMap))
|
|
|
|
gidmap := make([]rspec.LinuxIDMapping, 0, len(GIDMap))
|
|
|
|
for _, m := range UIDMap {
|
|
|
|
uidmap = append(uidmap, rspec.LinuxIDMapping{
|
|
|
|
HostID: uint32(m.HostID),
|
|
|
|
ContainerID: uint32(m.ContainerID),
|
|
|
|
Size: uint32(m.Size),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
for _, m := range GIDMap {
|
|
|
|
gidmap = append(gidmap, rspec.LinuxIDMapping{
|
|
|
|
HostID: uint32(m.HostID),
|
|
|
|
ContainerID: uint32(m.ContainerID),
|
|
|
|
Size: uint32(m.Size),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return uidmap, gidmap
|
|
|
|
}
|
2018-04-24 03:55:46 +08:00
|
|
|
|
2018-03-13 01:53:12 +08:00
|
|
|
func convertRuntimeIDMaps(UIDMap, GIDMap []rspec.LinuxIDMapping) ([]idtools.IDMap, []idtools.IDMap) {
|
|
|
|
uidmap := make([]idtools.IDMap, 0, len(UIDMap))
|
|
|
|
gidmap := make([]idtools.IDMap, 0, len(GIDMap))
|
|
|
|
for _, m := range UIDMap {
|
|
|
|
uidmap = append(uidmap, idtools.IDMap{
|
|
|
|
HostID: int(m.HostID),
|
|
|
|
ContainerID: int(m.ContainerID),
|
|
|
|
Size: int(m.Size),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
for _, m := range GIDMap {
|
|
|
|
gidmap = append(gidmap, idtools.IDMap{
|
|
|
|
HostID: int(m.HostID),
|
|
|
|
ContainerID: int(m.ContainerID),
|
|
|
|
Size: int(m.Size),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return uidmap, gidmap
|
|
|
|
}
|
|
|
|
|
|
|
|
// copyFileWithTar returns a function which copies a single file from outside
|
2019-05-30 12:22:53 +08:00
|
|
|
// of any container, or another container, into our working container, mapping
|
|
|
|
// read permissions using the passed-in ID maps, writing using the container's
|
|
|
|
// ID mappings, possibly overridden using the passed-in chownOpts
|
2019-06-08 06:02:50 +08:00
|
|
|
func (b *Builder) copyFileWithTar(tarIDMappingOptions *IDMappingOptions, chownOpts *idtools.IDPair, hasher io.Writer, dryRun bool) func(src, dest string) error {
|
2019-05-30 12:22:53 +08:00
|
|
|
if tarIDMappingOptions == nil {
|
|
|
|
tarIDMappingOptions = &IDMappingOptions{
|
|
|
|
HostUIDMapping: true,
|
|
|
|
HostGIDMapping: true,
|
|
|
|
}
|
|
|
|
}
|
2019-06-08 05:58:04 +08:00
|
|
|
|
|
|
|
var hardlinkChecker util.HardlinkChecker
|
2019-05-30 12:22:53 +08:00
|
|
|
return func(src, dest string) error {
|
2019-06-08 03:59:39 +08:00
|
|
|
var f *os.File
|
|
|
|
|
2019-05-30 12:22:53 +08:00
|
|
|
logrus.Debugf("copyFileWithTar(%s, %s)", src, dest)
|
2019-06-08 03:59:39 +08:00
|
|
|
fi, err := os.Lstat(src)
|
2019-05-30 12:22:53 +08:00
|
|
|
if err != nil {
|
2019-06-08 03:59:39 +08:00
|
|
|
return errors.Wrapf(err, "error reading attributes of %q", src)
|
2019-05-30 12:22:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
sysfi, err := system.Lstat(src)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading attributes of %q", src)
|
|
|
|
}
|
|
|
|
|
|
|
|
hostUID := sysfi.UID()
|
|
|
|
hostGID := sysfi.GID()
|
|
|
|
containerUID, containerGID, err := util.GetContainerIDs(tarIDMappingOptions.UIDMap, tarIDMappingOptions.GIDMap, hostUID, hostGID)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error mapping owner IDs of %q: %d/%d", src, hostUID, hostGID)
|
|
|
|
}
|
|
|
|
|
|
|
|
hdr, err := tar.FileInfoHeader(fi, filepath.Base(src))
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error generating tar header for: %q", src)
|
|
|
|
}
|
2019-06-08 05:58:04 +08:00
|
|
|
chrootedDest, err := filepath.Rel(b.MountPoint, dest)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error generating relative-to-chroot target name for %q", dest)
|
|
|
|
}
|
|
|
|
hdr.Name = chrootedDest
|
2019-05-30 12:22:53 +08:00
|
|
|
hdr.Uid = int(containerUID)
|
|
|
|
hdr.Gid = int(containerGID)
|
|
|
|
|
2019-06-08 03:59:39 +08:00
|
|
|
if fi.Mode().IsRegular() && hdr.Typeflag == tar.TypeReg {
|
2019-06-08 05:58:04 +08:00
|
|
|
if linkname := hardlinkChecker.Check(fi); linkname != "" {
|
|
|
|
hdr.Typeflag = tar.TypeLink
|
|
|
|
hdr.Linkname = linkname
|
|
|
|
} else {
|
|
|
|
hardlinkChecker.Add(fi, chrootedDest)
|
|
|
|
f, err = os.Open(src)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error opening %q to copy its contents", src)
|
|
|
|
}
|
|
|
|
defer func() {
|
2019-06-08 03:59:39 +08:00
|
|
|
if err := f.Close(); err != nil {
|
2019-06-08 05:58:04 +08:00
|
|
|
logrus.Debugf("error closing %s: %v", fi.Name(), err)
|
2019-06-08 03:59:39 +08:00
|
|
|
}
|
2019-06-08 05:58:04 +08:00
|
|
|
}()
|
|
|
|
}
|
2019-06-08 03:59:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if fi.Mode()&os.ModeSymlink == os.ModeSymlink && hdr.Typeflag == tar.TypeSymlink {
|
|
|
|
hdr.Typeflag = tar.TypeSymlink
|
|
|
|
linkName, err := os.Readlink(src)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error reading destination from symlink %q", src)
|
|
|
|
}
|
|
|
|
hdr.Linkname = linkName
|
|
|
|
}
|
|
|
|
|
2019-05-30 12:22:53 +08:00
|
|
|
pipeReader, pipeWriter := io.Pipe()
|
|
|
|
writer := tar.NewWriter(pipeWriter)
|
|
|
|
var copyErr error
|
|
|
|
go func(srcFile *os.File) {
|
|
|
|
err := writer.WriteHeader(hdr)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Debugf("error writing header for %s: %v", srcFile.Name(), err)
|
|
|
|
copyErr = err
|
|
|
|
}
|
2019-06-08 03:59:39 +08:00
|
|
|
if srcFile != nil {
|
|
|
|
n, err := pools.Copy(writer, srcFile)
|
|
|
|
if n != hdr.Size {
|
|
|
|
logrus.Debugf("expected to write %d bytes for %s, wrote %d instead", hdr.Size, srcFile.Name(), n)
|
|
|
|
}
|
|
|
|
if err != nil {
|
2019-06-08 05:58:04 +08:00
|
|
|
logrus.Debugf("error copying contents of %s: %v", fi.Name(), err)
|
2019-06-08 03:59:39 +08:00
|
|
|
copyErr = err
|
|
|
|
}
|
2019-05-30 12:22:53 +08:00
|
|
|
}
|
|
|
|
if err = writer.Close(); err != nil {
|
2019-06-08 05:58:04 +08:00
|
|
|
logrus.Debugf("error closing write pipe for %s: %v", hdr.Name, err)
|
2019-05-30 12:22:53 +08:00
|
|
|
}
|
|
|
|
pipeWriter.Close()
|
|
|
|
pipeWriter = nil
|
|
|
|
}(f)
|
|
|
|
|
2019-06-08 06:02:50 +08:00
|
|
|
untar := b.untar(chownOpts, hasher, dryRun)
|
2019-06-08 05:58:04 +08:00
|
|
|
err = untar(pipeReader, b.MountPoint)
|
2019-05-30 12:22:53 +08:00
|
|
|
if err == nil {
|
|
|
|
err = copyErr
|
|
|
|
}
|
|
|
|
f = nil
|
|
|
|
if pipeWriter != nil {
|
|
|
|
pipeWriter.Close()
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
2018-03-13 01:53:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// copyWithTar returns a function which copies a directory tree from outside of
|
2019-05-30 12:22:53 +08:00
|
|
|
// our container or from another container, into our working container, mapping
|
|
|
|
// permissions at read-time using the container's ID maps, with ownership at
|
|
|
|
// write-time possibly overridden using the passed-in chownOpts
|
2019-06-08 06:02:50 +08:00
|
|
|
func (b *Builder) copyWithTar(tarIDMappingOptions *IDMappingOptions, chownOpts *idtools.IDPair, hasher io.Writer, dryRun bool) func(src, dest string) error {
|
2019-05-30 12:22:53 +08:00
|
|
|
tar := b.tarPath(tarIDMappingOptions)
|
2019-06-08 06:02:50 +08:00
|
|
|
untar := b.untar(chownOpts, hasher, dryRun)
|
2019-05-30 12:22:53 +08:00
|
|
|
return func(src, dest string) error {
|
|
|
|
rc, err := tar(src)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error archiving %q for copy", src)
|
|
|
|
}
|
|
|
|
return untar(rc, dest)
|
|
|
|
}
|
2018-03-13 01:53:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// untarPath returns a function which extracts an archive in a specified
|
|
|
|
// location into our working container, mapping permissions using the
|
|
|
|
// container's ID maps, possibly overridden using the passed-in chownOpts
|
2019-06-08 06:02:50 +08:00
|
|
|
func (b *Builder) untarPath(chownOpts *idtools.IDPair, hasher io.Writer, dryRun bool) func(src, dest string) error {
|
2018-03-13 01:53:12 +08:00
|
|
|
convertedUIDMap, convertedGIDMap := convertRuntimeIDMaps(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap)
|
2019-06-08 06:02:50 +08:00
|
|
|
if dryRun {
|
|
|
|
return func(src, dest string) error {
|
|
|
|
if hasher == nil {
|
|
|
|
hasher = ioutil.Discard
|
|
|
|
}
|
|
|
|
f, err := os.Open(src)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "error opening %q", src)
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
_, err = io.Copy(hasher, f)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2019-02-01 23:29:45 +08:00
|
|
|
return chrootarchive.UntarPathAndChown(chownOpts, hasher, convertedUIDMap, convertedGIDMap)
|
2018-03-13 01:53:12 +08:00
|
|
|
}
|
|
|
|
|
2019-05-30 12:22:53 +08:00
|
|
|
// tarPath returns a function which creates an archive of a specified location,
|
|
|
|
// which is often somewhere in the container's filesystem, mapping permissions
|
|
|
|
// using the container's ID maps, or the passed-in maps if specified
|
|
|
|
func (b *Builder) tarPath(idMappingOptions *IDMappingOptions) func(path string) (io.ReadCloser, error) {
|
|
|
|
var uidmap, gidmap []idtools.IDMap
|
|
|
|
if idMappingOptions == nil {
|
|
|
|
idMappingOptions = &IDMappingOptions{
|
|
|
|
HostUIDMapping: true,
|
|
|
|
HostGIDMapping: true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
convertedUIDMap, convertedGIDMap := convertRuntimeIDMaps(idMappingOptions.UIDMap, idMappingOptions.GIDMap)
|
|
|
|
tarMappings := idtools.NewIDMappingsFromMaps(convertedUIDMap, convertedGIDMap)
|
|
|
|
uidmap = tarMappings.UIDs()
|
|
|
|
gidmap = tarMappings.GIDs()
|
|
|
|
options := &archive.TarOptions{
|
|
|
|
Compression: archive.Uncompressed,
|
|
|
|
UIDMaps: uidmap,
|
|
|
|
GIDMaps: gidmap,
|
|
|
|
}
|
|
|
|
return func(path string) (io.ReadCloser, error) {
|
|
|
|
return archive.TarWithOptions(path, options)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// untar returns a function which extracts an archive stream to a specified
|
2018-03-17 05:19:29 +08:00
|
|
|
// location in the container's filesystem, mapping permissions using the
|
2019-05-30 12:22:53 +08:00
|
|
|
// container's ID maps, possibly overridden using the passed-in chownOpts
|
2019-06-08 06:02:50 +08:00
|
|
|
func (b *Builder) untar(chownOpts *idtools.IDPair, hasher io.Writer, dryRun bool) func(tarArchive io.ReadCloser, dest string) error {
|
2018-03-17 05:19:29 +08:00
|
|
|
convertedUIDMap, convertedGIDMap := convertRuntimeIDMaps(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap)
|
2019-05-30 12:22:53 +08:00
|
|
|
untarMappings := idtools.NewIDMappingsFromMaps(convertedUIDMap, convertedGIDMap)
|
|
|
|
options := &archive.TarOptions{
|
|
|
|
UIDMaps: untarMappings.UIDs(),
|
|
|
|
GIDMaps: untarMappings.GIDs(),
|
|
|
|
ChownOpts: chownOpts,
|
|
|
|
}
|
|
|
|
untar := chrootarchive.Untar
|
2019-06-08 06:02:50 +08:00
|
|
|
if dryRun {
|
|
|
|
untar = func(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
|
|
|
|
if _, err := io.Copy(ioutil.Discard, tarArchive); err != nil {
|
|
|
|
return errors.Wrapf(err, "error digesting tar stream")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
2019-05-30 12:22:53 +08:00
|
|
|
if hasher != nil {
|
|
|
|
originalUntar := untar
|
|
|
|
untar = func(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
|
|
|
|
return originalUntar(io.TeeReader(tarArchive, hasher), dest, options)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return func(tarArchive io.ReadCloser, dest string) error {
|
|
|
|
err := untar(tarArchive, dest, options)
|
|
|
|
if err2 := tarArchive.Close(); err2 != nil {
|
|
|
|
if err == nil {
|
|
|
|
err = err2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
2018-03-17 05:19:29 +08:00
|
|
|
}
|
|
|
|
|
2018-10-03 01:48:45 +08:00
|
|
|
// isRegistryBlocked checks if the named registry is marked as blocked
|
|
|
|
func isRegistryBlocked(registry string, sc *types.SystemContext) (bool, error) {
|
2018-12-04 02:02:47 +08:00
|
|
|
reginfo, err := sysregistriesv2.FindRegistry(sc, registry)
|
2018-10-03 01:48:45 +08:00
|
|
|
if err != nil {
|
2019-08-02 17:30:22 +08:00
|
|
|
return false, errors.Wrapf(err, "unable to parse the registries configuration (%s)", sysregistriesv2.ConfigPath(sc))
|
2018-10-03 01:48:45 +08:00
|
|
|
}
|
2018-12-04 02:02:47 +08:00
|
|
|
if reginfo != nil {
|
2018-10-03 02:48:11 +08:00
|
|
|
if reginfo.Blocked {
|
2019-08-02 17:30:22 +08:00
|
|
|
logrus.Debugf("registry %q is marked as blocked in registries configuration %q", registry, sysregistriesv2.ConfigPath(sc))
|
2018-10-03 02:48:11 +08:00
|
|
|
} else {
|
2019-08-02 17:30:22 +08:00
|
|
|
logrus.Debugf("registry %q is not marked as blocked in registries configuration %q", registry, sysregistriesv2.ConfigPath(sc))
|
2018-10-03 02:48:11 +08:00
|
|
|
}
|
2018-10-03 01:48:45 +08:00
|
|
|
return reginfo.Blocked, nil
|
|
|
|
}
|
2019-08-02 17:30:22 +08:00
|
|
|
logrus.Debugf("registry %q is not listed in registries configuration %q, assuming it's not blocked", registry, sysregistriesv2.ConfigPath(sc))
|
2018-10-03 01:48:45 +08:00
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// isReferenceSomething checks if the registry part of a reference is insecure or blocked
|
|
|
|
func isReferenceSomething(ref types.ImageReference, sc *types.SystemContext, what func(string, *types.SystemContext) (bool, error)) (bool, error) {
|
|
|
|
if ref != nil && ref.DockerReference() != nil {
|
|
|
|
if named, ok := ref.DockerReference().(reference.Named); ok {
|
|
|
|
if domain := reference.Domain(named); domain != "" {
|
|
|
|
return what(domain, sc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// isReferenceBlocked checks if the registry part of a reference is blocked
|
|
|
|
func isReferenceBlocked(ref types.ImageReference, sc *types.SystemContext) (bool, error) {
|
|
|
|
if ref != nil && ref.Transport() != nil {
|
|
|
|
switch ref.Transport().Name() {
|
|
|
|
case "docker":
|
|
|
|
return isReferenceSomething(ref, sc, isRegistryBlocked)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
2018-09-27 10:23:37 +08:00
|
|
|
// ReserveSELinuxLabels reads containers storage and reserves SELinux containers
|
|
|
|
// fall all existing buildah containers
|
|
|
|
func ReserveSELinuxLabels(store storage.Store, id string) error {
|
|
|
|
if selinux.GetEnabled() {
|
|
|
|
containers, err := store.Containers()
|
|
|
|
if err != nil {
|
2018-10-03 22:05:46 +08:00
|
|
|
return errors.Wrapf(err, "error getting list of containers")
|
2018-09-27 10:23:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, c := range containers {
|
|
|
|
if id == c.ID {
|
|
|
|
continue
|
|
|
|
} else {
|
|
|
|
b, err := OpenBuilder(store, c.ID)
|
|
|
|
if err != nil {
|
2018-10-18 04:58:32 +08:00
|
|
|
if os.IsNotExist(errors.Cause(err)) {
|
2018-09-27 10:23:37 +08:00
|
|
|
// Ignore not exist errors since containers probably created by other tool
|
|
|
|
// TODO, we need to read other containers json data to reserve their SELinux labels
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
// Prevent different containers from using same MCS label
|
|
|
|
if err := label.ReserveLabel(b.ProcessLabel); err != nil {
|
2018-10-03 22:05:46 +08:00
|
|
|
return errors.Wrapf(err, "error reserving SELinux label %q", b.ProcessLabel)
|
2018-09-27 10:23:37 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|