diff options
Diffstat (limited to 'cmd/podman/build.go')
-rw-r--r-- | cmd/podman/build.go | 147 |
1 files changed, 87 insertions, 60 deletions
diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 0cd1bfbe3..20f621e84 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -10,38 +10,58 @@ import ( "github.com/containers/buildah/imagebuildah" buildahcli "github.com/containers/buildah/pkg/cli" "github.com/containers/buildah/pkg/parse" + "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/urfave/cli" + "github.com/spf13/cobra" ) var ( - layerFlags = []cli.Flag{ - cli.BoolTFlag{ - Name: "force-rm", - Usage: "Always remove intermediate containers after a build, even if the build is unsuccessful. (default true)", - }, - cli.BoolTFlag{ - Name: "layers", - Usage: "Cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. ", - }, - } + buildCommand cliconfig.BuildValues buildDescription = "Builds an OCI or Docker image using instructions from one\n" + "or more Dockerfiles and a specified build context directory." - buildCommand = cli.Command{ - Name: "build", - Usage: "Build an image using instructions from Dockerfiles", - Description: buildDescription, - Flags: sortFlags(append(append(buildahcli.BudFlags, layerFlags...), buildahcli.FromAndBudFlags...)), - Action: buildCmd, - ArgsUsage: "CONTEXT-DIRECTORY | URL", - SkipArgReorder: true, - OnUsageError: usageErrorHandler, + layerValues buildahcli.LayerResults + budFlagsValues buildahcli.BudResults + fromAndBudValues buildahcli.FromAndBudResults + userNSValues buildahcli.UserNSResults + namespaceValues buildahcli.NameSpaceResults + + _buildCommand = &cobra.Command{ + Use: "build", + Short: "Build an image using instructions from Dockerfiles", + Long: buildDescription, + RunE: func(cmd *cobra.Command, args []string) error { + buildCommand.InputArgs = args + buildCommand.GlobalFlags = MainGlobalOpts + buildCommand.BudResults = &budFlagsValues + buildCommand.UserNSResults = &userNSValues + buildCommand.FromAndBudResults = &fromAndBudValues + buildCommand.LayerResults = &layerValues + buildCommand.NameSpaceResults = &namespaceValues + return buildCmd(&buildCommand) + }, + Example: "CONTEXT-DIRECTORY | URL", } ) +func init() { + buildCommand.Command = _buildCommand + flags := buildCommand.Flags() + flags.SetInterspersed(false) + + flags.BoolVar(&layerValues.ForceRm, "force-rm", true, "Always remove intermediate containers after a build, even if the build is unsuccessful. (default true)") + flags.BoolVar(&layerValues.Layers, "layers", true, "Cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override") + budFlags := buildahcli.GetBudFlags(&budFlagsValues) + fromAndBugFlags := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues) + + flags.AddFlagSet(&budFlags) + flags.AddFlagSet(&fromAndBugFlags) + + rootCmd.AddCommand(buildCommand.Command) +} + func getDockerfiles(files []string) []string { var dockerfiles []string for _, f := range files { @@ -54,30 +74,30 @@ func getDockerfiles(files []string) []string { return dockerfiles } -func buildCmd(c *cli.Context) error { +func buildCmd(c *cliconfig.BuildValues) error { // The following was taken directly from containers/buildah/cmd/bud.go // TODO Find a away to vendor more of this in rather than copy from bud output := "" tags := []string{} - if c.IsSet("tag") || c.IsSet("t") { - tags = c.StringSlice("tag") + if c.Flag("tag").Changed { + tags = c.Tag if len(tags) > 0 { output = tags[0] tags = tags[1:] } } pullPolicy := imagebuildah.PullNever - if c.BoolT("pull") { + if c.Pull { pullPolicy = imagebuildah.PullIfMissing } - if c.Bool("pull-always") { + if c.PullAlways { pullPolicy = imagebuildah.PullAlways } args := make(map[string]string) - if c.IsSet("build-arg") { - for _, arg := range c.StringSlice("build-arg") { + if c.Flag("build-arg").Changed { + for _, arg := range c.BuildArg { av := strings.SplitN(arg, "=", 2) if len(av) > 1 { args[av[0]] = av[1] @@ -87,15 +107,15 @@ func buildCmd(c *cli.Context) error { } } - dockerfiles := getDockerfiles(c.StringSlice("file")) - format, err := getFormat(c) + dockerfiles := getDockerfiles(c.File) + format, err := getFormat(&c.PodmanCommand) if err != nil { return nil } contextDir := "" - cliArgs := c.Args() + cliArgs := c.InputArgs - layers := c.BoolT("layers") // layers for podman defaults to true + layers := c.Layers // layers for podman defaults to true // Check to see if the BUILDAH_LAYERS environment variable is set and override command-line if _, ok := os.LookupEnv("BUILDAH_LAYERS"); ok { layers = buildahcli.UseLayers() @@ -124,7 +144,7 @@ func buildCmd(c *cli.Context) error { } contextDir = absDir } - cliArgs = cliArgs.Tail() + cliArgs = Tail(cliArgs) } else { // No context directory or URL was specified. Try to use the // home of the first locally-available Dockerfile. @@ -153,17 +173,14 @@ func buildCmd(c *cli.Context) error { if len(dockerfiles) == 0 { dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile")) } - if err := parse.ValidateFlags(c, buildahcli.BudFlags); err != nil { - return err - } runtimeFlags := []string{} - for _, arg := range c.StringSlice("runtime-flag") { + for _, arg := range c.RuntimeOpts { runtimeFlags = append(runtimeFlags, "--"+arg) } // end from buildah - runtime, err := libpodruntime.GetRuntime(c) + runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } @@ -173,10 +190,10 @@ func buildCmd(c *cli.Context) error { stdout = os.Stdout stderr = os.Stderr reporter = os.Stderr - if c.IsSet("logfile") { - f, err := os.OpenFile(c.String("logfile"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) + if c.Flag("logfile").Changed { + f, err := os.OpenFile(c.Logfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) if err != nil { - return errors.Errorf("error opening logfile %q: %v", c.String("logfile"), err) + return errors.Errorf("error opening logfile %q: %v", c.Logfile, err) } defer f.Close() logrus.SetOutput(f) @@ -185,36 +202,36 @@ func buildCmd(c *cli.Context) error { reporter = f } - systemContext, err := parse.SystemContextFromOptions(c) + systemContext, err := parse.SystemContextFromOptions(c.PodmanCommand.Command) if err != nil { return errors.Wrapf(err, "error building system context") } - systemContext.AuthFilePath = getAuthFile(c.String("authfile")) - commonOpts, err := parse.CommonBuildOptions(c) + systemContext.AuthFilePath = getAuthFile(c.Authfile) + commonOpts, err := parse.CommonBuildOptions(c.PodmanCommand.Command) if err != nil { return err } - namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c) + namespaceOptions, networkPolicy, err := parse.NamespaceOptions(c.PodmanCommand.Command) if err != nil { return errors.Wrapf(err, "error parsing namespace-related options") } - usernsOption, idmappingOptions, err := parse.IDMappingOptions(c) + usernsOption, idmappingOptions, err := parse.IDMappingOptions(c.PodmanCommand.Command) if err != nil { return errors.Wrapf(err, "error parsing ID mapping options") } namespaceOptions.AddOrReplace(usernsOption...) ociruntime := runtime.GetOCIRuntimePath() - if c.IsSet("runtime") { - ociruntime = c.String("runtime") + if c.Flag("runtime").Changed { + ociruntime = c.Runtime } options := imagebuildah.BuildOptions{ ContextDirectory: contextDir, PullPolicy: pullPolicy, Compression: imagebuildah.Gzip, - Quiet: c.Bool("quiet"), - SignaturePolicyPath: c.String("signature-policy"), + Quiet: c.Quiet, + SignaturePolicyPath: c.SignaturePolicy, Args: args, Output: output, AdditionalTags: tags, @@ -227,22 +244,22 @@ func buildCmd(c *cli.Context) error { SystemContext: systemContext, NamespaceOptions: namespaceOptions, ConfigureNetwork: networkPolicy, - CNIPluginPath: c.String("cni-plugin-path"), - CNIConfigDir: c.String("cni-config-dir"), + CNIPluginPath: c.CNIPlugInPath, + CNIConfigDir: c.CNIConfigDir, IDMappingOptions: idmappingOptions, CommonBuildOpts: commonOpts, - DefaultMountsFilePath: c.GlobalString("default-mounts-file"), - IIDFile: c.String("iidfile"), - Squash: c.Bool("squash"), - Labels: c.StringSlice("label"), - Annotations: c.StringSlice("annotation"), + DefaultMountsFilePath: c.GlobalFlags.DefaultMountsFile, + IIDFile: c.Iidfile, + Squash: c.Squash, + Labels: c.Label, + Annotations: c.Annotation, Layers: layers, - NoCache: c.Bool("no-cache"), - RemoveIntermediateCtrs: c.BoolT("rm"), - ForceRmIntermediateCtrs: c.BoolT("force-rm"), + NoCache: c.NoCache, + RemoveIntermediateCtrs: c.Rm, + ForceRmIntermediateCtrs: c.ForceRm, } - if c.Bool("quiet") { + if c.Quiet { options.ReportWriter = ioutil.Discard } @@ -252,3 +269,13 @@ func buildCmd(c *cli.Context) error { return runtime.Build(getContext(), options, dockerfiles...) } + +// Tail returns a string slice after the first element unless there are +// not enough elements, then it returns an empty slice. This is to replace +// the urfavecli Tail method for args +func Tail(a []string) []string { + if len(a) >= 2 { + return []string(a)[1:] + } + return []string{} +} |