mirror of
https://github.com/containers/podman.git
synced 2025-09-27 16:54:42 +08:00
Migrate to cobra CLI
We intend to migrate to the cobra cli from urfave/cli because the project is more well maintained. There are also some technical reasons as well which extend into our remote client work. Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
185
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
185
vendor/github.com/containers/buildah/pkg/parse/parse.go
generated
vendored
@ -6,11 +6,10 @@ package parse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
@ -22,7 +21,6 @@ import (
|
||||
"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"
|
||||
)
|
||||
@ -35,7 +33,7 @@ const (
|
||||
)
|
||||
|
||||
// CommonBuildOptions parses the build options from the bud cli
|
||||
func CommonBuildOptions(c *cli.Context) (*buildah.CommonBuildOptions, error) {
|
||||
func CommonBuildOptions(c *cobra.Command) (*buildah.CommonBuildOptions, error) {
|
||||
var (
|
||||
memoryLimit int64
|
||||
memorySwap int64
|
||||
@ -49,47 +47,57 @@ func CommonBuildOptions(c *cli.Context) (*buildah.CommonBuildOptions, error) {
|
||||
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"))
|
||||
memVal, _ := c.Flags().GetString("memory")
|
||||
if memVal != "" {
|
||||
memoryLimit, err = units.RAMInBytes(memVal)
|
||||
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"))
|
||||
|
||||
memSwapValue, _ := c.Flags().GetString("memory-swap")
|
||||
if memSwapValue != "" {
|
||||
memorySwap, err = units.RAMInBytes(memSwapValue)
|
||||
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") {
|
||||
|
||||
addHost, _ := c.Flags().GetStringSlice("add-host")
|
||||
if len(addHost) > 0 {
|
||||
for _, host := range addHost {
|
||||
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 {
|
||||
if _, err := units.FromHumanSize(c.Flag("shm-size").Value.String()); err != nil {
|
||||
return nil, errors.Wrapf(err, "invalid --shm-size")
|
||||
}
|
||||
if err := ParseVolumes(c.StringSlice("volume")); err != nil {
|
||||
volumes, _ := c.Flags().GetStringSlice("volume")
|
||||
if err := ParseVolumes(volumes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cpuPeriod, _ := c.Flags().GetUint64("cpu-period")
|
||||
cpuQuota, _ := c.Flags().GetInt64("cpu-quota")
|
||||
cpuShares, _ := c.Flags().GetUint64("cpu-shared")
|
||||
ulimit, _ := c.Flags().GetStringSlice("ulimit")
|
||||
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"),
|
||||
AddHost: addHost,
|
||||
CgroupParent: c.Flag("cgroup-parent").Value.String(),
|
||||
CPUPeriod: cpuPeriod,
|
||||
CPUQuota: cpuQuota,
|
||||
CPUSetCPUs: c.Flag("cpuset-cpus").Value.String(),
|
||||
CPUSetMems: c.Flag("cpuset-mems").Value.String(),
|
||||
CPUShares: cpuShares,
|
||||
Memory: memoryLimit,
|
||||
MemorySwap: memorySwap,
|
||||
ShmSize: c.String("shm-size"),
|
||||
Ulimit: append(defaultLimits, c.StringSlice("ulimit")...),
|
||||
Volumes: c.StringSlice("volume"),
|
||||
ShmSize: c.Flag("shm-size").Value.String(),
|
||||
Ulimit: append(defaultLimits, ulimit...),
|
||||
Volumes: volumes,
|
||||
}
|
||||
if err := parseSecurityOpts(c.StringSlice("security-opt"), commonOpts); err != nil {
|
||||
securityOpts, _ := c.Flags().GetStringSlice("security-opt")
|
||||
if err := parseSecurityOpts(securityOpts, commonOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return commonOpts, nil
|
||||
@ -231,79 +239,45 @@ func validateIPAddress(val string) (string, error) {
|
||||
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) {
|
||||
func SystemContextFromOptions(c *cobra.Command) (*types.SystemContext, error) {
|
||||
certDir, err := c.Flags().GetString("cert-dir")
|
||||
if err != nil {
|
||||
certDir = ""
|
||||
}
|
||||
ctx := &types.SystemContext{
|
||||
DockerCertPath: c.String("cert-dir"),
|
||||
DockerCertPath: certDir,
|
||||
}
|
||||
if c.IsSet("tls-verify") {
|
||||
ctx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.BoolT("tls-verify"))
|
||||
ctx.OCIInsecureSkipTLSVerify = !c.BoolT("tls-verify")
|
||||
ctx.DockerDaemonInsecureSkipTLSVerify = !c.BoolT("tls-verify")
|
||||
tlsVerify, err := c.Flags().GetBool("tls-verify")
|
||||
if err == nil && c.Flag("tls-verify").Changed {
|
||||
ctx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(tlsVerify)
|
||||
ctx.OCIInsecureSkipTLSVerify = tlsVerify
|
||||
ctx.DockerDaemonInsecureSkipTLSVerify = tlsVerify
|
||||
}
|
||||
if c.IsSet("creds") {
|
||||
creds, err := c.Flags().GetString("creds")
|
||||
if err == nil && c.Flag("creds").Changed {
|
||||
var err error
|
||||
ctx.DockerAuthConfig, err = getDockerAuth(c.String("creds"))
|
||||
ctx.DockerAuthConfig, err = getDockerAuth(creds)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.IsSet("signature-policy") {
|
||||
ctx.SignaturePolicyPath = c.String("signature-policy")
|
||||
sigPolicy, err := c.Flags().GetString("signature-policy")
|
||||
if err == nil && c.Flag("signature-policy").Changed {
|
||||
ctx.SignaturePolicyPath = sigPolicy
|
||||
}
|
||||
if c.IsSet("authfile") {
|
||||
ctx.AuthFilePath = c.String("authfile")
|
||||
authfile, err := c.Flags().GetString("authfile")
|
||||
if err == nil && c.Flag("authfile").Changed {
|
||||
ctx.AuthFilePath = authfile
|
||||
}
|
||||
if c.GlobalIsSet("registries-conf") {
|
||||
ctx.SystemRegistriesConfPath = c.GlobalString("registries-conf")
|
||||
regConf, err := c.Flags().GetString("registries-conf")
|
||||
if err == nil && c.Flag("registries-conf").Changed {
|
||||
ctx.SystemRegistriesConfPath = regConf
|
||||
}
|
||||
if c.GlobalIsSet("registries-conf-dir") {
|
||||
ctx.RegistriesDirPath = c.GlobalString("registries-conf-dir")
|
||||
regConfDir, err := c.Flags().GetString("registries-conf-dir")
|
||||
if err == nil && c.Flag("registries-conf-dir").Changed {
|
||||
ctx.RegistriesDirPath = regConfDir
|
||||
}
|
||||
ctx.DockerRegistryUserAgent = fmt.Sprintf("Buildah/%s", buildah.Version)
|
||||
return ctx, nil
|
||||
@ -345,9 +319,9 @@ func getDockerAuth(creds string) (*types.DockerAuthConfig, error) {
|
||||
}
|
||||
|
||||
// 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")
|
||||
func IDMappingOptions(c *cobra.Command) (usernsOptions buildah.NamespaceOptions, idmapOptions *buildah.IDMappingOptions, err error) {
|
||||
user := c.Flag("userns-uid-map-user").Value.String()
|
||||
group := c.Flag("userns-gid-map-group").Value.String()
|
||||
// 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.
|
||||
@ -366,6 +340,7 @@ func IDMappingOptions(c *cli.Context) (usernsOptions buildah.NamespaceOptions, i
|
||||
}
|
||||
mappings = submappings
|
||||
}
|
||||
globalOptions := c.PersistentFlags()
|
||||
// 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))
|
||||
@ -380,11 +355,11 @@ func IDMappingOptions(c *cli.Context) (usernsOptions buildah.NamespaceOptions, i
|
||||
// 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 globalOptions.Lookup(option) != nil && globalOptions.Lookup(option).Changed {
|
||||
spec, _ = globalOptions.GetStringSlice(option)
|
||||
}
|
||||
if c.IsSet(option) {
|
||||
spec = c.StringSlice(option)
|
||||
if c.Flag(option).Changed {
|
||||
spec, _ = c.Flags().GetStringSlice(option)
|
||||
}
|
||||
idmap, err := parseIDMap(spec)
|
||||
if err != nil {
|
||||
@ -424,8 +399,8 @@ func IDMappingOptions(c *cli.Context) (usernsOptions buildah.NamespaceOptions, i
|
||||
}
|
||||
// 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")
|
||||
if c.Flag("userns").Changed {
|
||||
how := c.Flag("userns").Value.String()
|
||||
switch how {
|
||||
case "", "container":
|
||||
usernsOption.Host = false
|
||||
@ -440,7 +415,12 @@ func IDMappingOptions(c *cli.Context) (usernsOptions buildah.NamespaceOptions, i
|
||||
}
|
||||
}
|
||||
usernsOptions = buildah.NamespaceOptions{usernsOption}
|
||||
if !c.IsSet("net") {
|
||||
|
||||
// Because --net and --network are technically two different flags, we need
|
||||
// to check each for nil and .Changed
|
||||
usernet := c.Flags().Lookup("net")
|
||||
usernetwork := c.Flags().Lookup("network")
|
||||
if (usernet != nil && usernetwork != nil) && (!usernet.Changed && !usernetwork.Changed) {
|
||||
usernsOptions = append(usernsOptions, buildah.NamespaceOption{
|
||||
Name: string(specs.NetworkNamespace),
|
||||
Host: usernsOption.Host,
|
||||
@ -486,12 +466,12 @@ func parseIDMap(spec []string) (m [][3]uint32, err error) {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
func NamespaceOptions(c *cobra.Command) (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)
|
||||
for _, what := range []string{string(specs.IPCNamespace), "net", "network", string(specs.PIDNamespace), string(specs.UTSNamespace)} {
|
||||
if c.Flags().Lookup(what) != nil && c.Flag(what).Changed {
|
||||
how := c.Flag(what).Value.String()
|
||||
switch what {
|
||||
case "net", "network":
|
||||
what = string(specs.NetworkNamespace)
|
||||
@ -560,9 +540,10 @@ func defaultIsolation() (buildah.Isolation, error) {
|
||||
}
|
||||
|
||||
// IsolationOption parses the --isolation flag.
|
||||
func IsolationOption(c *cli.Context) (buildah.Isolation, error) {
|
||||
if c.String("isolation") != "" {
|
||||
switch strings.ToLower(c.String("isolation")) {
|
||||
func IsolationOption(c *cobra.Command) (buildah.Isolation, error) {
|
||||
isolation, _ := c.Flags().GetString("isolation")
|
||||
if isolation != "" {
|
||||
switch strings.ToLower(isolation) {
|
||||
case "oci":
|
||||
return buildah.IsolationOCI, nil
|
||||
case "rootless":
|
||||
@ -570,7 +551,7 @@ func IsolationOption(c *cli.Context) (buildah.Isolation, error) {
|
||||
case "chroot":
|
||||
return buildah.IsolationChroot, nil
|
||||
default:
|
||||
return 0, errors.Errorf("unrecognized isolation type %q", c.String("isolation"))
|
||||
return 0, errors.Errorf("unrecognized isolation type %q", isolation)
|
||||
}
|
||||
}
|
||||
return defaultIsolation()
|
||||
|
Reference in New Issue
Block a user