diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2018-07-27 07:21:47 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-07-27 13:07:19 +0000 |
commit | 02e7efc2b35da65cb4e27b0d58923d6c7b3a1c6c (patch) | |
tree | cbb0d236dc3fe4c83874389ec521b1424b571b24 /vendor | |
parent | 876a30590b93757ca16ee607dee4f4458983620c (diff) | |
download | podman-02e7efc2b35da65cb4e27b0d58923d6c7b3a1c6c.tar.gz podman-02e7efc2b35da65cb4e27b0d58923d6c7b3a1c6c.tar.bz2 podman-02e7efc2b35da65cb4e27b0d58923d6c7b3a1c6c.zip |
Update vendored version of runc,buildah,containers/image
There is a compiler warning that has been fixed in the
upstream, so I figured we should update to fix.
Also vendor in latest buildah to get better support for running builds in rootless
mode.
Vendor in latest containers/image to allow daemon support to be pluggable.
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Closes: #1169
Approved by: mheon
Diffstat (limited to 'vendor')
18 files changed, 459 insertions, 132 deletions
diff --git a/vendor/github.com/containers/image/transports/alltransports/alltransports.go b/vendor/github.com/containers/image/transports/alltransports/alltransports.go index b4552df66..23b2782f6 100644 --- a/vendor/github.com/containers/image/transports/alltransports/alltransports.go +++ b/vendor/github.com/containers/image/transports/alltransports/alltransports.go @@ -9,7 +9,6 @@ import ( _ "github.com/containers/image/directory" _ "github.com/containers/image/docker" _ "github.com/containers/image/docker/archive" - _ "github.com/containers/image/docker/daemon" _ "github.com/containers/image/oci/archive" _ "github.com/containers/image/oci/layout" _ "github.com/containers/image/openshift" diff --git a/vendor/github.com/containers/image/transports/alltransports/docker_daemon.go b/vendor/github.com/containers/image/transports/alltransports/docker_daemon.go new file mode 100644 index 000000000..6d2ba4b30 --- /dev/null +++ b/vendor/github.com/containers/image/transports/alltransports/docker_daemon.go @@ -0,0 +1,8 @@ +// +build !containers_image_docker_daemon_stub + +package alltransports + +import ( + // Register the docker-daemon transport + _ "github.com/containers/image/docker/daemon" +) diff --git a/vendor/github.com/containers/image/transports/alltransports/docker_daemon_stub.go b/vendor/github.com/containers/image/transports/alltransports/docker_daemon_stub.go new file mode 100644 index 000000000..27f3850f1 --- /dev/null +++ b/vendor/github.com/containers/image/transports/alltransports/docker_daemon_stub.go @@ -0,0 +1,9 @@ +// +build containers_image_docker_daemon_stub + +package alltransports + +import "github.com/containers/image/transports" + +func init() { + transports.Register(transports.NewStubTransport("docker-daemon")) +} diff --git a/vendor/github.com/opencontainers/runc/README.md b/vendor/github.com/opencontainers/runc/README.md index 3ca7a1a22..5215e32c1 100644 --- a/vendor/github.com/opencontainers/runc/README.md +++ b/vendor/github.com/opencontainers/runc/README.md @@ -41,8 +41,18 @@ make sudo make install ``` +You can also use `go get` to install to your `GOPATH`, assuming that you have a `github.com` parent folder already created under `src`: + +```bash +go get github.com/opencontainers/runc +cd $GOPATH/src/github.com/opencontainers/runc +make +sudo make install +``` + `runc` will be installed to `/usr/local/sbin/runc` on your system. + #### Build Tags `runc` supports optional build tags for compiling support of various features. @@ -204,8 +214,7 @@ runc list runc delete mycontainerid ``` -This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted. -This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running. +This allows higher level systems to augment the containers creation logic with setup of various settings after the container is created and/or before it is deleted. For example, the container's network stack is commonly set up after `create` but before `start`. #### Rootless containers `runc` has the ability to run containers without root privileges. This is called `rootless`. You need to pass some parameters to `runc` in order to run rootless containers. See below and compare with the previous version. Run the following commands as an ordinary user: diff --git a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go index 3cae4fd8d..b1c4762fe 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/configs/config.go @@ -141,9 +141,10 @@ type Config struct { // OomScoreAdj specifies the adjustment to be made by the kernel when calculating oom scores // for a process. Valid values are between the range [-1000, '1000'], where processes with - // higher scores are preferred for being killed. + // higher scores are preferred for being killed. If it is unset then we don't touch the current + // value. // More information about kernel oom score calculation here: https://lwn.net/Articles/317814/ - OomScoreAdj int `json:"oom_score_adj"` + OomScoreAdj *int `json:"oom_score_adj,omitempty"` // UidMappings is an array of User ID mappings for User Namespaces UidMappings []IDMap `json:"uid_mappings"` diff --git a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go index 361925890..5e2ab0581 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go @@ -30,8 +30,9 @@ func DeviceFromPath(path, permissions string) (*configs.Device, error) { } var ( - devNumber = stat.Rdev + devNumber = uint64(stat.Rdev) major = unix.Major(devNumber) + minor = unix.Minor(devNumber) ) if major == 0 { return nil, ErrNotADevice @@ -51,7 +52,7 @@ func DeviceFromPath(path, permissions string) (*configs.Device, error) { Type: devType, Path: path, Major: int64(major), - Minor: int64(unix.Minor(devNumber)), + Minor: int64(minor), Permissions: permissions, FileMode: os.FileMode(mode), Uid: stat.Uid, diff --git a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c index 2c69cee5d..a4cd1399d 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c +++ b/vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c @@ -505,7 +505,8 @@ void join_namespaces(char *nslist) ns->fd = fd; ns->ns = nsflag(namespace); - strncpy(ns->path, path, PATH_MAX); + strncpy(ns->path, path, PATH_MAX - 1); + ns->path[PATH_MAX - 1] = '\0'; } while ((namespace = strtok_r(NULL, ",", &saveptr)) != NULL); /* @@ -678,17 +679,15 @@ void nsexec(void) /* * Enable setgroups(2) if we've been asked to. But we also * have to explicitly disable setgroups(2) if we're - * creating a rootless container (this is required since - * Linux 3.19). + * creating a rootless container for single-entry mapping. + * i.e. config.is_setgroup == false. + * (this is required since Linux 3.19). + * + * For rootless multi-entry mapping, config.is_setgroup shall be true and + * newuidmap/newgidmap shall be used. */ - if (config.is_rootless && config.is_setgroup) { - kill(child, SIGKILL); - bail("cannot allow setgroup in an unprivileged user namespace setup"); - } - if (config.is_setgroup) - update_setgroups(child, SETGROUPS_ALLOW); - if (config.is_rootless) + if (config.is_rootless && !config.is_setgroup) update_setgroups(child, SETGROUPS_DENY); /* Set up mappings. */ @@ -810,24 +809,29 @@ void nsexec(void) join_namespaces(config.namespaces); /* - * Unshare all of the namespaces. Now, it should be noted that this - * ordering might break in the future (especially with rootless - * containers). But for now, it's not possible to split this into - * CLONE_NEWUSER + [the rest] because of some RHEL SELinux issues. - * - * Note that we don't merge this with clone() because there were - * some old kernel versions where clone(CLONE_PARENT | CLONE_NEWPID) - * was broken, so we'll just do it the long way anyway. - */ - if (unshare(config.cloneflags) < 0) - bail("failed to unshare namespaces"); - - /* * Deal with user namespaces first. They are quite special, as they * affect our ability to unshare other namespaces and are used as * context for privilege checks. + * + * We don't unshare all namespaces in one go. The reason for this + * is that, while the kernel documentation may claim otherwise, + * there are certain cases where unsharing all namespaces at once + * will result in namespace objects being owned incorrectly. + * Ideally we should just fix these kernel bugs, but it's better to + * be safe than sorry, and fix them separately. + * + * A specific case of this is that the SELinux label of the + * internal kern-mount that mqueue uses will be incorrect if the + * UTS namespace is cloned before the USER namespace is mapped. + * I've also heard of similar problems with the network namespace + * in some scenarios. This also mirrors how LXC deals with this + * problem. */ if (config.cloneflags & CLONE_NEWUSER) { + if (unshare(CLONE_NEWUSER) < 0) + bail("failed to unshare user namespace"); + config.cloneflags &= ~CLONE_NEWUSER; + /* * We don't have the privileges to do any mapping here (see the * clone_parent rant). So signal our parent to hook us up. @@ -853,9 +857,22 @@ void nsexec(void) if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) < 0) bail("failed to set process as dumpable"); } + + /* Become root in the namespace proper. */ + if (setresuid(0, 0, 0) < 0) + bail("failed to become root in user namespace"); } /* + * Unshare all of the namespaces. Note that we don't merge this + * with clone() because there were some old kernel versions where + * clone(CLONE_PARENT | CLONE_NEWPID) was broken, so we'll just do + * it the long way. + */ + if (unshare(config.cloneflags) < 0) + bail("failed to unshare namespaces"); + + /* * TODO: What about non-namespace clone flags that we're dropping here? * * We fork again because of PID namespace, setns(2) or unshare(2) don't diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go index 5f124cd8b..a4ae8901a 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/linux.go @@ -3,13 +3,12 @@ package system import ( - "bufio" - "fmt" "os" "os/exec" "syscall" // only for exec "unsafe" + "github.com/opencontainers/runc/libcontainer/user" "golang.org/x/sys/unix" ) @@ -102,34 +101,43 @@ func Setctty() error { } // RunningInUserNS detects whether we are currently running in a user namespace. -// Copied from github.com/lxc/lxd/shared/util.go +// Originally copied from github.com/lxc/lxd/shared/util.go func RunningInUserNS() bool { - file, err := os.Open("/proc/self/uid_map") + uidmap, err := user.CurrentProcessUIDMap() if err != nil { // This kernel-provided file only exists if user namespaces are supported return false } - defer file.Close() - - buf := bufio.NewReader(file) - l, _, err := buf.ReadLine() - if err != nil { - return false - } + return UIDMapInUserNS(uidmap) +} - line := string(l) - var a, b, c int64 - fmt.Sscanf(line, "%d %d %d", &a, &b, &c) +func UIDMapInUserNS(uidmap []user.IDMap) bool { /* * We assume we are in the initial user namespace if we have a full * range - 4294967295 uids starting at uid 0. */ - if a == 0 && b == 0 && c == 4294967295 { + if len(uidmap) == 1 && uidmap[0].ID == 0 && uidmap[0].ParentID == 0 && uidmap[0].Count == 4294967295 { return false } return true } +// GetParentNSeuid returns the euid within the parent user namespace +func GetParentNSeuid() int64 { + euid := int64(os.Geteuid()) + uidmap, err := user.CurrentProcessUIDMap() + if err != nil { + // This kernel-provided file only exists if user namespaces are supported + return euid + } + for _, um := range uidmap { + if um.ID <= euid && euid <= um.ID+um.Count-1 { + return um.ParentID + euid - um.ID + } + } + return euid +} + // SetSubreaper sets the value i as the subreaper setting for the calling process func SetSubreaper(i int) error { return unix.Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go b/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go index e7cfd62b2..b94be74a6 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go @@ -2,8 +2,26 @@ package system +import ( + "os" + + "github.com/opencontainers/runc/libcontainer/user" +) + // RunningInUserNS is a stub for non-Linux systems // Always returns false func RunningInUserNS() bool { return false } + +// UIDMapInUserNS is a stub for non-Linux systems +// Always returns false +func UIDMapInUserNS(uidmap []user.IDMap) bool { + return false +} + +// GetParentNSeuid returns the euid within the parent user namespace +// Always returns os.Geteuid on non-linux +func GetParentNSeuid() int { + return os.Geteuid() +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go index 95e9eebc0..6fd8dd0d4 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go @@ -12,84 +12,30 @@ var ( ErrNoGroupEntries = errors.New("no matching entries in group file") ) -func lookupUser(filter func(u User) bool) (User, error) { - // Get operating system-specific passwd reader-closer. - passwd, err := GetPasswd() - if err != nil { - return User{}, err - } - defer passwd.Close() - - // Get the users. - users, err := ParsePasswdFilter(passwd, filter) - if err != nil { - return User{}, err - } - - // No user entries found. - if len(users) == 0 { - return User{}, ErrNoPasswdEntries - } - - // Assume the first entry is the "correct" one. - return users[0], nil -} - // LookupUser looks up a user by their username in /etc/passwd. If the user // cannot be found (or there is no /etc/passwd file on the filesystem), then // LookupUser returns an error. func LookupUser(username string) (User, error) { - return lookupUser(func(u User) bool { - return u.Name == username - }) + return lookupUser(username) } // LookupUid looks up a user by their user id in /etc/passwd. If the user cannot // be found (or there is no /etc/passwd file on the filesystem), then LookupId // returns an error. func LookupUid(uid int) (User, error) { - return lookupUser(func(u User) bool { - return u.Uid == uid - }) -} - -func lookupGroup(filter func(g Group) bool) (Group, error) { - // Get operating system-specific group reader-closer. - group, err := GetGroup() - if err != nil { - return Group{}, err - } - defer group.Close() - - // Get the users. - groups, err := ParseGroupFilter(group, filter) - if err != nil { - return Group{}, err - } - - // No user entries found. - if len(groups) == 0 { - return Group{}, ErrNoGroupEntries - } - - // Assume the first entry is the "correct" one. - return groups[0], nil + return lookupUid(uid) } // LookupGroup looks up a group by its name in /etc/group. If the group cannot // be found (or there is no /etc/group file on the filesystem), then LookupGroup // returns an error. func LookupGroup(groupname string) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Name == groupname - }) + return lookupGroup(groupname) } // LookupGid looks up a group by its group id in /etc/group. If the group cannot // be found (or there is no /etc/group file on the filesystem), then LookupGid // returns an error. func LookupGid(gid int) (Group, error) { - return lookupGroup(func(g Group) bool { - return g.Gid == gid - }) + return lookupGid(gid) } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go index c2bb9ec90..c1e634c94 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go @@ -15,6 +15,76 @@ const ( unixGroupPath = "/etc/group" ) +func lookupUser(username string) (User, error) { + return lookupUserFunc(func(u User) bool { + return u.Name == username + }) +} + +func lookupUid(uid int) (User, error) { + return lookupUserFunc(func(u User) bool { + return u.Uid == uid + }) +} + +func lookupUserFunc(filter func(u User) bool) (User, error) { + // Get operating system-specific passwd reader-closer. + passwd, err := GetPasswd() + if err != nil { + return User{}, err + } + defer passwd.Close() + + // Get the users. + users, err := ParsePasswdFilter(passwd, filter) + if err != nil { + return User{}, err + } + + // No user entries found. + if len(users) == 0 { + return User{}, ErrNoPasswdEntries + } + + // Assume the first entry is the "correct" one. + return users[0], nil +} + +func lookupGroup(groupname string) (Group, error) { + return lookupGroupFunc(func(g Group) bool { + return g.Name == groupname + }) +} + +func lookupGid(gid int) (Group, error) { + return lookupGroupFunc(func(g Group) bool { + return g.Gid == gid + }) +} + +func lookupGroupFunc(filter func(g Group) bool) (Group, error) { + // Get operating system-specific group reader-closer. + group, err := GetGroup() + if err != nil { + return Group{}, err + } + defer group.Close() + + // Get the users. + groups, err := ParseGroupFilter(group, filter) + if err != nil { + return Group{}, err + } + + // No user entries found. + if len(groups) == 0 { + return Group{}, ErrNoGroupEntries + } + + // Assume the first entry is the "correct" one. + return groups[0], nil +} + func GetPasswdPath() (string, error) { return unixPasswdPath, nil } @@ -44,3 +114,29 @@ func CurrentUser() (User, error) { func CurrentGroup() (Group, error) { return LookupGid(unix.Getgid()) } + +func CurrentUserSubUIDs() ([]SubID, error) { + u, err := CurrentUser() + if err != nil { + return nil, err + } + return ParseSubIDFileFilter("/etc/subuid", + func(entry SubID) bool { return entry.Name == u.Name }) +} + +func CurrentGroupSubGIDs() ([]SubID, error) { + g, err := CurrentGroup() + if err != nil { + return nil, err + } + return ParseSubIDFileFilter("/etc/subgid", + func(entry SubID) bool { return entry.Name == g.Name }) +} + +func CurrentProcessUIDMap() ([]IDMap, error) { + return ParseIDMapFile("/proc/self/uid_map") +} + +func CurrentProcessGIDMap() ([]IDMap, error) { + return ParseIDMapFile("/proc/self/gid_map") +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go new file mode 100644 index 000000000..65cd40e92 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go @@ -0,0 +1,40 @@ +// +build windows + +package user + +import ( + "fmt" + "os/user" +) + +func lookupUser(username string) (User, error) { + u, err := user.Lookup(username) + if err != nil { + return User{}, err + } + return userFromOS(u) +} + +func lookupUid(uid int) (User, error) { + u, err := user.LookupId(fmt.Sprintf("%d", uid)) + if err != nil { + return User{}, err + } + return userFromOS(u) +} + +func lookupGroup(groupname string) (Group, error) { + g, err := user.LookupGroup(groupname) + if err != nil { + return Group{}, err + } + return groupFromOS(g) +} + +func lookupGid(gid int) (Group, error) { + g, err := user.LookupGroupId(fmt.Sprintf("%d", gid)) + if err != nil { + return Group{}, err + } + return groupFromOS(g) +} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index 8962cab33..7b912bbf8 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "os" + "os/user" "strconv" "strings" ) @@ -28,6 +29,28 @@ type User struct { Shell string } +// userFromOS converts an os/user.(*User) to local User +// +// (This does not include Pass, Shell or Gecos) +func userFromOS(u *user.User) (User, error) { + newUser := User{ + Name: u.Username, + Home: u.HomeDir, + } + id, err := strconv.Atoi(u.Uid) + if err != nil { + return newUser, err + } + newUser.Uid = id + + id, err = strconv.Atoi(u.Gid) + if err != nil { + return newUser, err + } + newUser.Gid = id + return newUser, nil +} + type Group struct { Name string Pass string @@ -35,12 +58,46 @@ type Group struct { List []string } +// groupFromOS converts an os/user.(*Group) to local Group +// +// (This does not include Pass, Shell or Gecos) +func groupFromOS(g *user.Group) (Group, error) { + newGroup := Group{ + Name: g.Name, + } + + id, err := strconv.Atoi(g.Gid) + if err != nil { + return newGroup, err + } + newGroup.Gid = id + + return newGroup, nil +} + +// SubID represents an entry in /etc/sub{u,g}id +type SubID struct { + Name string + SubID int64 + Count int64 +} + +// IDMap represents an entry in /proc/PID/{u,g}id_map +type IDMap struct { + ID int64 + ParentID int64 + Count int64 +} + func parseLine(line string, v ...interface{}) { - if line == "" { + parseParts(strings.Split(line, ":"), v...) +} + +func parseParts(parts []string, v ...interface{}) { + if len(parts) == 0 { return } - parts := strings.Split(line, ":") for i, p := range parts { // Ignore cases where we don't have enough fields to populate the arguments. // Some configuration files like to misbehave. @@ -56,6 +113,8 @@ func parseLine(line string, v ...interface{}) { case *int: // "numbers", with conversion errors ignored because of some misbehaving configuration files. *e, _ = strconv.Atoi(p) + case *int64: + *e, _ = strconv.ParseInt(p, 10, 64) case *[]string: // Comma-separated lists. if p != "" { @@ -65,7 +124,7 @@ func parseLine(line string, v ...interface{}) { } default: // Someone goof'd when writing code using this function. Scream so they can hear us. - panic(fmt.Sprintf("parseLine only accepts {*string, *int, *[]string} as arguments! %#v is not a pointer!", e)) + panic(fmt.Sprintf("parseLine only accepts {*string, *int, *int64, *[]string} as arguments! %#v is not a pointer!", e)) } } } @@ -439,3 +498,111 @@ func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int } return GetAdditionalGroups(additionalGroups, group) } + +func ParseSubIDFile(path string) ([]SubID, error) { + subid, err := os.Open(path) + if err != nil { + return nil, err + } + defer subid.Close() + return ParseSubID(subid) +} + +func ParseSubID(subid io.Reader) ([]SubID, error) { + return ParseSubIDFilter(subid, nil) +} + +func ParseSubIDFileFilter(path string, filter func(SubID) bool) ([]SubID, error) { + subid, err := os.Open(path) + if err != nil { + return nil, err + } + defer subid.Close() + return ParseSubIDFilter(subid, filter) +} + +func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { + if r == nil { + return nil, fmt.Errorf("nil source for subid-formatted data") + } + + var ( + s = bufio.NewScanner(r) + out = []SubID{} + ) + + for s.Scan() { + if err := s.Err(); err != nil { + return nil, err + } + + line := strings.TrimSpace(s.Text()) + if line == "" { + continue + } + + // see: man 5 subuid + p := SubID{} + parseLine(line, &p.Name, &p.SubID, &p.Count) + + if filter == nil || filter(p) { + out = append(out, p) + } + } + + return out, nil +} + +func ParseIDMapFile(path string) ([]IDMap, error) { + r, err := os.Open(path) + if err != nil { + return nil, err + } + defer r.Close() + return ParseIDMap(r) +} + +func ParseIDMap(r io.Reader) ([]IDMap, error) { + return ParseIDMapFilter(r, nil) +} + +func ParseIDMapFileFilter(path string, filter func(IDMap) bool) ([]IDMap, error) { + r, err := os.Open(path) + if err != nil { + return nil, err + } + defer r.Close() + return ParseIDMapFilter(r, filter) +} + +func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { + if r == nil { + return nil, fmt.Errorf("nil source for idmap-formatted data") + } + + var ( + s = bufio.NewScanner(r) + out = []IDMap{} + ) + + for s.Scan() { + if err := s.Err(); err != nil { + return nil, err + } + + line := strings.TrimSpace(s.Text()) + if line == "" { + continue + } + + // see: man 7 user_namespaces + p := IDMap{} + parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) + + if filter == nil || filter(p) { + out = append(out, p) + } + } + + return out, nil +} diff --git a/vendor/github.com/opencontainers/runc/vendor.conf b/vendor/github.com/opencontainers/runc/vendor.conf index 0ab4685fd..e2b519e67 100644 --- a/vendor/github.com/opencontainers/runc/vendor.conf +++ b/vendor/github.com/opencontainers/runc/vendor.conf @@ -21,5 +21,5 @@ github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e golang.org/x/sys 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce https://github.com/golang/sys # console dependencies -github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e +github.com/containerd/console 2748ece16665b45a47f884001d5831ec79703880 github.com/pkg/errors v0.8.0 diff --git a/vendor/github.com/projectatomic/buildah/docker/types.go b/vendor/github.com/projectatomic/buildah/docker/types.go index 9890eaf93..759fc1246 100644 --- a/vendor/github.com/projectatomic/buildah/docker/types.go +++ b/vendor/github.com/projectatomic/buildah/docker/types.go @@ -15,15 +15,6 @@ import ( const TypeLayers = "layers" // github.com/docker/distribution/manifest/schema2/manifest.go -const V2S2MediaTypeManifest = "application/vnd.docker.distribution.manifest.v2+json" - -// github.com/docker/distribution/manifest/schema2/manifest.go -const V2S2MediaTypeImageConfig = "application/vnd.docker.container.image.v1+json" - -// github.com/docker/distribution/manifest/schema2/manifest.go -const V2S2MediaTypeLayer = "application/vnd.docker.image.rootfs.diff.tar.gzip" - -// github.com/docker/distribution/manifest/schema2/manifest.go const V2S2MediaTypeUncompressedLayer = "application/vnd.docker.image.rootfs.diff.tar" // github.com/moby/moby/image/rootfs.go diff --git a/vendor/github.com/projectatomic/buildah/image.go b/vendor/github.com/projectatomic/buildah/image.go index f8b9de6cf..b94720f59 100644 --- a/vendor/github.com/projectatomic/buildah/image.go +++ b/vendor/github.com/projectatomic/buildah/image.go @@ -13,6 +13,7 @@ import ( "github.com/containers/image/docker/reference" "github.com/containers/image/image" + "github.com/containers/image/manifest" is "github.com/containers/image/storage" "github.com/containers/image/types" "github.com/containers/storage" @@ -34,7 +35,7 @@ const ( // Dockerv2ImageManifest is the MIME type of a Docker v2s2 image // manifest, suitable for specifying as a value of the // PreferredManifestType member of a CommitOptions structure. - Dockerv2ImageManifest = docker.V2S2MediaTypeManifest + Dockerv2ImageManifest = manifest.DockerV2Schema2MediaType ) type containerImageRef struct { @@ -106,12 +107,13 @@ func expectedDockerDiffIDs(image docker.V2Image) int { // compression that we'll be applying. func (i *containerImageRef) computeLayerMIMEType(what string) (omediaType, dmediaType string, err error) { omediaType = v1.MediaTypeImageLayer + //TODO: Convert to manifest.DockerV2Schema2LayerUncompressedMediaType once available dmediaType = docker.V2S2MediaTypeUncompressedLayer if i.compression != archive.Uncompressed { switch i.compression { case archive.Gzip: omediaType = v1.MediaTypeImageLayerGzip - dmediaType = docker.V2S2MediaTypeLayer + dmediaType = manifest.DockerV2Schema2LayerMediaType logrus.Debugf("compressing %s with gzip", what) case archive.Bzip2: // Until the image specs define a media type for bzip2-compressed layers, even if we know @@ -207,10 +209,10 @@ func (i *containerImageRef) createConfigsAndManifests() (v1.Image, v1.Manifest, dmanifest := docker.V2S2Manifest{ V2Versioned: docker.V2Versioned{ SchemaVersion: 2, - MediaType: docker.V2S2MediaTypeManifest, + MediaType: manifest.DockerV2Schema2MediaType, }, Config: docker.V2S2Descriptor{ - MediaType: docker.V2S2MediaTypeImageConfig, + MediaType: manifest.DockerV2Schema2ConfigMediaType, }, Layers: []docker.V2S2Descriptor{}, } @@ -222,9 +224,9 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Decide which type of manifest and configuration output we're going to provide. manifestType := i.preferredManifestType // If it's not a format we support, return an error. - if manifestType != v1.MediaTypeImageManifest && manifestType != docker.V2S2MediaTypeManifest { + if manifestType != v1.MediaTypeImageManifest && manifestType != manifest.DockerV2Schema2MediaType { return nil, errors.Errorf("no supported manifest types (attempted to use %q, only know %q and %q)", - manifestType, v1.MediaTypeImageManifest, docker.V2S2MediaTypeManifest) + manifestType, v1.MediaTypeImageManifest, manifest.DockerV2Schema2MediaType) } // Start building the list of layers using the read-write layer. layers := []string{} @@ -448,7 +450,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Add the configuration blob to the manifest. dmanifest.Config.Digest = digest.Canonical.FromBytes(dconfig) dmanifest.Config.Size = int64(len(dconfig)) - dmanifest.Config.MediaType = docker.V2S2MediaTypeImageConfig + dmanifest.Config.MediaType = manifest.DockerV2Schema2ConfigMediaType // Encode the manifest. dmanifestbytes, err := json.Marshal(&dmanifest) @@ -459,13 +461,13 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System // Decide which manifest and configuration blobs we'll actually output. var config []byte - var manifest []byte + var imageManifest []byte switch manifestType { case v1.MediaTypeImageManifest: - manifest = omanifestbytes + imageManifest = omanifestbytes config = oconfig - case docker.V2S2MediaTypeManifest: - manifest = dmanifestbytes + case manifest.DockerV2Schema2MediaType: + imageManifest = dmanifestbytes config = dconfig default: panic("unreachable code: unsupported manifest type") @@ -481,7 +483,7 @@ func (i *containerImageRef) NewImageSource(ctx context.Context, sc *types.System compression: i.compression, config: config, configDigest: digest.Canonical.FromBytes(config), - manifest: manifest, + manifest: imageManifest, manifestType: manifestType, exporting: i.exporting, } diff --git a/vendor/github.com/projectatomic/buildah/run.go b/vendor/github.com/projectatomic/buildah/run.go index 6d9fa260f..b9a7b4e9e 100644 --- a/vendor/github.com/projectatomic/buildah/run.go +++ b/vendor/github.com/projectatomic/buildah/run.go @@ -938,6 +938,17 @@ func (b *Builder) Run(command []string, options RunOptions) error { b.configureEnvironment(g, options) + if os.Getuid() != 0 { + g.RemoveMount("/dev/pts") + devPts := specs.Mount{ + Destination: "/dev/pts", + Type: "devpts", + Source: "devpts", + Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, + } + g.AddMount(devPts) + } + if b.CommonBuildOpts == nil { return errors.Errorf("Invalid format on container you must recreate the container") } @@ -1212,7 +1223,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetwork // Figure out how we're doing stdio handling, and create pipes and sockets. var stdio sync.WaitGroup var consoleListener *net.UnixListener - var errorFds []int + var errorFds, closeBeforeReadingErrorFds []int stdioPipe := make([][]int, 3) copyConsole := false copyPipes := false @@ -1244,6 +1255,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetwork return 1, err } errorFds = []int{stdioPipe[unix.Stdout][0], stdioPipe[unix.Stderr][0]} + closeBeforeReadingErrorFds = []int{stdioPipe[unix.Stdout][1], stdioPipe[unix.Stderr][1]} // Set stdio to our pipes. getCreateStdio = func() (io.ReadCloser, io.WriteCloser, io.WriteCloser) { stdin := os.NewFile(uintptr(stdioPipe[unix.Stdin][0]), "/dev/stdin") @@ -1290,7 +1302,7 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetwork // Actually create the container. err = create.Run() if err != nil { - return 1, errors.Wrapf(err, "error creating container for %v: %s", spec.Process.Args, runCollectOutput(errorFds...)) + return 1, errors.Wrapf(err, "error creating container for %v: %s", spec.Process.Args, runCollectOutput(errorFds, closeBeforeReadingErrorFds)) } defer func() { err2 := del.Run() @@ -1412,7 +1424,10 @@ func runUsingRuntime(options RunOptions, configureNetwork bool, configureNetwork return wstatus, nil } -func runCollectOutput(fds ...int) string { +func runCollectOutput(fds, closeBeforeReadingFds []int) string { + for _, fd := range closeBeforeReadingFds { + unix.Close(fd) + } var b bytes.Buffer buf := make([]byte, 8192) for _, fd := range fds { diff --git a/vendor/github.com/projectatomic/buildah/vendor.conf b/vendor/github.com/projectatomic/buildah/vendor.conf index 1254e4dad..94e5ebb10 100644 --- a/vendor/github.com/projectatomic/buildah/vendor.conf +++ b/vendor/github.com/projectatomic/buildah/vendor.conf @@ -5,7 +5,7 @@ github.com/containerd/continuity master github.com/containernetworking/cni v0.6.0 github.com/seccomp/containers-golang master github.com/containers/image master -github.com/containers/storage 8b1a0f8d6863cf05709af333b8997a437652ec4c +github.com/containers/storage afdedba2d2ad573350aee35033d4e0c58fdbd57b github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716 github.com/docker/docker b8571fd81c7d2223c9ecbf799c693e3ef1daaea9 github.com/docker/docker-credential-helpers d68f9aeca33f5fd3f08eeae5e9d175edf4e731d1 |