summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/containers/image/transports/alltransports/alltransports.go1
-rw-r--r--vendor/github.com/containers/image/transports/alltransports/docker_daemon.go8
-rw-r--r--vendor/github.com/containers/image/transports/alltransports/docker_daemon_stub.go9
-rw-r--r--vendor/github.com/opencontainers/runc/README.md13
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/configs/config.go5
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/devices/devices.go5
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c63
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/system/linux.go38
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/system/unsupported.go18
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go62
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go96
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go40
-rw-r--r--vendor/github.com/opencontainers/runc/libcontainer/user/user.go173
-rw-r--r--vendor/github.com/opencontainers/runc/vendor.conf2
-rw-r--r--vendor/github.com/projectatomic/buildah/docker/types.go9
-rw-r--r--vendor/github.com/projectatomic/buildah/image.go26
-rw-r--r--vendor/github.com/projectatomic/buildah/run.go21
-rw-r--r--vendor/github.com/projectatomic/buildah/vendor.conf2
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