diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/build.go | 92 | ||||
-rw-r--r-- | cmd/podman/cliconfig/config.go | 1 | ||||
-rw-r--r-- | cmd/podman/cliconfig/create.go | 9 | ||||
-rw-r--r-- | cmd/podman/cliconfig/defaults.go | 5 | ||||
-rw-r--r-- | cmd/podman/common.go | 6 | ||||
-rw-r--r-- | cmd/podman/images.go | 16 | ||||
-rw-r--r-- | cmd/podman/inspect.go | 3 | ||||
-rw-r--r-- | cmd/podman/libpodruntime/runtime.go | 17 | ||||
-rw-r--r-- | cmd/podman/shared/container.go | 6 | ||||
-rw-r--r-- | cmd/podman/shared/create.go | 14 | ||||
-rw-r--r-- | cmd/podman/shared/funcs.go | 2 | ||||
-rw-r--r-- | cmd/podman/shared/intermediate.go | 2 | ||||
-rw-r--r-- | cmd/podman/shared/intermediate_varlink.go | 5 | ||||
-rw-r--r-- | cmd/podman/system_migrate.go | 4 | ||||
-rw-r--r-- | cmd/podman/utils.go | 10 | ||||
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 2 |
16 files changed, 132 insertions, 62 deletions
diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 8eb12cacd..f4efea544 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -17,20 +17,22 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) var ( buildCommand cliconfig.BuildValues - buildDescription = "Builds an OCI or Docker image using instructions from one or more Dockerfiles and a specified build context directory." + buildDescription = "Builds an OCI or Docker image using instructions from one or more Containerfiles and a specified build context directory." layerValues buildahcli.LayerResults budFlagsValues buildahcli.BudResults fromAndBudValues buildahcli.FromAndBudResults userNSValues buildahcli.UserNSResults namespaceValues buildahcli.NameSpaceResults + podBuildValues cliconfig.PodmanBuildResults _buildCommand = &cobra.Command{ Use: "build [flags] CONTEXT", - Short: "Build an image using instructions from Dockerfiles", + Short: "Build an image using instructions from Containerfiles", Long: buildDescription, RunE: func(cmd *cobra.Command, args []string) error { buildCommand.InputArgs = args @@ -40,11 +42,12 @@ var ( buildCommand.FromAndBudResults = &fromAndBudValues buildCommand.LayerResults = &layerValues buildCommand.NameSpaceResults = &namespaceValues + buildCommand.PodmanBuildResults = &podBuildValues buildCommand.Remote = remoteclient return buildCmd(&buildCommand) }, Example: `podman build . - podman build --creds=username:password -t imageName -f Dockerfile.simple . + podman build --creds=username:password -t imageName -f Containerfile.simple . podman build --layers --force-rm --tag imageName .`, } ) @@ -73,25 +76,40 @@ func init() { logrus.Error("unable to set force-rm flag to true") } flag.DefValue = "true" + podmanBuildFlags := GetPodmanBuildFlags(&podBuildValues) + flag = podmanBuildFlags.Lookup("squash-all") + if err := flag.Value.Set("false"); err != nil { + logrus.Error("unable to set squash-all flag to false") + } + flag.DefValue = "true" fromAndBugFlags := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues) flags.AddFlagSet(&budFlags) - flags.AddFlagSet(&layerFlags) flags.AddFlagSet(&fromAndBugFlags) + flags.AddFlagSet(&layerFlags) + flags.AddFlagSet(&podmanBuildFlags) markFlagHidden(flags, "signature-policy") } -func getDockerfiles(files []string) []string { - var dockerfiles []string +// GetPodmanBuildFlags flags used only by `podman build` and not by +// `buildah bud`. +func GetPodmanBuildFlags(flags *cliconfig.PodmanBuildResults) pflag.FlagSet { + fs := pflag.FlagSet{} + fs.BoolVar(&flags.SquashAll, "squash-all", false, "Squash all layers into a single layer.") + return fs +} + +func getContainerfiles(files []string) []string { + var containerfiles []string for _, f := range files { if f == "-" { - dockerfiles = append(dockerfiles, "/dev/stdin") + containerfiles = append(containerfiles, "/dev/stdin") } else { - dockerfiles = append(dockerfiles, f) + containerfiles = append(containerfiles, f) } } - return dockerfiles + return containerfiles } func getNsValues(c *cliconfig.BuildValues) ([]buildah.NamespaceOption, error) { @@ -119,6 +137,12 @@ func getNsValues(c *cliconfig.BuildValues) ([]buildah.NamespaceOption, error) { } func buildCmd(c *cliconfig.BuildValues) error { + if (c.Flags().Changed("squash") && c.Flags().Changed("layers")) || + (c.Flags().Changed("squash-all") && c.Flags().Changed("layers")) || + (c.Flags().Changed("squash-all") && c.Flags().Changed("squash")) { + return fmt.Errorf("cannot specify squash, squash-all and layers options together") + } + // 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 := "" @@ -151,7 +175,7 @@ func buildCmd(c *cliconfig.BuildValues) error { } } - dockerfiles := getDockerfiles(c.File) + containerfiles := getContainerfiles(c.File) format, err := getFormat(&c.PodmanCommand) if err != nil { return nil @@ -190,31 +214,35 @@ func buildCmd(c *cliconfig.BuildValues) error { } } else { // No context directory or URL was specified. Try to use the - // home of the first locally-available Dockerfile. - for i := range dockerfiles { - if strings.HasPrefix(dockerfiles[i], "http://") || - strings.HasPrefix(dockerfiles[i], "https://") || - strings.HasPrefix(dockerfiles[i], "git://") || - strings.HasPrefix(dockerfiles[i], "github.com/") { + // home of the first locally-available Containerfile. + for i := range containerfiles { + if strings.HasPrefix(containerfiles[i], "http://") || + strings.HasPrefix(containerfiles[i], "https://") || + strings.HasPrefix(containerfiles[i], "git://") || + strings.HasPrefix(containerfiles[i], "github.com/") { continue } - absFile, err := filepath.Abs(dockerfiles[i]) + absFile, err := filepath.Abs(containerfiles[i]) if err != nil { - return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i]) + return errors.Wrapf(err, "error determining path to file %q", containerfiles[i]) } contextDir = filepath.Dir(absFile) - dockerfiles[i], err = filepath.Rel(contextDir, absFile) + containerfiles[i], err = filepath.Rel(contextDir, absFile) if err != nil { - return errors.Wrapf(err, "error determining path to file %q", dockerfiles[i]) + return errors.Wrapf(err, "error determining path to file %q", containerfiles[i]) } break } } if contextDir == "" { - return errors.Errorf("no context directory specified, and no dockerfile specified") + return errors.Errorf("no context directory specified, and no containerfile specified") } - if len(dockerfiles) == 0 { - dockerfiles = append(dockerfiles, filepath.Join(contextDir, "Dockerfile")) + if len(containerfiles) == 0 { + if checkIfFileExists(filepath.Join(contextDir, "Containerfile")) { + containerfiles = append(containerfiles, filepath.Join(contextDir, "Containerfile")) + } else { + containerfiles = append(containerfiles, filepath.Join(contextDir, "Dockerfile")) + } } runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) @@ -289,6 +317,22 @@ func buildCmd(c *cliconfig.BuildValues) error { Volumes: c.Volumes, } + // `buildah bud --layers=false` acts like `docker build --squash` does. + // That is all of the new layers created during the build process are + // condensed into one, any layers present prior to this build are retained + // without condensing. `buildah bud --squash` squashes both new and old + // layers down into one. Translate Podman commands into Buildah. + // Squash invoked, retain old layers, squash new layers into one. + if c.Flags().Changed("squash") && c.Squash { + c.Squash = false + layers = false + } + // Squash-all invoked, squash both new and old layers into one. + if c.Flags().Changed("squash-all") { + c.Squash = true + layers = false + } + options := imagebuildah.BuildOptions{ CommonBuildOpts: &buildOpts, AdditionalTags: tags, @@ -318,7 +362,7 @@ func buildCmd(c *cliconfig.BuildValues) error { Squash: c.Squash, Target: c.Target, } - return runtime.Build(getContext(), c, options, dockerfiles) + return runtime.Build(getContext(), c, options, containerfiles) } // useLayers returns false if BUILDAH_LAYERS is set to "0" or "false" diff --git a/cmd/podman/cliconfig/config.go b/cmd/podman/cliconfig/config.go index 5b5225f02..4831b7971 100644 --- a/cmd/podman/cliconfig/config.go +++ b/cmd/podman/cliconfig/config.go @@ -651,6 +651,7 @@ type SystemRenumberValues struct { type SystemMigrateValues struct { PodmanCommand + NewRuntime string } type SystemDfValues struct { diff --git a/cmd/podman/cliconfig/create.go b/cmd/podman/cliconfig/create.go index 5fb2eed10..c27dfbbee 100644 --- a/cmd/podman/cliconfig/create.go +++ b/cmd/podman/cliconfig/create.go @@ -12,13 +12,20 @@ type RunValues struct { PodmanCommand } +// PodmanBuildResults represents the results for Podman Build flags +// that are unique to Podman. +type PodmanBuildResults struct { + SquashAll bool +} + type BuildValues struct { PodmanCommand *buildahcli.BudResults *buildahcli.UserNSResults *buildahcli.FromAndBudResults - *buildahcli.NameSpaceResults *buildahcli.LayerResults + *buildahcli.NameSpaceResults + *PodmanBuildResults } type CpValues struct { diff --git a/cmd/podman/cliconfig/defaults.go b/cmd/podman/cliconfig/defaults.go index d5dae0874..ce695d153 100644 --- a/cmd/podman/cliconfig/defaults.go +++ b/cmd/podman/cliconfig/defaults.go @@ -1,10 +1,5 @@ package cliconfig -const ( - // DefaultSystemD value - DefaultSystemD bool = true -) - var ( // DefaultHealthCheckInterval default value DefaultHealthCheckInterval = "30s" diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 2a3f8f3ad..e93586b62 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -455,9 +455,9 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "sysctl", []string{}, "Sysctl options (default [])", ) - createFlags.Bool( - "systemd", cliconfig.DefaultSystemD, - "Run container in systemd mode if the command executable is systemd or init", + createFlags.String( + "systemd", "true", + `Run container in systemd mode ("true"|"false"|"always" (default "true")`, ) createFlags.StringArray( "tmpfs", []string{}, diff --git a/cmd/podman/images.go b/cmd/podman/images.go index fe7c89b5c..e363fa3bb 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -216,17 +216,18 @@ func (i imagesOptions) setOutputFormat() string { } // imagesToGeneric creates an empty array of interfaces for output -func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSONParams) (genericParams []interface{}) { +func imagesToGeneric(templParams []imagesTemplateParams, JSONParams []imagesJSONParams) []interface{} { + genericParams := []interface{}{} if len(templParams) > 0 { for _, v := range templParams { genericParams = append(genericParams, interface{}(v)) } - return + return genericParams } for _, v := range JSONParams { genericParams = append(genericParams, interface{}(v)) } - return + return genericParams } func sortImagesOutput(sortBy string, imagesOutput imagesSorted) imagesSorted { @@ -309,7 +310,8 @@ func getImagesTemplateOutput(ctx context.Context, images []*adapter.ContainerIma } // getImagesJSONOutput returns the images information in its raw form -func getImagesJSONOutput(ctx context.Context, images []*adapter.ContainerImage) (imagesOutput []imagesJSONParams) { +func getImagesJSONOutput(ctx context.Context, images []*adapter.ContainerImage) []imagesJSONParams { + imagesOutput := []imagesJSONParams{} for _, img := range images { size, err := img.Size(ctx) if err != nil { @@ -325,7 +327,7 @@ func getImagesJSONOutput(ctx context.Context, images []*adapter.ContainerImage) } imagesOutput = append(imagesOutput, params) } - return + return imagesOutput } // generateImagesOutput generates the images based on the format provided @@ -336,10 +338,6 @@ func generateImagesOutput(ctx context.Context, images []*adapter.ContainerImage, switch opts.format { case formats.JSONString: - // If 0 images are present, print nothing for JSON - if len(images) == 0 { - return nil - } imagesOutput := getImagesJSONOutput(ctx, images) out = formats.JSONStructArray{Output: imagesToGeneric([]imagesTemplateParams{}, imagesOutput)} default: diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index cff221cb0..872b59561 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -104,6 +104,9 @@ func inspectCmd(c *cliconfig.InspectValues) error { if strings.Contains(outputFormat, ".Dst") { outputFormat = strings.Replace(outputFormat, ".Dst", ".Destination", -1) } + if strings.Contains(outputFormat, ".ImageID") { + outputFormat = strings.Replace(outputFormat, ".ImageID", ".Image", -1) + } if latestContainer { lc, err := runtime.GetLatestContainer() if err != nil { diff --git a/cmd/podman/libpodruntime/runtime.go b/cmd/podman/libpodruntime/runtime.go index 6dafeb0b0..dd8c3f173 100644 --- a/cmd/podman/libpodruntime/runtime.go +++ b/cmd/podman/libpodruntime/runtime.go @@ -14,31 +14,31 @@ import ( ) // GetRuntimeMigrate gets a libpod runtime that will perform a migration of existing containers -func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { - return getRuntime(ctx, c, false, true, false, true) +func GetRuntimeMigrate(ctx context.Context, c *cliconfig.PodmanCommand, newRuntime string) (*libpod.Runtime, error) { + return getRuntime(ctx, c, false, true, false, true, newRuntime) } // GetRuntimeDisableFDs gets a libpod runtime that will disable sd notify func GetRuntimeDisableFDs(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { - return getRuntime(ctx, c, false, false, false, false) + return getRuntime(ctx, c, false, false, false, false, "") } // GetRuntimeRenumber gets a libpod runtime that will perform a lock renumber func GetRuntimeRenumber(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { - return getRuntime(ctx, c, true, false, false, true) + return getRuntime(ctx, c, true, false, false, true, "") } // GetRuntime generates a new libpod runtime configured by command line options func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { - return getRuntime(ctx, c, false, false, false, true) + return getRuntime(ctx, c, false, false, false, true, "") } // GetRuntimeNoStore generates a new libpod runtime configured by command line options func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*libpod.Runtime, error) { - return getRuntime(ctx, c, false, false, true, true) + return getRuntime(ctx, c, false, false, true, true, "") } -func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool) (*libpod.Runtime, error) { +func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migrate, noStore, withFDS bool, newRuntime string) (*libpod.Runtime, error) { options := []libpod.RuntimeOption{} storageOpts := storage.StoreOptions{} storageSet := false @@ -88,6 +88,9 @@ func getRuntime(ctx context.Context, c *cliconfig.PodmanCommand, renumber, migra } if migrate { options = append(options, libpod.WithMigrate()) + if newRuntime != "" { + options = append(options, libpod.WithMigrateRuntime(newRuntime)) + } } if renumber { diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index 022377b1f..15bbb46d2 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -449,10 +449,8 @@ func GetPsContainerOutput(r *libpod.Runtime, opts PsOptions, filters []string, m // PBatch performs batch operations on a container in parallel. It spawns the // number of workers relative to the number of parallel operations desired. func PBatch(containers []*libpod.Container, workers int, opts PsOptions) []PsContainerOutput { - var ( - wg sync.WaitGroup - psResults []PsContainerOutput - ) + var wg sync.WaitGroup + psResults := []PsContainerOutput{} // If the number of containers in question is less than the number of // proposed parallel operations, we shouldnt spawn so many workers. diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index 9020613c5..bf9410b72 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -662,9 +662,17 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod. return nil, errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.String("image-volume")) } - var systemd bool - if command != nil && c.Bool("systemd") && ((filepath.Base(command[0]) == "init") || (filepath.Base(command[0]) == "systemd")) { - systemd = true + systemd := c.String("systemd") == "always" + if !systemd && command != nil { + x, err := strconv.ParseBool(c.String("systemd")) + if err != nil { + return nil, errors.Wrapf(err, "cannot parse bool %s", c.String("systemd")) + } + if x && (command[0] == "/usr/sbin/init" || command[0] == "/sbin/init" || (filepath.Base(command[0]) == "systemd")) { + systemd = true + } + } + if systemd { if signalString == "" { stopSignal, err = signal.ParseSignal("RTMIN+3") if err != nil { diff --git a/cmd/podman/shared/funcs.go b/cmd/podman/shared/funcs.go index bb4eed1e3..9362e8e9b 100644 --- a/cmd/podman/shared/funcs.go +++ b/cmd/podman/shared/funcs.go @@ -21,7 +21,7 @@ func GetAuthFile(authfile string) string { } if runtimeDir, err := util.GetRuntimeDir(); err == nil { - return filepath.Join(runtimeDir, "auth.json") + return filepath.Join(runtimeDir, "containers/auth.json") } return "" } diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go index cccdd1bea..0f71dc087 100644 --- a/cmd/podman/shared/intermediate.go +++ b/cmd/podman/shared/intermediate.go @@ -449,7 +449,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes m["subgidname"] = newCRString(c, "subgidname") m["subuidname"] = newCRString(c, "subuidname") m["sysctl"] = newCRStringSlice(c, "sysctl") - m["systemd"] = newCRBool(c, "systemd") + m["systemd"] = newCRString(c, "systemd") m["tmpfs"] = newCRStringArray(c, "tmpfs") m["tty"] = newCRBool(c, "tty") m["uidmap"] = newCRStringSlice(c, "uidmap") diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go index 9dbf83950..c95470a72 100644 --- a/cmd/podman/shared/intermediate_varlink.go +++ b/cmd/podman/shared/intermediate_varlink.go @@ -152,7 +152,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create { Subuidname: StringToPtr(g.Find("subuidname")), Subgidname: StringToPtr(g.Find("subgidname")), Sysctl: StringSliceToPtr(g.Find("sysctl")), - Systemd: BoolToPtr(g.Find("systemd")), + Systemd: StringToPtr(g.Find("systemd")), Tmpfs: StringSliceToPtr(g.Find("tmpfs")), Tty: BoolToPtr(g.Find("tty")), Uidmap: StringSliceToPtr(g.Find("uidmap")), @@ -321,6 +321,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { var memSwapDefault int64 = -1 netModeDefault := "bridge" + systemdDefault := "true" if rootless.IsRootless() { netModeDefault = "slirp4netns" } @@ -409,7 +410,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults { m["subgidname"] = stringFromVarlink(opts.Subgidname, "subgidname", nil) m["subuidname"] = stringFromVarlink(opts.Subuidname, "subuidname", nil) m["sysctl"] = stringSliceFromVarlink(opts.Sysctl, "sysctl", nil) - m["systemd"] = boolFromVarlink(opts.Systemd, "systemd", cliconfig.DefaultSystemD) + m["systemd"] = stringFromVarlink(opts.Systemd, "systemd", &systemdDefault) m["tmpfs"] = stringSliceFromVarlink(opts.Tmpfs, "tmpfs", nil) m["tty"] = boolFromVarlink(opts.Tty, "tty", false) m["uidmap"] = stringSliceFromVarlink(opts.Uidmap, "uidmap", nil) diff --git a/cmd/podman/system_migrate.go b/cmd/podman/system_migrate.go index 4a0afcfad..9c90aeb52 100644 --- a/cmd/podman/system_migrate.go +++ b/cmd/podman/system_migrate.go @@ -32,13 +32,15 @@ func init() { migrateCommand.Command = _migrateCommand migrateCommand.SetHelpTemplate(HelpTemplate()) migrateCommand.SetUsageTemplate(UsageTemplate()) + flags := migrateCommand.Flags() + flags.StringVar(&migrateCommand.NewRuntime, "new-runtime", "", "Specify a new runtime for all containers") } func migrateCmd(c *cliconfig.SystemMigrateValues) error { // We need to pass one extra option to NewRuntime. // This will inform the OCI runtime to start a migrate. // That's controlled by the last argument to GetRuntime. - r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand) + r, err := libpodruntime.GetRuntimeMigrate(getContext(), &c.PodmanCommand, c.NewRuntime) if err != nil { return errors.Wrapf(err, "error migrating containers") } diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index c0ddaba4e..592d7a1d1 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "reflect" "runtime/debug" @@ -63,3 +64,12 @@ func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { } return pflag.NormalizedName(name) } + +// Check if a file exists and is not a directory +func checkIfFileExists(name string) bool { + file, err := os.Stat(name) + if os.IsNotExist(err) { + return false + } + return !file.IsDir() +} diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 2408dc80c..13e8394fb 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -363,7 +363,7 @@ type Create ( subuidname: ?string, subgidname: ?string, sysctl: ?[]string, - systemd: ?bool, + systemd: ?string, tmpfs: ?[]string, tty: ?bool, uidmap: ?[]string, |