mirror of
https://github.com/containers/podman.git
synced 2025-09-27 08:43:52 +08:00
Vendor in latest containers/buildah
Switch from projectatomic/buildah to containers/buildah Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
572
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
Normal file
572
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
Normal file
@ -0,0 +1,572 @@
|
||||
package parse
|
||||
|
||||
// this package should contain functions that parse and validate
|
||||
// user input and is shared either amongst buildah subcommands or
|
||||
// would be useful to projects vendoring buildah
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/containers/buildah"
|
||||
"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/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
// SeccompDefaultPath defines the default seccomp path
|
||||
SeccompDefaultPath = "/usr/share/containers/seccomp.json"
|
||||
// SeccompOverridePath if this exists it overrides the default seccomp path
|
||||
SeccompOverridePath = "/etc/crio/seccomp.json"
|
||||
)
|
||||
|
||||
// CommonBuildOptions parses the build options from the bud cli
|
||||
func CommonBuildOptions(c *cli.Context) (*buildah.CommonBuildOptions, error) {
|
||||
var (
|
||||
memoryLimit int64
|
||||
memorySwap int64
|
||||
err error
|
||||
)
|
||||
rlim := unix.Rlimit{Cur: 1048576, Max: 1048576}
|
||||
defaultLimits := []string{}
|
||||
if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil {
|
||||
defaultLimits = append(defaultLimits, fmt.Sprintf("nofile=%d:%d", rlim.Cur, rlim.Max))
|
||||
}
|
||||
if err := unix.Setrlimit(unix.RLIMIT_NPROC, &rlim); err == nil {
|
||||
defaultLimits = append(defaultLimits, fmt.Sprintf("nproc=%d:%d", rlim.Cur, rlim.Max))
|
||||
}
|
||||
if c.String("memory") != "" {
|
||||
memoryLimit, err = units.RAMInBytes(c.String("memory"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid value for memory")
|
||||
}
|
||||
}
|
||||
if c.String("memory-swap") != "" {
|
||||
memorySwap, err = units.RAMInBytes(c.String("memory-swap"))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid value for memory-swap")
|
||||
}
|
||||
}
|
||||
if len(c.StringSlice("add-host")) > 0 {
|
||||
for _, host := range c.StringSlice("add-host") {
|
||||
if err := validateExtraHost(host); err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid value for add-host")
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, err := units.FromHumanSize(c.String("shm-size")); err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid --shm-size")
|
||||
}
|
||||
if err := ParseVolumes(c.StringSlice("volume")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commonOpts := &buildah.CommonBuildOptions{
|
||||
AddHost: c.StringSlice("add-host"),
|
||||
CgroupParent: c.String("cgroup-parent"),
|
||||
CPUPeriod: c.Uint64("cpu-period"),
|
||||
CPUQuota: c.Int64("cpu-quota"),
|
||||
CPUSetCPUs: c.String("cpuset-cpus"),
|
||||
CPUSetMems: c.String("cpuset-mems"),
|
||||
CPUShares: c.Uint64("cpu-shares"),
|
||||
Memory: memoryLimit,
|
||||
MemorySwap: memorySwap,
|
||||
ShmSize: c.String("shm-size"),
|
||||
Ulimit: append(defaultLimits, c.StringSlice("ulimit")...),
|
||||
Volumes: c.StringSlice("volume"),
|
||||
}
|
||||
if err := parseSecurityOpts(c.StringSlice("security-opt"), commonOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return commonOpts, nil
|
||||
}
|
||||
|
||||
func parseSecurityOpts(securityOpts []string, commonOpts *buildah.CommonBuildOptions) error {
|
||||
for _, opt := range securityOpts {
|
||||
if opt == "no-new-privileges" {
|
||||
return errors.Errorf("no-new-privileges is not supported")
|
||||
}
|
||||
con := strings.SplitN(opt, "=", 2)
|
||||
if len(con) != 2 {
|
||||
return errors.Errorf("Invalid --security-opt name=value pair: %q", opt)
|
||||
}
|
||||
|
||||
switch con[0] {
|
||||
case "label":
|
||||
commonOpts.LabelOpts = append(commonOpts.LabelOpts, con[1])
|
||||
case "apparmor":
|
||||
commonOpts.ApparmorProfile = con[1]
|
||||
case "seccomp":
|
||||
commonOpts.SeccompProfilePath = con[1]
|
||||
default:
|
||||
return errors.Errorf("Invalid --security-opt 2: %q", opt)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if commonOpts.SeccompProfilePath == "" {
|
||||
if _, err := os.Stat(SeccompOverridePath); err == nil {
|
||||
commonOpts.SeccompProfilePath = SeccompOverridePath
|
||||
} else {
|
||||
if !os.IsNotExist(err) {
|
||||
return errors.Wrapf(err, "can't check if %q exists", SeccompOverridePath)
|
||||
}
|
||||
if _, err := os.Stat(SeccompDefaultPath); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return errors.Wrapf(err, "can't check if %q exists", SeccompDefaultPath)
|
||||
}
|
||||
} else {
|
||||
commonOpts.SeccompProfilePath = SeccompDefaultPath
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseVolumes validates the host and container paths passed in to the --volume flag
|
||||
func ParseVolumes(volumes []string) error {
|
||||
if len(volumes) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, volume := range volumes {
|
||||
arr := strings.SplitN(volume, ":", 3)
|
||||
if len(arr) < 2 {
|
||||
return errors.Errorf("incorrect volume format %q, should be host-dir:ctr-dir[:option]", volume)
|
||||
}
|
||||
if err := validateVolumeHostDir(arr[0]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validateVolumeCtrDir(arr[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(arr) > 2 {
|
||||
if err := validateVolumeOpts(arr[2]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateVolumeHostDir(hostDir string) error {
|
||||
if !filepath.IsAbs(hostDir) {
|
||||
return errors.Errorf("invalid host path, must be an absolute path %q", hostDir)
|
||||
}
|
||||
if _, err := os.Stat(hostDir); err != nil {
|
||||
return errors.Wrapf(err, "error checking path %q", hostDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateVolumeCtrDir(ctrDir string) error {
|
||||
if !filepath.IsAbs(ctrDir) {
|
||||
return errors.Errorf("invalid container path, must be an absolute path %q", ctrDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateVolumeOpts(option string) error {
|
||||
var foundRootPropagation, foundRWRO, foundLabelChange int
|
||||
options := strings.Split(option, ",")
|
||||
for _, opt := range options {
|
||||
switch opt {
|
||||
case "rw", "ro":
|
||||
if foundRWRO > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 'rw' or 'ro' option", option)
|
||||
}
|
||||
foundRWRO++
|
||||
case "z", "Z":
|
||||
if foundLabelChange > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 'z' or 'Z' option", option)
|
||||
}
|
||||
foundLabelChange++
|
||||
case "private", "rprivate", "shared", "rshared", "slave", "rslave", "unbindable", "runbindable":
|
||||
if foundRootPropagation > 1 {
|
||||
return errors.Errorf("invalid options %q, can only specify 1 '[r]shared', '[r]private', '[r]slave' or '[r]unbindable' option", option)
|
||||
}
|
||||
foundRootPropagation++
|
||||
default:
|
||||
return errors.Errorf("invalid option type %q", option)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateExtraHost validates that the specified string is a valid extrahost and returns it.
|
||||
// ExtraHost is in the form of name:ip where the ip has to be a valid ip (ipv4 or ipv6).
|
||||
// for add-host flag
|
||||
func validateExtraHost(val string) error {
|
||||
// allow for IPv6 addresses in extra hosts by only splitting on first ":"
|
||||
arr := strings.SplitN(val, ":", 2)
|
||||
if len(arr) != 2 || len(arr[0]) == 0 {
|
||||
return fmt.Errorf("bad format for add-host: %q", val)
|
||||
}
|
||||
if _, err := validateIPAddress(arr[1]); err != nil {
|
||||
return fmt.Errorf("invalid IP address in add-host: %q", arr[1])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateIPAddress validates an Ip address.
|
||||
// for dns, ip, and ip6 flags also
|
||||
func validateIPAddress(val string) (string, error) {
|
||||
var ip = net.ParseIP(strings.TrimSpace(val))
|
||||
if ip != nil {
|
||||
return ip.String(), nil
|
||||
}
|
||||
return "", fmt.Errorf("%s is not an ip address", val)
|
||||
}
|
||||
|
||||
// ValidateFlags searches for StringFlags or StringSlice flags that never had
|
||||
// a value set. This commonly occurs when the CLI mistakenly takes the next
|
||||
// option and uses it as a value.
|
||||
func ValidateFlags(c *cli.Context, flags []cli.Flag) error {
|
||||
re, err := regexp.Compile("^-.+")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "compiling regex failed")
|
||||
}
|
||||
|
||||
// The --cmd flag can have a following command i.e. --cmd="--help".
|
||||
// Let's skip this check just for the --cmd flag.
|
||||
for _, flag := range flags {
|
||||
switch reflect.TypeOf(flag).String() {
|
||||
case "cli.StringSliceFlag":
|
||||
{
|
||||
f := flag.(cli.StringSliceFlag)
|
||||
name := strings.Split(f.Name, ",")
|
||||
if f.Name == "cmd" {
|
||||
continue
|
||||
}
|
||||
val := c.StringSlice(name[0])
|
||||
for _, v := range val {
|
||||
if ok := re.MatchString(v); ok {
|
||||
return errors.Errorf("option --%s requires a value", name[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
case "cli.StringFlag":
|
||||
{
|
||||
f := flag.(cli.StringFlag)
|
||||
name := strings.Split(f.Name, ",")
|
||||
if f.Name == "cmd" {
|
||||
continue
|
||||
}
|
||||
val := c.String(name[0])
|
||||
if ok := re.MatchString(val); ok {
|
||||
return errors.Errorf("option --%s requires a value", name[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SystemContextFromOptions returns a SystemContext populated with values
|
||||
// per the input parameters provided by the caller for the use in authentication.
|
||||
func SystemContextFromOptions(c *cli.Context) (*types.SystemContext, error) {
|
||||
ctx := &types.SystemContext{
|
||||
DockerCertPath: c.String("cert-dir"),
|
||||
}
|
||||
if c.IsSet("tls-verify") {
|
||||
ctx.DockerInsecureSkipTLSVerify = !c.BoolT("tls-verify")
|
||||
}
|
||||
if c.IsSet("creds") {
|
||||
var err error
|
||||
ctx.DockerAuthConfig, err = getDockerAuth(c.String("creds"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.IsSet("signature-policy") {
|
||||
ctx.SignaturePolicyPath = c.String("signature-policy")
|
||||
}
|
||||
if c.IsSet("authfile") {
|
||||
ctx.AuthFilePath = c.String("authfile")
|
||||
}
|
||||
if c.GlobalIsSet("registries-conf") {
|
||||
ctx.SystemRegistriesConfPath = c.GlobalString("registries-conf")
|
||||
}
|
||||
if c.GlobalIsSet("registries-conf-dir") {
|
||||
ctx.RegistriesDirPath = c.GlobalString("registries-conf-dir")
|
||||
}
|
||||
ctx.DockerRegistryUserAgent = fmt.Sprintf("Buildah/%s", buildah.Version)
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
func parseCreds(creds string) (string, string) {
|
||||
if creds == "" {
|
||||
return "", ""
|
||||
}
|
||||
up := strings.SplitN(creds, ":", 2)
|
||||
if len(up) == 1 {
|
||||
return up[0], ""
|
||||
}
|
||||
if up[0] == "" {
|
||||
return "", up[1]
|
||||
}
|
||||
return up[0], up[1]
|
||||
}
|
||||
|
||||
func getDockerAuth(creds string) (*types.DockerAuthConfig, error) {
|
||||
username, password := parseCreds(creds)
|
||||
if username == "" {
|
||||
fmt.Print("Username: ")
|
||||
fmt.Scanln(&username)
|
||||
}
|
||||
if password == "" {
|
||||
fmt.Print("Password: ")
|
||||
termPassword, err := terminal.ReadPassword(0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not read password from terminal")
|
||||
}
|
||||
password = string(termPassword)
|
||||
}
|
||||
|
||||
return &types.DockerAuthConfig{
|
||||
Username: username,
|
||||
Password: password,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IDMappingOptions parses the build options related to user namespaces and ID mapping.
|
||||
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.
|
||||
var spec []string
|
||||
if c.GlobalIsSet(option) {
|
||||
spec = c.GlobalStringSlice(option)
|
||||
}
|
||||
if c.IsSet(option) {
|
||||
spec = c.StringSlice(option)
|
||||
}
|
||||
idmap, err := parseIDMap(spec)
|
||||
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
|
||||
}
|
||||
|
||||
// NamespaceOptions parses the build options for all namespaces except for 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
|
||||
}
|
||||
|
||||
func defaultIsolation() (buildah.Isolation, error) {
|
||||
isolation, isSet := os.LookupEnv("BUILDAH_ISOLATION")
|
||||
if isSet {
|
||||
if strings.HasPrefix(strings.ToLower(isolation), "oci") {
|
||||
return buildah.IsolationOCI, nil
|
||||
} else if strings.HasPrefix(strings.ToLower(isolation), "rootless") {
|
||||
return buildah.IsolationOCIRootless, nil
|
||||
} else if strings.HasPrefix(strings.ToLower(isolation), "chroot") {
|
||||
return buildah.IsolationChroot, nil
|
||||
}
|
||||
return 0, errors.Errorf("unrecognized $BUILDAH_ISOLATION value %q", isolation)
|
||||
}
|
||||
return buildah.IsolationDefault, nil
|
||||
}
|
||||
|
||||
// IsolationOption parses the --isolation flag.
|
||||
func IsolationOption(c *cli.Context) (buildah.Isolation, error) {
|
||||
if c.String("isolation") != "" {
|
||||
if strings.HasPrefix(strings.ToLower(c.String("isolation")), "oci") {
|
||||
return buildah.IsolationOCI, nil
|
||||
} else if strings.HasPrefix(strings.ToLower(c.String("isolation")), "rootless") {
|
||||
return buildah.IsolationOCIRootless, nil
|
||||
} else if strings.HasPrefix(strings.ToLower(c.String("isolation")), "chroot") {
|
||||
return buildah.IsolationChroot, nil
|
||||
} else {
|
||||
return buildah.IsolationDefault, errors.Errorf("unrecognized isolation type %q", c.String("isolation"))
|
||||
}
|
||||
}
|
||||
return defaultIsolation()
|
||||
}
|
Reference in New Issue
Block a user