summaryrefslogtreecommitdiff
path: root/vendor/github.com/projectatomic/buildah/pkg/parse
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2018-06-07 01:00:07 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-06-07 17:14:02 +0000
commitcf7c8295b8875ddd4fe87a4207aa302efbd90b18 (patch)
treef9358349d4574e469b72db2208a57c0f5160da91 /vendor/github.com/projectatomic/buildah/pkg/parse
parent7d6e717dd9f8fe367b64839089db859ca6bd8a83 (diff)
downloadpodman-cf7c8295b8875ddd4fe87a4207aa302efbd90b18.tar.gz
podman-cf7c8295b8875ddd4fe87a4207aa302efbd90b18.tar.bz2
podman-cf7c8295b8875ddd4fe87a4207aa302efbd90b18.zip
Vendor in latest buildah code
Use the parsing code to properly setup podman build namespaces Fixes support for network namespace and user namespace Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Closes: #917 Approved by: rhatdan
Diffstat (limited to 'vendor/github.com/projectatomic/buildah/pkg/parse')
-rw-r--r--vendor/github.com/projectatomic/buildah/pkg/parse/parse.go200
1 files changed, 198 insertions, 2 deletions
diff --git a/vendor/github.com/projectatomic/buildah/pkg/parse/parse.go b/vendor/github.com/projectatomic/buildah/pkg/parse/parse.go
index eb7be9c1e..1a4a1e423 100644
--- a/vendor/github.com/projectatomic/buildah/pkg/parse/parse.go
+++ b/vendor/github.com/projectatomic/buildah/pkg/parse/parse.go
@@ -11,12 +11,17 @@ import (
"path/filepath"
"reflect"
"regexp"
+ "strconv"
"strings"
+ "unicode"
"github.com/containers/image/types"
+ "github.com/containers/storage/pkg/idtools"
"github.com/docker/go-units"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/projectatomic/buildah"
+ "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"golang.org/x/crypto/ssh/terminal"
)
@@ -28,8 +33,8 @@ const (
SeccompOverridePath = "/etc/crio/seccomp.json"
)
-// ParseCommonBuildOptions parses the build options from the bud cli
-func ParseCommonBuildOptions(c *cli.Context) (*buildah.CommonBuildOptions, error) {
+// CommonBuildOptions parses the build options from the bud cli
+func CommonBuildOptions(c *cli.Context) (*buildah.CommonBuildOptions, error) {
var (
memoryLimit int64
memorySwap int64
@@ -326,3 +331,194 @@ func getDockerAuth(creds string) (*types.DockerAuthConfig, error) {
Password: password,
}, nil
}
+
+// IDMappingOptions parses the build options from user namespace
+func IDMappingOptions(c *cli.Context) (usernsOptions buildah.NamespaceOptions, idmapOptions *buildah.IDMappingOptions, err error) {
+ user := c.String("userns-uid-map-user")
+ group := c.String("userns-gid-map-group")
+ // If only the user or group was specified, use the same value for the
+ // other, since we need both in order to initialize the maps using the
+ // names.
+ if user == "" && group != "" {
+ user = group
+ }
+ if group == "" && user != "" {
+ group = user
+ }
+ // Either start with empty maps or the name-based maps.
+ mappings := idtools.NewIDMappingsFromMaps(nil, nil)
+ if user != "" && group != "" {
+ submappings, err := idtools.NewIDMappings(user, group)
+ if err != nil {
+ return nil, nil, err
+ }
+ mappings = submappings
+ }
+ // We'll parse the UID and GID mapping options the same way.
+ buildIDMap := func(basemap []idtools.IDMap, option string) ([]specs.LinuxIDMapping, error) {
+ outmap := make([]specs.LinuxIDMapping, 0, len(basemap))
+ // Start with the name-based map entries.
+ for _, m := range basemap {
+ outmap = append(outmap, specs.LinuxIDMapping{
+ ContainerID: uint32(m.ContainerID),
+ HostID: uint32(m.HostID),
+ Size: uint32(m.Size),
+ })
+ }
+ // Parse the flag's value as one or more triples (if it's even
+ // been set), and append them.
+ idmap, err := parseIDMap(c.StringSlice(option))
+ if err != nil {
+ return nil, err
+ }
+ for _, m := range idmap {
+ outmap = append(outmap, specs.LinuxIDMapping{
+ ContainerID: m[0],
+ HostID: m[1],
+ Size: m[2],
+ })
+ }
+ return outmap, nil
+ }
+ uidmap, err := buildIDMap(mappings.UIDs(), "userns-uid-map")
+ if err != nil {
+ return nil, nil, err
+ }
+ gidmap, err := buildIDMap(mappings.GIDs(), "userns-gid-map")
+ if err != nil {
+ return nil, nil, err
+ }
+ // If we only have one map or the other populated at this point, then
+ // use the same mapping for both, since we know that no user or group
+ // name was specified, but a specific mapping was for one or the other.
+ if len(uidmap) == 0 && len(gidmap) != 0 {
+ uidmap = gidmap
+ }
+ if len(gidmap) == 0 && len(uidmap) != 0 {
+ gidmap = uidmap
+ }
+ // By default, having mappings configured means we use a user
+ // namespace. Otherwise, we don't.
+ usernsOption := buildah.NamespaceOption{
+ Name: string(specs.UserNamespace),
+ Host: len(uidmap) == 0 && len(gidmap) == 0,
+ }
+ // If the user specifically requested that we either use or don't use
+ // user namespaces, override that default.
+ if c.IsSet("userns") {
+ how := c.String("userns")
+ switch how {
+ case "", "container":
+ usernsOption.Host = false
+ case "host":
+ usernsOption.Host = true
+ default:
+ if _, err := os.Stat(how); err != nil {
+ return nil, nil, errors.Wrapf(err, "error checking for %s namespace at %q", string(specs.UserNamespace), how)
+ }
+ logrus.Debugf("setting %q namespace to %q", string(specs.UserNamespace), how)
+ usernsOption.Path = how
+ }
+ }
+ usernsOptions = buildah.NamespaceOptions{usernsOption}
+ if !c.IsSet("net") {
+ usernsOptions = append(usernsOptions, buildah.NamespaceOption{
+ Name: string(specs.NetworkNamespace),
+ Host: usernsOption.Host,
+ })
+ }
+ // If the user requested that we use the host namespace, but also that
+ // we use mappings, that's not going to work.
+ if (len(uidmap) != 0 || len(gidmap) != 0) && usernsOption.Host {
+ return nil, nil, errors.Errorf("can not specify ID mappings while using host's user namespace")
+ }
+ return usernsOptions, &buildah.IDMappingOptions{
+ HostUIDMapping: usernsOption.Host,
+ HostGIDMapping: usernsOption.Host,
+ UIDMap: uidmap,
+ GIDMap: gidmap,
+ }, nil
+}
+
+func parseIDMap(spec []string) (m [][3]uint32, err error) {
+ for _, s := range spec {
+ args := strings.FieldsFunc(s, func(r rune) bool { return !unicode.IsDigit(r) })
+ if len(args)%3 != 0 {
+ return nil, fmt.Errorf("mapping %q is not in the form containerid:hostid:size[,...]", s)
+ }
+ for len(args) >= 3 {
+ cid, err := strconv.ParseUint(args[0], 10, 32)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing container ID %q from mapping %q as a number: %v", args[0], s, err)
+ }
+ hostid, err := strconv.ParseUint(args[1], 10, 32)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing host ID %q from mapping %q as a number: %v", args[1], s, err)
+ }
+ size, err := strconv.ParseUint(args[2], 10, 32)
+ if err != nil {
+ return nil, fmt.Errorf("error parsing %q from mapping %q as a number: %v", args[2], s, err)
+ }
+ m = append(m, [3]uint32{uint32(cid), uint32(hostid), uint32(size)})
+ args = args[3:]
+ }
+ }
+ return m, nil
+}
+
+// NamesapceOptions parses the build options from all namespaces except user namespace
+func NamespaceOptions(c *cli.Context) (namespaceOptions buildah.NamespaceOptions, networkPolicy buildah.NetworkConfigurationPolicy, err error) {
+ options := make(buildah.NamespaceOptions, 0, 7)
+ policy := buildah.NetworkDefault
+ for _, what := range []string{string(specs.IPCNamespace), "net", string(specs.PIDNamespace), string(specs.UTSNamespace)} {
+ if c.IsSet(what) {
+ how := c.String(what)
+ switch what {
+ case "net", "network":
+ what = string(specs.NetworkNamespace)
+ }
+ switch how {
+ case "", "container":
+ logrus.Debugf("setting %q namespace to %q", what, "")
+ options.AddOrReplace(buildah.NamespaceOption{
+ Name: what,
+ })
+ case "host":
+ logrus.Debugf("setting %q namespace to host", what)
+ options.AddOrReplace(buildah.NamespaceOption{
+ Name: what,
+ Host: true,
+ })
+ default:
+ if what == specs.NetworkNamespace {
+ if how == "none" {
+ options.AddOrReplace(buildah.NamespaceOption{
+ Name: what,
+ })
+ policy = buildah.NetworkDisabled
+ logrus.Debugf("setting network to disabled")
+ break
+ }
+ if !filepath.IsAbs(how) {
+ options.AddOrReplace(buildah.NamespaceOption{
+ Name: what,
+ Path: how,
+ })
+ policy = buildah.NetworkEnabled
+ logrus.Debugf("setting network configuration to %q", how)
+ break
+ }
+ }
+ if _, err := os.Stat(how); err != nil {
+ return nil, buildah.NetworkDefault, errors.Wrapf(err, "error checking for %s namespace at %q", what, how)
+ }
+ logrus.Debugf("setting %q namespace to %q", what, how)
+ options.AddOrReplace(buildah.NamespaceOption{
+ Name: what,
+ Path: how,
+ })
+ }
+ }
+ }
+ return options, policy, nil
+}