diff options
236 files changed, 1540 insertions, 5363 deletions
diff --git a/.golangci.yml b/.golangci.yml index da22b7602..cf067a58c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,30 +7,47 @@ run: - contrib - dependencies - test - - pkg/spec - - vendor skip-files: - - iopodman.go - swagger.go modules-download-mode: readonly linters: enable-all: true disable: # All these break for one reason or another + - nolintlint + - gocognit + - testpackage + - goerr113 + - exhaustivestruct + - errorlint + - wrapcheck + - paralleltest + - wsl + - godox + - tparallel + - gomnd + - nlreturn + - noctx + - nestif + - predeclared + - thelper + - ifshort + - staticcheck + - forbidigo + - exhaustive + - unparam + - gofumpt + - gci + - godot + - makezero - dupl - funlen - gochecknoglobals - gochecknoinits - goconst - gocyclo - - golint - lll - - structcheck - - typecheck - unconvert - - varcheck - - deadcode - - depguard - errcheck - gocritic - gosec @@ -609,7 +609,7 @@ endef .PHONY: .install.golangci-lint .install.golangci-lint: .gopathok - VERSION=1.18.0 GOBIN=$(GOBIN) sh ./hack/install_golangci.sh + VERSION=1.36.0 GOBIN=$(GOBIN) sh ./hack/install_golangci.sh .PHONY: .install.bats .install.bats: .gopathok diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 17d90aeca..b802a4805 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,36 @@ # Release Notes +## 3.0.1 +### Changes +- Several frequently-occurring `WARN` level log messages have been downgraded to `INFO` or `DEBUG` to not clutter terminal output. + +### Bugfixes +- Fixed a bug where the `Created` field of `podman ps --format=json` was formatted as a string instead of an Unix timestamp (integer) ([#9315](https://github.com/containers/podman/issues/9315)). +- Fixed a bug where failing lookups of individual layers during the `podman images` command would cause the whole command to fail without printing output. +- Fixed a bug where `--cgroups=split` did not function properly on cgroups v1 systems. +- Fixed a bug where mounting a volume over an directory in the container that existed, but was empty, could fail ([#9393](https://github.com/containers/podman/issues/9393)). +- Fixed a bug where mounting a volume over a directory in the container that existed could copy the entirety of the container's rootfs, instead of just the directory mounted over, into the volume ([#9415](https://github.com/containers/podman/pull/9415)). +- Fixed a bug where Podman would treat the `--entrypoint=[""]` option to `podman run` and `podman create` as a literal empty string in the entrypoint, when instead it should have been ignored ([#9377](https://github.com/containers/podman/issues/9377)). +- Fixed a bug where Podman would set the `HOME` environment variable to `""` when the container ran as a user without an assigned home directory ([#9378](https://github.com/containers/podman/issues/9378)). +- Fixed a bug where specifying a pod infra image that had no tags (by using its ID) would cause `podman pod create` to panic ([#9374](https://github.com/containers/podman/issues/9374)). +- Fixed a bug where the `--runtime` option was not properly handled by the `podman build` command ([#9365](https://github.com/containers/podman/issues/9365)). +- Fixed a bug where Podman would incorrectly print an error message related to the remote API when the remote API was not in use and starting Podman failed. +- Fixed a bug where Podman would change ownership of a container's working directory, even if it already existed ([#9387](https://github.com/containers/podman/issues/9387)). +- Fixed a bug where the `podman generate systemd --new` command would incorrectly escape `%t` when generating the path for the PID file ([#9373](https://github.com/containers/podman/issues/9373)). +- Fixed a bug where Podman could, when run inside a Podman container with the host's containers/storage directory mounted into the container, erroneously detect a reboot and reset container state if the temporary directory was not also mounted in ([#9191](https://github.com/containers/podman/issues/9191)). +- Fixed a bug where some options of the `podman build` command (including but not limited to `--jobs`) were nonfunctional ([#9247](https://github.com/containers/podman/issues/9247)). + +### API +- Fixed a breaking change to the Libpod Wait API for Containers where the Conditions parameter changed type in Podman v3.0 ([#9351](https://github.com/containers/podman/issues/9351)). +- Fixed a bug where the Compat Create endpoint for Containers did not properly handle forwarded ports that did not specify a host port. +- Fixed a bug where the Libpod Wait endpoint for Containers could write duplicate headers after an error occurred. +- Fixed a bug where the Compat Create endpoint for Images would not pull images that already had a matching tag present locally, even if a more recent version was available at the registry ([#9232](https://github.com/containers/podman/issues/9232)). +- The Compat Create endpoint for Images has had its compatibility with Docker improved, allowing its use with the `docker-java` library. + +### Misc +- Updated Buildah to v1.19.4 +- Updated the containers/storage library to v1.24.6 + ## 3.0.0 ### Features - Podman now features initial support for Docker Compose. diff --git a/changelog.txt b/changelog.txt index 7b5fb1848..fdc018fa2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,50 @@ +- Changelog for v3.0.1 (2021-02-18): + * Final 3.0.1 release notes update + * Bump containers/buildah to v1.19.4 + * Implement missing arguments for podman build + * Fix swagger generation + * Updated Buildah to v1.19.4 + * Add release notes for v3.0.1 + * Don't switch on a single case + * Quote URL + * bindings: support simple types that implement fmt.Stringer interface + * API: fix libpod's container wait endpoint condition conversion + * Do not reset storage when running inside of a container + * Add missing early returns in compat API + * [NO TESTS NEEDED] Refactor generated code + * Enable more golangci-lint linters + * Enable whitespace linter + * Enable golint linter + * Enable stylecheck linter + * [NO TESTS NEEDED] Update linter + * apiv2: handle docker-java clients pulling + * Fix superfluous response.WriteHeader call in WaitContainerLibpod() + * fix dns resolution on ubuntu + * e2e: fix network alias test + * fix failing image e2e test + * Fix broken podman generate systemd --new with pods + * Don't chown workdir if it already exists + * correct startup error message + * fix create container: handle empty host port + * podman build: pass runtime to buildah + * images/create: always pull image + * Fix panic in pod creation + * do not set empty $HOME + * infra: downgrade warning to debug + * Ignore entrypoint=[\"\"] + * podman ps --format '{{ .Size }}' requires --size option + * Change source path resolution for volume copy-up + * Fix an issue where copyup could fail with ENOENT + * change ps Created to unix + * container ps json format miscue + * make layer-tree lookup errors non-fatal + * Bump c/storage to v1.24.6 + * utils: takes the longest path on cgroup v1 + * utils: create parent cgroups + * utils: ignore unified on cgroupv1 if not present + * utils: skip empty lines + * hardening flags for fedora rpmbuilds + - Changelog for v3.0.0 (2021-02-11): * Update release notes for v3.0 final * Rewrite copy-up to use buildah Copier diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 915ff63b6..3ea1a40d0 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -796,5 +796,4 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) { "Configure cgroup v2 (key=value)", ) _ = cmd.RegisterFlagCompletionFunc(cgroupConfFlagName, completion.AutocompleteNone) - } diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index d86a6d364..5fcbda0ce 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -222,7 +222,11 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup // publish for port, pbs := range cc.HostConfig.PortBindings { for _, pb := range pbs { - hostport, err := strconv.Atoi(pb.HostPort) + var hostport int + var err error + if pb.HostPort != "" { + hostport, err = strconv.Atoi(pb.HostPort) + } if err != nil { return nil, nil, err } @@ -268,7 +272,6 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, cgroup endpointsConfig := cc.NetworkingConfig.EndpointsConfig cniNetworks := make([]string, 0, len(endpointsConfig)) for netName, endpoint := range endpointsConfig { - cniNetworks = append(cniNetworks, netName) if endpoint == nil { diff --git a/cmd/podman/common/createparse.go b/cmd/podman/common/createparse.go index 3a69f11b6..140518cf7 100644 --- a/cmd/podman/common/createparse.go +++ b/cmd/podman/common/createparse.go @@ -26,5 +26,4 @@ func (c *ContainerCLIOpts) validate() error { return errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.ImageVolume) } return nil - } diff --git a/cmd/podman/containers/attach.go b/cmd/podman/containers/attach.go index f00c5378b..7c7d780bc 100644 --- a/cmd/podman/containers/attach.go +++ b/cmd/podman/containers/attach.go @@ -68,7 +68,6 @@ func init() { }) attachFlags(containerAttachCommand) validate.AddLatestFlag(containerAttachCommand, &attachOpts.Latest) - } func attach(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index 23baca70f..0c6cbab42 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -22,6 +22,7 @@ import ( "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/go-units" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -253,12 +254,12 @@ func ps(cmd *cobra.Command, _ []string) error { // responses will grow to the largest number of processes reported on, but will not thrash the gc var responses []psReporter for ; ; responses = responses[:0] { - if ctnrs, err := getResponses(); err != nil { + ctnrs, err := getResponses() + if err != nil { return err - } else { - for _, r := range ctnrs { - responses = append(responses, psReporter{r}) - } + } + for _, r := range ctnrs { + responses = append(responses, psReporter{r}) } tm.Clear() @@ -392,6 +393,11 @@ func (l psReporter) Command() string { // Size returns the rootfs and virtual sizes in human duration in // and output form (string) suitable for ps func (l psReporter) Size() string { + if l.ListContainer.Size == nil { + logrus.Errorf("Size format requires --size option") + return "" + } + virt := units.HumanSizeWithPrecision(float64(l.ListContainer.Size.RootFsSize), 3) s := units.HumanSizeWithPrecision(float64(l.ListContainer.Size.RwSize), 3) return fmt.Sprintf("%s (virtual %s)", s, virt) diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go index 49c0be88e..61bd84219 100644 --- a/cmd/podman/containers/restore.go +++ b/cmd/podman/containers/restore.go @@ -118,5 +118,4 @@ func restore(_ *cobra.Command, args []string) error { } } return errs.PrintErrors() - } diff --git a/cmd/podman/containers/wait.go b/cmd/podman/containers/wait.go index 7a531b98a..7831ef1c9 100644 --- a/cmd/podman/containers/wait.go +++ b/cmd/podman/containers/wait.go @@ -56,7 +56,6 @@ func waitFlags(cmd *cobra.Command) { conditionFlagName := "condition" flags.StringVar(&waitCondition, conditionFlagName, "stopped", "Condition to wait on") _ = cmd.RegisterFlagCompletionFunc(conditionFlagName, common.AutocompleteWaitCondition) - } func init() { diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go index f9099d3b8..7b2d9ebb7 100644 --- a/cmd/podman/generate/systemd.go +++ b/cmd/podman/generate/systemd.go @@ -128,7 +128,6 @@ func systemd(cmd *cobra.Command, args []string) error { default: return errors.Errorf("unknown --format argument: %s", format) } - } func printDefault(units map[string]string) error { diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index a35fea442..abd3ced5b 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -1,9 +1,11 @@ package images import ( + "io" "os" "path/filepath" "strings" + "time" "github.com/containers/buildah" "github.com/containers/buildah/imagebuildah" @@ -11,6 +13,8 @@ import ( "github.com/containers/buildah/pkg/parse" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" + encconfig "github.com/containers/ocicrypt/config" + enchelpers "github.com/containers/ocicrypt/helpers" "github.com/containers/podman/v2/cmd/podman/common" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" @@ -78,7 +82,8 @@ func useLayers() string { func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, + Command: buildCmd, }) buildFlags(buildCmd) @@ -151,8 +156,21 @@ func buildFlags(cmd *cobra.Command) { // Add the completion functions fromAndBudFlagsCompletions := buildahCLI.GetFromAndBudFlagsCompletions() completion.CompleteCommandFlags(cmd, fromAndBudFlagsCompletions) - _ = flags.MarkHidden("signature-policy") flags.SetNormalizeFunc(buildahCLI.AliasFlags) + if registry.IsRemote() { + flag = flags.Lookup("isolation") + buildOpts.Isolation = buildah.OCI + if err := flag.Value.Set(buildah.OCI); err != nil { + logrus.Errorf("unable to set --isolation to %v: %v", buildah.OCI, err) + } + flag.DefValue = buildah.OCI + _ = flags.MarkHidden("disable-content-trust") + _ = flags.MarkHidden("cache-from") + _ = flags.MarkHidden("sign-by") + _ = flags.MarkHidden("signature-policy") + _ = flags.MarkHidden("tls-verify") + _ = flags.MarkHidden("compress") + } } // build executes the build command. @@ -246,7 +264,18 @@ func build(cmd *cobra.Command, args []string) error { return err } - _, err = registry.ImageEngine().Build(registry.GetContext(), containerFiles, *apiBuildOpts) + report, err := registry.ImageEngine().Build(registry.GetContext(), containerFiles, *apiBuildOpts) + + if cmd.Flag("iidfile").Changed { + f, err := os.Create(buildOpts.Iidfile) + if err != nil { + return err + } + if _, err := f.WriteString("sha256:" + report.ID); err != nil { + return err + } + } + return err } @@ -308,6 +337,10 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil flags.Layers = false } + var stdin io.Reader + if flags.Stdin { + stdin = os.Stdin + } var stdout, stderr, reporter *os.File stdout = os.Stdout stderr = os.Stderr @@ -402,10 +435,21 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil runtimeFlags = append(runtimeFlags, "--systemd-cgroup") } + imageOS, arch, err := parse.PlatformFromOptions(c) + if err != nil { + return nil, err + } + + decConfig, err := getDecryptConfig(flags.DecryptionKeys) + if err != nil { + return nil, errors.Wrapf(err, "unable to obtain decrypt config") + } + opts := imagebuildah.BuildOptions{ AddCapabilities: flags.CapAdd, AdditionalTags: tags, Annotations: flags.Annotation, + Architecture: arch, Args: args, BlobDirectory: flags.BlobCache, CNIConfigDir: flags.CNIConfigDir, @@ -433,17 +477,25 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil DropCapabilities: flags.CapDrop, Err: stderr, ForceRmIntermediateCtrs: flags.ForceRm, + From: flags.From, IDMappingOptions: idmappingOptions, - IIDFile: flags.Iidfile, + In: stdin, Isolation: isolation, + Jobs: &flags.Jobs, Labels: flags.Label, Layers: flags.Layers, + LogRusage: flags.LogRusage, + Manifest: flags.Manifest, + MaxPullPushRetries: 3, NamespaceOptions: nsValues, NoCache: flags.NoCache, + OS: imageOS, + OciDecryptConfig: decConfig, Out: stdout, Output: output, OutputFormat: format, PullPolicy: pullPolicy, + PullPushRetryDelay: 2 * time.Second, Quiet: flags.Quiet, RemoveIntermediateCtrs: flags.Rm, ReportWriter: reporter, @@ -459,3 +511,18 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil return &entities.BuildOptions{BuildOptions: opts}, nil } + +func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) { + decConfig := &encconfig.DecryptConfig{} + if len(decryptionKeys) > 0 { + // decryption + dcc, err := enchelpers.CreateCryptoConfig([]string{}, decryptionKeys) + if err != nil { + return nil, errors.Wrapf(err, "invalid decryption keys") + } + cc := encconfig.CombineCryptoConfigs([]encconfig.CryptoConfig{dcc}) + decConfig = cc.DecryptConfig + } + + return decConfig, nil +} diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go index 8a7951923..65486e3ba 100644 --- a/cmd/podman/images/list.go +++ b/cmd/podman/images/list.go @@ -275,7 +275,6 @@ func tokenRepoTag(ref string) (string, string, error) { } return name, tag, nil - } func sortFunc(key string, data []imageReporter) func(i, j int) bool { diff --git a/cmd/podman/images/prune.go b/cmd/podman/images/prune.go index 268a68681..8ded8d352 100644 --- a/cmd/podman/images/prune.go +++ b/cmd/podman/images/prune.go @@ -48,7 +48,6 @@ func init() { flags.StringArrayVar(&filter, filterFlagName, []string{}, "Provide filter values (e.g. 'label=<key>=<value>')") //TODO: add completion for filters _ = pruneCmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone) - } func prune(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/images/pull.go b/cmd/podman/images/pull.go index fe92baebe..3b2595757 100644 --- a/cmd/podman/images/pull.go +++ b/cmd/podman/images/pull.go @@ -110,11 +110,9 @@ func pullFlags(cmd *cobra.Command) { _ = cmd.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault) if !registry.IsRemote() { - certDirFlagName := "cert-dir" flags.StringVar(&pullOptions.CertDir, certDirFlagName, "", "`Pathname` of a directory containing TLS certificates and keys") _ = cmd.RegisterFlagCompletionFunc(certDirFlagName, completion.AutocompleteDefault) - } _ = flags.MarkHidden("signature-policy") } diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go index c8ea4b04a..b8274cfce 100644 --- a/cmd/podman/images/search.go +++ b/cmd/podman/images/search.go @@ -156,12 +156,12 @@ func imageSearch(cmd *cobra.Command, args []string) error { return errors.Errorf("filters are not applicable to list tags result") } if report.IsJSON(searchOptions.Format) { - listTagsEntries := buildListTagsJson(searchReport) - return printJson(listTagsEntries) + listTagsEntries := buildListTagsJSON(searchReport) + return printArbitraryJSON(listTagsEntries) } row = "{{.Name}}\t{{.Tag}}\n" case report.IsJSON(searchOptions.Format): - return printJson(searchReport) + return printArbitraryJSON(searchReport) case cmd.Flags().Changed("format"): renderHeaders = parse.HasTable(searchOptions.Format) row = report.NormalizeFormat(searchOptions.Format) @@ -186,7 +186,7 @@ func imageSearch(cmd *cobra.Command, args []string) error { return tmpl.Execute(w, searchReport) } -func printJson(v interface{}) error { +func printArbitraryJSON(v interface{}) error { prettyJSON, err := json.MarshalIndent(v, "", " ") if err != nil { return err @@ -195,7 +195,7 @@ func printJson(v interface{}) error { return nil } -func buildListTagsJson(searchReport []entities.ImageSearchReport) []listEntryTag { +func buildListTagsJSON(searchReport []entities.ImageSearchReport) []listEntryTag { entries := []listEntryTag{} ReportLoop: diff --git a/cmd/podman/images/trust_show.go b/cmd/podman/images/trust_show.go index dc35dc6a1..89733a1aa 100644 --- a/cmd/podman/images/trust_show.go +++ b/cmd/podman/images/trust_show.go @@ -42,7 +42,6 @@ func init() { _ = showFlags.MarkHidden("policypath") showFlags.StringVar(&showTrustOptions.RegistryPath, "registrypath", "", "") _ = showFlags.MarkHidden("registrypath") - } func showTrust(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go index 1a091f111..d1cbe253f 100644 --- a/cmd/podman/networks/create.go +++ b/cmd/podman/networks/create.go @@ -80,7 +80,6 @@ func init() { Parent: networkCmd, }) networkCreateFlags(networkCreateCommand) - } func networkCreate(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/networks/inspect.go b/cmd/podman/networks/inspect.go index 671b0265f..bd9f76ea9 100644 --- a/cmd/podman/networks/inspect.go +++ b/cmd/podman/networks/inspect.go @@ -39,5 +39,4 @@ func init() { func networkInspect(_ *cobra.Command, args []string) error { inspectOpts.Type = inspect.NetworkType return inspect.Inspect(args, *inspectOpts) - } diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go index 16ae980dc..6f63e97cc 100644 --- a/cmd/podman/networks/list.go +++ b/cmd/podman/networks/list.go @@ -51,7 +51,6 @@ func networkListFlags(flags *pflag.FlagSet) { filterFlagName := "filter" flags.StringArrayVarP(&filters, filterFlagName, "f", nil, "Provide filter values (e.g. 'name=podman')") _ = networklistCommand.RegisterFlagCompletionFunc(filterFlagName, common.AutocompleteNetworkFilters) - } func init() { diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go index 4c44fa30f..511e208cf 100644 --- a/cmd/podman/play/kube.go +++ b/cmd/podman/play/kube.go @@ -77,7 +77,6 @@ func init() { _ = kubeCmd.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault) if !registry.IsRemote() { - certDirFlagName := "cert-dir" flags.StringVar(&kubeOptions.CertDir, certDirFlagName, "", "`Pathname` of a directory containing TLS certificates and keys") _ = kubeCmd.RegisterFlagCompletionFunc(certDirFlagName, completion.AutocompleteDefault) diff --git a/cmd/podman/pods/inspect.go b/cmd/podman/pods/inspect.go index e809be0c9..0fbb730ce 100644 --- a/cmd/podman/pods/inspect.go +++ b/cmd/podman/pods/inspect.go @@ -50,7 +50,6 @@ func init() { } func inspect(cmd *cobra.Command, args []string) error { - if len(args) < 1 && !inspectOptions.Latest { return errors.Errorf("you must provide the name or id of a running pod") } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 0ee530242..1f613a4c5 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -158,7 +158,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { // Prep the engines if _, err := registry.NewImageEngine(cmd, args); err != nil { - return errors.Wrapf(err, "Cannot connect to the Podman socket, make sure there is a Podman REST API service running.") + return err } if _, err := registry.NewContainerEngine(cmd, args); err != nil { return err diff --git a/cmd/podman/shell_completion_test.go b/cmd/podman/shell_completion_test.go index d2b500b09..3f6f56fbe 100644 --- a/cmd/podman/shell_completion_test.go +++ b/cmd/podman/shell_completion_test.go @@ -26,14 +26,11 @@ import ( ) func TestShellCompletionFunctions(t *testing.T) { - rootCmd := parseCommands() checkCommand(t, rootCmd) - } func checkCommand(t *testing.T, cmd *cobra.Command) { - if cmd.HasSubCommands() { for _, childCmd := range cmd.Commands() { checkCommand(t, childCmd) @@ -46,7 +43,6 @@ func checkCommand(t *testing.T, cmd *cobra.Command) { // loop over all local flags cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) { - // an error means that there is a completion function for this flag err := cmd.RegisterFlagCompletionFunc(flag.Name, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return nil, cobra.ShellCompDirectiveDefault diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go index a9eab24bb..68b244e35 100644 --- a/cmd/podman/system/df.go +++ b/cmd/podman/system/df.go @@ -50,7 +50,6 @@ func init() { formatFlagName := "format" flags.StringVar(&dfOptions.Format, formatFlagName, "", "Pretty-print images using a Go template") _ = dfSystemCommand.RegisterFlagCompletionFunc(formatFlagName, completion.AutocompleteNone) - } func df(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go index 5e96a654a..7ec08366e 100644 --- a/cmd/podman/system/prune.go +++ b/cmd/podman/system/prune.go @@ -51,7 +51,6 @@ func init() { filterFlagName := "filter" flags.StringArrayVar(&filters, filterFlagName, []string{}, "Provide filter values (e.g. 'label=<key>=<value>')") _ = pruneCommand.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone) - } func prune(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/renumber.go b/cmd/podman/system/renumber.go index b1683395f..37f9a5865 100644 --- a/cmd/podman/system/renumber.go +++ b/cmd/podman/system/renumber.go @@ -39,7 +39,6 @@ func init() { Command: renumberCommand, Parent: systemCmd, }) - } func renumber(cmd *cobra.Command, args []string) { // Shutdown all running engines, `renumber` will hijack all methods diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index 42ab5ece0..15bfd262e 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -42,7 +42,7 @@ Epoch: 99 %else Epoch: 0 %endif -Version: 3.0.1 +Version: 3.0.2 Release: #COMMITDATE#.git%{shortcommit0}%{?dist} Summary: Manage Pods, Containers and Container Images License: ASL 2.0 diff --git a/dependencies/dependencies.go b/dependencies/dependencies.go index b03ab149b..b1b0aee08 100644 --- a/dependencies/dependencies.go +++ b/dependencies/dependencies.go @@ -1,3 +1,5 @@ +// +build !linter + package dependencies import ( @@ -10,10 +10,11 @@ require ( github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/containernetworking/cni v0.8.1 github.com/containernetworking/plugins v0.9.0 - github.com/containers/buildah v1.19.2 + github.com/containers/buildah v1.19.4 github.com/containers/common v0.33.4 github.com/containers/conmon v2.0.20+incompatible github.com/containers/image/v5 v5.10.2 + github.com/containers/ocicrypt v1.0.3 github.com/containers/psgo v1.5.2 github.com/containers/storage v1.24.6 github.com/coreos/go-systemd/v22 v22.1.0 @@ -89,7 +89,6 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.0 h1:BT9lpgGoH4jw3lFC7Odz2prU5ruiYKcgAjMCbgybcKI= github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI= @@ -97,8 +96,8 @@ github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0= github.com/containernetworking/plugins v0.9.0 h1:c+1gegKhR7+d0Caum9pEHugZlyhXPOG6v3V6xJgIGCI= github.com/containernetworking/plugins v0.9.0/go.mod h1:dbWv4dI0QrBGuVgj+TuVQ6wJRZVOhrCQj91YyC92sxg= -github.com/containers/buildah v1.19.2 h1:1/ePUtinuqTPSwXiZXPyBJmik688l1e4SUZsoOv716w= -github.com/containers/buildah v1.19.2/go.mod h1:zUMKdtZu4rs6lgKHheKwo+wBlh5ZL+1+/5/IsaNTD74= +github.com/containers/buildah v1.19.4 h1:TygMnZAt8JCQ0i1APbSHfdn69B2vGvPoJKD+f6D6fuA= +github.com/containers/buildah v1.19.4/go.mod h1:PfK0EiB871UFD1CT8xNsKq60s7xw2pgSOEGICf+x6O8= github.com/containers/common v0.33.1 h1:XpDiq8Cta8+u1s4kpYSEWdB140ZmqgyIXfWkLqKx3z0= github.com/containers/common v0.33.1/go.mod h1:mjDo/NKeweL/onaspLhZ38WnHXaYmrELHclIdvSnYpY= github.com/containers/common v0.33.4 h1:f1jowItfo6xw0bZGZq8oE5dw1pBIkldqB0FqW+HHzG8= diff --git a/hack/golangci-lint.sh b/hack/golangci-lint.sh index 50bf29bb8..984fb42f2 100755 --- a/hack/golangci-lint.sh +++ b/hack/golangci-lint.sh @@ -5,7 +5,7 @@ set -e declare -A BUILD_TAGS # TODO: add systemd tag -BUILD_TAGS[default]="apparmor,seccomp,selinux" +BUILD_TAGS[default]="apparmor,seccomp,selinux,linter" BUILD_TAGS[abi]="${BUILD_TAGS[default]},!remoteclient" BUILD_TAGS[tunnel]="${BUILD_TAGS[default]},remote,remoteclient" diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index b2ee63b08..c9d214cd0 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -269,9 +269,9 @@ func (s *BoltState) Refresh() error { if err != nil { return err } - for _, execId := range toRemove { - if err := ctrExecBkt.Delete([]byte(execId)); err != nil { - return errors.Wrapf(err, "error removing exec session %s from container %s", execId, string(id)) + for _, execID := range toRemove { + if err := ctrExecBkt.Delete([]byte(execID)); err != nil { + return errors.Wrapf(err, "error removing exec session %s from container %s", execID, string(id)) } } } @@ -904,7 +904,6 @@ func (s *BoltState) ContainerInUse(ctr *Container) ([]string, error) { } return depCtrs, nil - } // AllContainers retrieves all the containers in the database @@ -962,7 +961,6 @@ func (s *BoltState) AllContainers() ([]*Container, error) { } return nil - }) }) if err != nil { @@ -2580,7 +2578,6 @@ func (s *BoltState) LookupVolume(name string) (*Volume, error) { } return volume, nil - } // HasVolume returns true if the given volume exists in the state, otherwise it returns false diff --git a/libpod/container.go b/libpod/container.go index ed7535bc8..5d90c31fd 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -1056,7 +1056,6 @@ func (c *Container) NetworkDisabled() (bool, error) { return container.NetworkDisabled() } return networkDisabled(c) - } func networkDisabled(c *Container) (bool, error) { diff --git a/libpod/container_exec.go b/libpod/container_exec.go index 5aee847e1..0d18b55ca 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -78,9 +78,11 @@ type ExecConfig struct { type ExecSession struct { // Id is the ID of the exec session. // Named somewhat strangely to not conflict with ID(). + // nolint:stylecheck,golint Id string `json:"id"` // ContainerId is the ID of the container this exec session belongs to. // Named somewhat strangely to not conflict with ContainerID(). + // nolint:stylecheck,golint ContainerId string `json:"containerId"` // State is the state of the exec session. diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index cc8b75472..412f7c6f1 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -789,7 +789,6 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named if c.config.UTSNsCtr != "" { utsMode = fmt.Sprintf("container:%s", c.config.UTSNsCtr) } else if ctrSpec.Linux != nil { - // Locate the spec's UTS namespace. // If there is none, it's uts=host. // If there is one and it has a path, it's "ns:". diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 15958471f..e02cb201e 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -264,7 +264,7 @@ func (c *Container) handleRestartPolicy(ctx context.Context) (_ bool, retErr err c.newContainerEvent(events.Restart) // Increment restart count - c.state.RestartCount += 1 + c.state.RestartCount++ logrus.Debugf("Container %s now on retry %d", c.ID(), c.state.RestartCount) if err := c.save(); err != nil { return false, err @@ -1615,6 +1615,17 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) if !srcStat.IsDir() { return vol, nil } + // Read contents, do not bother continuing if it's empty. Fixes + // a bizarre issue where something copier.Get will ENOENT on + // empty directories and sometimes it will not. + // RHBZ#1928643 + srcContents, err := ioutil.ReadDir(srcDir) + if err != nil { + return nil, errors.Wrapf(err, "error reading contents of source directory for copy up into volume %s", vol.Name()) + } + if len(srcContents) == 0 { + return vol, nil + } // Buildah Copier accepts a reader, so we'll need a pipe. reader, writer := io.Pipe() @@ -1631,7 +1642,7 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) getOptions := copier.GetOptions{ KeepDirectoryNames: false, } - errChan <- copier.Get(mountpoint, "", getOptions, []string{v.Dest + "/."}, writer) + errChan <- copier.Get(srcDir, "", getOptions, []string{"/."}, writer) }() // Copy, volume side: stream what we've written to the pipe, into diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 952cc42d1..1da8e6c38 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -21,6 +21,7 @@ import ( cnitypes "github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/plugins/pkg/ns" + "github.com/containers/buildah/pkg/chrootuser" "github.com/containers/buildah/pkg/overlay" "github.com/containers/common/pkg/apparmor" "github.com/containers/common/pkg/config" @@ -202,10 +203,17 @@ func (c *Container) resolveWorkDir() error { } logrus.Debugf("Workdir %q resolved to host path %q", workdir, resolvedWorkdir) - // No need to create it (e.g., `--workdir=/foo`), so let's make sure - // the path exists on the container. + st, err := os.Stat(resolvedWorkdir) + if err == nil { + if !st.IsDir() { + return errors.Errorf("workdir %q exists on container %s, but is not a directory", workdir, c.ID()) + } + return nil + } if !c.config.CreateWorkingDir { - if _, err := os.Stat(resolvedWorkdir); err != nil { + // No need to create it (e.g., `--workdir=/foo`), so let's make sure + // the path exists on the container. + if err != nil { if os.IsNotExist(err) { return errors.Errorf("workdir %q does not exist on container %s", workdir, c.ID()) } @@ -215,11 +223,6 @@ func (c *Container) resolveWorkDir() error { } return nil } - - // Ensure container entrypoint is created (if required). - rootUID := c.RootUID() - rootGID := c.RootGID() - if err := os.MkdirAll(resolvedWorkdir, 0755); err != nil { if os.IsExist(err) { return nil @@ -227,7 +230,12 @@ func (c *Container) resolveWorkDir() error { return errors.Wrapf(err, "error creating container %s workdir", c.ID()) } - if err := os.Chown(resolvedWorkdir, rootUID, rootGID); err != nil { + // Ensure container entrypoint is created (if required). + uid, gid, _, err := chrootuser.GetUser(c.state.Mountpoint, c.User()) + if err != nil { + return errors.Wrapf(err, "error looking up %s inside of the container %s", c.User(), c.ID()) + } + if err := os.Chown(resolvedWorkdir, int(uid), int(gid)); err != nil { return errors.Wrapf(err, "error chowning container %s workdir to container root", c.ID()) } @@ -457,7 +465,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { break } } - if !hasHomeSet { + if !hasHomeSet && execUser.Home != "" { c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", execUser.Home)) } @@ -520,14 +528,14 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { }} } for _, gid := range execUser.Sgids { - isGidAvailable := false + isGIDAvailable := false for _, m := range gidMappings { if gid >= m.ContainerID && gid < m.ContainerID+m.Size { - isGidAvailable = true + isGIDAvailable = true break } } - if isGidAvailable { + if isGIDAvailable { g.AddProcessAdditionalGid(uint32(gid)) } else { logrus.Warnf("additional gid=%d is not present in the user namespace, skip setting it", gid) @@ -1613,13 +1621,12 @@ func (c *Container) makeBindMounts() error { return errors.Wrapf(err, "error setting timezone for container %s", c.ID()) } c.state.BindMounts["/etc/localtime"] = localtimePath - } } // Make .containerenv if it does not exist if _, ok := c.state.BindMounts["/run/.containerenv"]; !ok { - var containerenv string + containerenv := c.runtime.graphRootMountedFlag(c.config.Spec.Mounts) isRootless := 0 if rootless.IsRootless() { isRootless = 1 @@ -1634,7 +1641,7 @@ id=%q image=%q imageid=%q rootless=%d -`, version.Version.String(), c.Name(), c.ID(), imageName, imageID, isRootless) +%s`, version.Version.String(), c.Name(), c.ID(), imageName, imageID, isRootless, containerenv) } containerenvPath, err := c.writeStringToRundir(".containerenv", containerenv) if err != nil { diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go index 805b3b947..5245314ae 100644 --- a/libpod/container_path_resolution.go +++ b/libpod/container_path_resolution.go @@ -18,7 +18,7 @@ import ( // mountPoint (e.g., via a mount or volume), the resolved root (e.g., container // mount, bind mount or volume) and the resolved path on the root (absolute to // the host). -func (container *Container) resolvePath(mountPoint string, containerPath string) (string, string, error) { +func (c *Container) resolvePath(mountPoint string, containerPath string) (string, string, error) { // Let's first make sure we have a path relative to the mount point. pathRelativeToContainerMountPoint := containerPath if !filepath.IsAbs(containerPath) { @@ -26,7 +26,7 @@ func (container *Container) resolvePath(mountPoint string, containerPath string) // container's working dir. To be extra careful, let's first // join the working dir with "/", and the add the containerPath // to it. - pathRelativeToContainerMountPoint = filepath.Join(filepath.Join("/", container.WorkingDir()), containerPath) + pathRelativeToContainerMountPoint = filepath.Join(filepath.Join("/", c.WorkingDir()), containerPath) } resolvedPathOnTheContainerMountPoint := filepath.Join(mountPoint, pathRelativeToContainerMountPoint) pathRelativeToContainerMountPoint = strings.TrimPrefix(pathRelativeToContainerMountPoint, mountPoint) @@ -43,7 +43,7 @@ func (container *Container) resolvePath(mountPoint string, containerPath string) searchPath := pathRelativeToContainerMountPoint for { - volume, err := findVolume(container, searchPath) + volume, err := findVolume(c, searchPath) if err != nil { return "", "", err } @@ -74,7 +74,7 @@ func (container *Container) resolvePath(mountPoint string, containerPath string) return mountPoint, absolutePathOnTheVolumeMount, nil } - if mount := findBindMount(container, searchPath); mount != nil { + if mount := findBindMount(c, searchPath); mount != nil { logrus.Debugf("Container path %q resolved to bind mount %q:%q on path %q", containerPath, mount.Source, mount.Destination, searchPath) // We found a matching bind mount for searchPath. We // now need to first find the relative path of our @@ -86,14 +86,12 @@ func (container *Container) resolvePath(mountPoint string, containerPath string) return "", "", err } return mount.Source, absolutePathOnTheBindMount, nil - } if searchPath == "/" { // Cannot go beyond "/", so we're done. break } - // Walk *down* the path (e.g., "/foo/bar/x" -> "/foo/bar"). searchPath = filepath.Dir(searchPath) } diff --git a/libpod/events/events.go b/libpod/events/events.go index aa0401b62..01ea6a386 100644 --- a/libpod/events/events.go +++ b/libpod/events/events.go @@ -97,7 +97,6 @@ func newEventFromJSONString(event string) (*Event, error) { return nil, err } return &e, nil - } // ToString converts a Type to a string diff --git a/libpod/events/filters.go b/libpod/events/filters.go index 62891d32c..26e1e10ba 100644 --- a/libpod/events/filters.go +++ b/libpod/events/filters.go @@ -86,7 +86,6 @@ func generateEventSinceOption(timeSince time.Time) func(e *Event) bool { func generateEventUntilOption(timeUntil time.Time) func(e *Event) bool { return func(e *Event) bool { return e.Time.Before(timeUntil) - } } diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go index 05ae3ce52..c5feabe66 100644 --- a/libpod/events/logfile.go +++ b/libpod/events/logfile.go @@ -39,7 +39,6 @@ func (e EventLogFile) Write(ee Event) error { return err } return nil - } // Reads from the log file diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go index f77075893..6c5becd5b 100644 --- a/libpod/healthcheck.go +++ b/libpod/healthcheck.go @@ -190,7 +190,7 @@ func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPerio } if !inStartPeriod { // increment failing streak - healthCheck.FailingStreak += 1 + healthCheck.FailingStreak++ // if failing streak > retries, then status to unhealthy if healthCheck.FailingStreak >= c.HealthCheckConfig().Retries { healthCheck.Status = define.HealthCheckUnhealthy diff --git a/libpod/image/image.go b/libpod/image/image.go index d732aecfe..8d8af0064 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -1688,7 +1688,6 @@ func (i *Image) GetConfigBlob(ctx context.Context) (*manifest.Schema2Image, erro return nil, errors.Wrapf(err, "unable to parse image blob for %s", i.ID()) } return &blob, nil - } // GetHealthCheck returns a HealthConfig for an image. This function only works with diff --git a/libpod/image/image_test.go b/libpod/image/image_test.go index 2704b8baf..8055ef7b1 100644 --- a/libpod/image/image_test.go +++ b/libpod/image/image_test.go @@ -66,7 +66,6 @@ func makeLocalMatrix(b, bg *Image) []localImageTest { l = append(l, busybox, busyboxGlibc) return l - } func TestMain(m *testing.M) { diff --git a/libpod/image/prune.go b/libpod/image/prune.go index 587c99333..6f026f630 100644 --- a/libpod/image/prune.go +++ b/libpod/image/prune.go @@ -52,7 +52,6 @@ func generatePruneFilterFuncs(filter, filterValue string) (ImageFilter, error) { } return false }, nil - } return nil, nil } @@ -170,7 +169,6 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ( Size: uint64(imgSize), }) } - } return preports, nil } diff --git a/libpod/image/utils.go b/libpod/image/utils.go index 5e7fed5c6..8882adcc1 100644 --- a/libpod/image/utils.go +++ b/libpod/image/utils.go @@ -45,7 +45,6 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er } } if len(candidates) == 0 { - return nil, errors.Wrapf(define.ErrNoSuchImage, "unable to find a name and tag match for %s in repotags", searchName) } @@ -75,9 +74,8 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er } if rwImageCnt > 1 { return nil, errors.Wrapf(define.ErrMultipleImages, "found multiple read/write images %s", strings.Join(keys, ",")) - } else { - return nil, errors.Wrapf(define.ErrMultipleImages, "found multiple read/only images %s", strings.Join(keys, ",")) } + return nil, errors.Wrapf(define.ErrMultipleImages, "found multiple read/only images %s", strings.Join(keys, ",")) } return candidates[0].image.image, nil } diff --git a/libpod/info.go b/libpod/info.go index 1b3550abd..f5bfb122e 100644 --- a/libpod/info.go +++ b/libpod/info.go @@ -222,11 +222,11 @@ func (r *Runtime) getContainerStoreInfo() (define.ContainerStore, error) { } switch state { case define.ContainerStateRunning: - running += 1 + running++ case define.ContainerStatePaused: - paused += 1 + paused++ default: - stopped += 1 + stopped++ } } cs.Paused = paused diff --git a/libpod/network/create.go b/libpod/network/create.go index 79bc47146..7088b5cd6 100644 --- a/libpod/network/create.go +++ b/libpod/network/create.go @@ -75,7 +75,6 @@ func validateBridgeOptions(options entities.NetworkCreateOptions) error { } return nil - } // parseMTU parses the mtu option diff --git a/libpod/network/create_test.go b/libpod/network/create_test.go index 0b828e635..017bf31fe 100644 --- a/libpod/network/create_test.go +++ b/libpod/network/create_test.go @@ -8,7 +8,6 @@ import ( ) func Test_validateBridgeOptions(t *testing.T) { - tests := []struct { name string subnet net.IPNet diff --git a/libpod/network/netconflist_test.go b/libpod/network/netconflist_test.go index 5ff733f0f..161764ed9 100644 --- a/libpod/network/netconflist_test.go +++ b/libpod/network/netconflist_test.go @@ -7,7 +7,6 @@ import ( ) func TestNewIPAMDefaultRoute(t *testing.T) { - tests := []struct { name string isIPv6 bool diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 9edea4fea..03edf7f02 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -480,9 +480,8 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error { if havePortMapping { if isSlirpHostForward { return r.setupRootlessPortMappingViaSlirp(ctr, cmd, apiSocket) - } else { - return r.setupRootlessPortMappingViaRLK(ctr, netnsPath) } + return r.setupRootlessPortMappingViaRLK(ctr, netnsPath) } return nil } diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 23bfb29d7..38ffba7d2 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1228,7 +1228,6 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio if options.Cwd != "" { pspec.Cwd = options.Cwd - } var addGroups []string @@ -1798,5 +1797,4 @@ func httpAttachNonTerminalCopy(container *net.UnixConn, http *bufio.ReadWriter, return err } } - } diff --git a/libpod/oci_util.go b/libpod/oci_util.go index d40cf13bd..4ec050d6d 100644 --- a/libpod/oci_util.go +++ b/libpod/oci_util.go @@ -103,7 +103,6 @@ func bindPorts(ports []ocicni.PortMapping) ([]*os.File, error) { } default: return nil, fmt.Errorf("unknown protocol %s", i.Protocol) - } } return files, nil diff --git a/libpod/options.go b/libpod/options.go index 20f62ee37..b6c8a5c3f 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1108,7 +1108,6 @@ func WithLogTag(tag string) CtrCreateOption { return nil } - } // WithCgroupsMode disables the creation of CGroups for the conmon process. @@ -1130,7 +1129,6 @@ func WithCgroupsMode(mode string) CtrCreateOption { return nil } - } // WithCgroupParent sets the Cgroup Parent of the new container. @@ -1429,7 +1427,6 @@ func WithOverlayVolumes(volumes []*ContainerOverlayVolume) CtrCreateOption { } for _, vol := range volumes { - ctr.config.OverlayVolumes = append(ctr.config.OverlayVolumes, &ContainerOverlayVolume{ Dest: vol.Dest, Source: vol.Source, diff --git a/libpod/plugin/volume_api.go b/libpod/plugin/volume_api.go index c5dec651c..79aebed43 100644 --- a/libpod/plugin/volume_api.go +++ b/libpod/plugin/volume_api.go @@ -241,9 +241,8 @@ func (p *VolumePlugin) makeErrorResponse(err, endpoint, volName string) error { } if volName != "" { return errors.Wrapf(errors.New(err), "error on %s on volume %s in volume plugin %s", endpoint, volName, p.Name) - } else { - return errors.Wrapf(errors.New(err), "error on %s in volume plugin %s", endpoint, p.Name) } + return errors.Wrapf(errors.New(err), "error on %s in volume plugin %s", endpoint, p.Name) } // Handle error responses from plugin diff --git a/libpod/reset.go b/libpod/reset.go index 24efeed40..3346f9d3f 100644 --- a/libpod/reset.go +++ b/libpod/reset.go @@ -16,7 +16,6 @@ import ( // Reset removes all storage func (r *Runtime) Reset(ctx context.Context) error { - pods, err := r.GetAllPods() if err != nil { return err diff --git a/libpod/runtime.go b/libpod/runtime.go index 0dc220b52..7726a1f8e 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1,6 +1,7 @@ package libpod import ( + "bufio" "context" "fmt" "os" @@ -26,6 +27,7 @@ import ( "github.com/containers/storage" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/docker/pkg/namesgenerator" + spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -146,7 +148,6 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error) // An error will be returned if the configuration file at the given path does // not exist or cannot be loaded func NewRuntimeFromConfig(ctx context.Context, userConfig *config.Config, options ...RuntimeOption) (*Runtime, error) { - return newRuntimeFromConfig(ctx, userConfig, options...) } @@ -382,7 +383,6 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { // Initialize remaining OCI runtimes for name, paths := range runtime.config.Engine.OCIRuntimes { - ociRuntime, err := newConmonOCIRuntime(name, paths, runtime.conmonPath, runtime.runtimeFlags, runtime.config) if err != nil { // Don't fatally error. @@ -437,7 +437,6 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { // Set up the CNI net plugin if !rootless.IsRootless() { - netPlugin, err := ocicni.InitCNI(runtime.config.Network.DefaultNetwork, runtime.config.Network.NetworkConfigDir, runtime.config.Network.CNIPluginDirs...) if err != nil { return errors.Wrapf(err, "error configuring CNI network plugin") @@ -484,7 +483,6 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) { if became { os.Exit(ret) } - } // If the file doesn't exist, we need to refresh the state // This will trigger on first use as well, but refreshing an @@ -626,9 +624,12 @@ func (r *Runtime) Shutdown(force bool) error { func (r *Runtime) refresh(alivePath string) error { logrus.Debugf("Podman detected system restart - performing state refresh") - // First clear the state in the database - if err := r.state.Refresh(); err != nil { - return err + // Clear state of database if not running in container + if !graphRootMounted() { + // First clear the state in the database + if err := r.state.Refresh(); err != nil { + return err + } } // Next refresh the state of all containers to recreate dirs and @@ -787,7 +788,6 @@ type DBConfig struct { // mergeDBConfig merges the configuration from the database. func (r *Runtime) mergeDBConfig(dbConfig *DBConfig) { - c := &r.config.Engine if !r.storageSet.RunRootSet && dbConfig.StorageTmp != "" { if r.storageConfig.RunRoot != dbConfig.StorageTmp && @@ -904,3 +904,29 @@ func (r *Runtime) getVolumePlugin(name string) (*plugin.VolumePlugin, error) { return plugin.GetVolumePlugin(name, pluginPath) } + +func graphRootMounted() bool { + f, err := os.OpenFile("/run/.containerenv", os.O_RDONLY, os.ModePerm) + if err != nil { + return false + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if scanner.Text() == "graphRootMounted=1" { + return true + } + } + return false +} + +func (r *Runtime) graphRootMountedFlag(mounts []spec.Mount) string { + root := r.store.GraphRoot() + for _, val := range mounts { + if strings.HasPrefix(root, val.Source) { + return "graphRootMounted=1" + } + } + return "" +} diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index d2bcd8db3..af6cc914e 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -1128,7 +1128,6 @@ func (r *Runtime) IsStorageContainerMounted(id string) (bool, string, error) { // StorageContainers returns a list of containers from containers/storage that // are not currently known to Podman. func (r *Runtime) StorageContainers() ([]storage.Container, error) { - if r.store == nil { return nil, define.ErrStoreNotInitialized } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index 2c5442bd2..fcc52b392 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -166,6 +166,11 @@ func (r *Runtime) newImageBuildCompleteEvent(idOrName string) { // Build adds the runtime to the imagebuildah call func (r *Runtime) Build(ctx context.Context, options imagebuildah.BuildOptions, dockerfiles ...string) (string, reference.Canonical, error) { + if options.Runtime == "" { + // Make sure that build containers use the same runtime as Podman (see #9365). + conf := util.DefaultContainerConfig() + options.Runtime = conf.Engine.OCIRuntime + } id, ref, err := imagebuildah.BuildDockerfiles(ctx, r.store, options, dockerfiles...) // Write event for build completion r.newImageBuildCompleteEvent(id) @@ -313,9 +318,8 @@ func (r *Runtime) LoadImageFromSingleImageArchive(ctx context.Context, writer io if err == nil && src != nil { if newImages, err := r.ImageRuntime().LoadFromArchiveReference(ctx, src, signaturePolicy, writer); err == nil { return getImageNames(newImages), nil - } else { - saveErr = err } + saveErr = err } } return "", errors.Wrapf(saveErr, "error pulling image") diff --git a/libpod/runtime_img_test.go b/libpod/runtime_img_test.go index 6ca4d900b..40d5860cf 100644 --- a/libpod/runtime_img_test.go +++ b/libpod/runtime_img_test.go @@ -26,7 +26,6 @@ func createTmpFile(content []byte) (string, error) { if _, err := tmpfile.Write(content); err != nil { return "", err - } if err := tmpfile.Close(); err != nil { return "", err diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 564851f4e..c6f268182 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -24,7 +24,6 @@ const ( ) func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawImageName, imgID string, config *v1.ImageConfig) (*Container, error) { - // Set up generator for infra container defaults g, err := generate.New("linux") if err != nil { @@ -226,7 +225,10 @@ func (r *Runtime) createInfraContainer(ctx context.Context, p *Pod) (*Container, if err != nil { return nil, err } - imageName := newImage.Names()[0] + imageName := "none" + if len(newImage.Names()) > 0 { + imageName = newImage.Names()[0] + } imageID := data.ID return r.makeInfraContainer(ctx, p, imageName, r.config.Engine.InfraImage, imageID, data.Config) diff --git a/libpod/volume_internal_linux.go b/libpod/volume_internal_linux.go index e184505e7..82c01be44 100644 --- a/libpod/volume_internal_linux.go +++ b/libpod/volume_internal_linux.go @@ -45,7 +45,7 @@ func (v *Volume) mount() error { // If the count is non-zero, the volume is already mounted. // Nothing to do. if v.state.MountCount > 0 { - v.state.MountCount += 1 + v.state.MountCount++ logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) return v.save() } @@ -67,7 +67,7 @@ func (v *Volume) mount() error { return err } - v.state.MountCount += 1 + v.state.MountCount++ v.state.MountPoint = mountPoint return v.save() } @@ -109,7 +109,7 @@ func (v *Volume) mount() error { logrus.Debugf("Mounted volume %s", v.Name()) // Increment the mount counter - v.state.MountCount += 1 + v.state.MountCount++ logrus.Debugf("Volume %s mount count now at %d", v.Name(), v.state.MountCount) return v.save() } @@ -152,7 +152,7 @@ func (v *Volume) unmount(force bool) error { } if !force { - v.state.MountCount -= 1 + v.state.MountCount-- } else { v.state.MountCount = 0 } diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go index 083c72ce8..55bd62f90 100644 --- a/pkg/api/handlers/compat/containers_archive.go +++ b/pkg/api/handlers/compat/containers_archive.go @@ -62,7 +62,7 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De w.Header().Add(copy.XDockerContainerPathStatHeader, statHeader) } - if errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == copy.ENOENT { + if errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == copy.ErrENOENT { // 404 is returned for an absent container and path. The // clients must deal with it accordingly. utils.Error(w, "Not found.", http.StatusNotFound, err) diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 6e85872b2..4a39e9563 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -47,6 +47,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { rtc, err := runtime.GetConfig() if err != nil { utils.Error(w, "unable to obtain runtime config", http.StatusInternalServerError, errors.Wrap(err, "unable to get runtime config")) + return } newImage, err := runtime.ImageRuntime().NewFromLocal(body.Config.Image) diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go index 82a74e419..7dad5f566 100644 --- a/pkg/api/handlers/compat/events.go +++ b/pkg/api/handlers/compat/events.go @@ -111,7 +111,6 @@ func GetEvents(w http.ResponseWriter, r *http.Request) { Until: query.Until, } errorChannel <- runtime.Events(r.Context(), readOpts) - }() var flush = func() {} diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 0ae0f3bcf..0d75d1a94 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/containers/buildah" - "github.com/containers/common/pkg/config" "github.com/containers/image/v5/manifest" "github.com/containers/podman/v2/libpod" image2 "github.com/containers/podman/v2/libpod/image" @@ -18,6 +17,7 @@ import ( "github.com/containers/podman/v2/pkg/api/handlers/utils" "github.com/containers/podman/v2/pkg/auth" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/util" "github.com/gorilla/schema" "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -202,7 +202,6 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { ProgressDetail: map[string]string{}, Id: iid, }) - } func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { @@ -237,16 +236,6 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { if sys := runtime.SystemContext(); sys != nil { registryOpts.DockerCertPath = sys.DockerCertPath } - rtc, err := runtime.GetConfig() - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) - return - } - pullPolicy, err := config.ValidatePullPolicy(rtc.Engine.PullPolicy) - if err != nil { - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) - return - } img, err := runtime.ImageRuntime().New(r.Context(), fromImage, "", // signature policy @@ -255,7 +244,7 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { ®istryOpts, image2.SigningOptions{}, nil, // label - pullPolicy, + util.PullImageAlways, ) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) @@ -265,12 +254,12 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) { // Success utils.WriteResponse(w, http.StatusOK, struct { Status string `json:"status"` - Error string `json:"error"` + Error string `json:"error,omitempty"` Progress string `json:"progress"` ProgressDetail map[string]string `json:"progressDetail"` Id string `json:"id"` // nolint }{ - Status: fmt.Sprintf("pulling image (%s) from %s", img.Tag, strings.Join(img.Names(), ", ")), + Status: fmt.Sprintf("pulling image (%s) from %s (Download complete)", img.Tag, strings.Join(img.Names(), ", ")), ProgressDetail: map[string]string{}, Id: img.ID(), }) diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 415ff85cd..0f27a090f 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -60,29 +60,39 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { }() query := struct { - BuildArgs string `schema:"buildargs"` - CacheFrom string `schema:"cachefrom"` - CpuPeriod uint64 `schema:"cpuperiod"` // nolint - CpuQuota int64 `schema:"cpuquota"` // nolint - CpuSetCpus string `schema:"cpusetcpus"` // nolint - CpuShares uint64 `schema:"cpushares"` // nolint - Dockerfile string `schema:"dockerfile"` - ExtraHosts string `schema:"extrahosts"` - ForceRm bool `schema:"forcerm"` - HTTPProxy bool `schema:"httpproxy"` - Labels string `schema:"labels"` - Layers bool `schema:"layers"` - MemSwap int64 `schema:"memswap"` - Memory int64 `schema:"memory"` - NetworkMode string `schema:"networkmode"` - NoCache bool `schema:"nocache"` - Outputs string `schema:"outputs"` - Platform string `schema:"platform"` - Pull bool `schema:"pull"` - Quiet bool `schema:"q"` - Registry string `schema:"registry"` - Remote string `schema:"remote"` - Rm bool `schema:"rm"` + AddHosts string `schema:"extrahosts"` + AdditionalCapabilities string `schema:"addcaps"` + Annotations string `schema:"annotations"` + BuildArgs string `schema:"buildargs"` + CacheFrom string `schema:"cachefrom"` + ConfigureNetwork int64 `schema:"networkmode"` + CpuPeriod uint64 `schema:"cpuperiod"` // nolint + CpuQuota int64 `schema:"cpuquota"` // nolint + CpuSetCpus string `schema:"cpusetcpus"` // nolint + CpuShares uint64 `schema:"cpushares"` // nolint + Devices string `schema:"devices"` + Dockerfile string `schema:"dockerfile"` + DropCapabilities string `schema:"dropcaps"` + ForceRm bool `schema:"forcerm"` + From string `schema:"from"` + HTTPProxy bool `schema:"httpproxy"` + Isolation int64 `schema:"isolation"` + Jobs uint64 `schema:"jobs"` // nolint + Labels string `schema:"labels"` + Layers bool `schema:"layers"` + LogRusage bool `schema:"rusage"` + Manifest string `schema:"manifest"` + MemSwap int64 `schema:"memswap"` + Memory int64 `schema:"memory"` + NoCache bool `schema:"nocache"` + OutputFormat string `schema:"outputformat"` + Platform string `schema:"platform"` + Pull bool `schema:"pull"` + Quiet bool `schema:"q"` + Registry string `schema:"registry"` + Rm bool `schema:"rm"` + //FIXME SecurityOpt in remote API is not handled + SecurityOpt string `schema:"securityopt"` ShmSize int `schema:"shmsize"` Squash bool `schema:"squash"` Tag []string `schema:"t"` @@ -101,14 +111,57 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { return } + // convert label formats + var addCaps = []string{} + if _, found := r.URL.Query()["addcaps"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.AdditionalCapabilities), &m); err != nil { + utils.BadRequest(w, "addcaps", query.AdditionalCapabilities, err) + return + } + addCaps = m + } + addhosts := []string{} + if _, found := r.URL.Query()["extrahosts"]; found { + if err := json.Unmarshal([]byte(query.AddHosts), &addhosts); err != nil { + utils.BadRequest(w, "extrahosts", query.AddHosts, err) + return + } + } + + // convert label formats + var dropCaps = []string{} + if _, found := r.URL.Query()["dropcaps"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.DropCapabilities), &m); err != nil { + utils.BadRequest(w, "dropcaps", query.DropCapabilities, err) + return + } + dropCaps = m + } + + // convert label formats + var devices = []string{} + if _, found := r.URL.Query()["devices"]; found { + var m = []string{} + if err := json.Unmarshal([]byte(query.DropCapabilities), &m); err != nil { + utils.BadRequest(w, "devices", query.DropCapabilities, err) + return + } + devices = m + } + var output string if len(query.Tag) > 0 { output = query.Tag[0] } - - var additionalNames []string + format := buildah.Dockerv2ImageManifest + if utils.IsLibpodRequest(r) { + format = query.OutputFormat + } + var additionalTags []string if len(query.Tag) > 1 { - additionalNames = query.Tag[1:] + additionalTags = query.Tag[1:] } var buildArgs = map[string]string{} @@ -120,17 +173,21 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { } // convert label formats + var annotations = []string{} + if _, found := r.URL.Query()["annotations"]; found { + if err := json.Unmarshal([]byte(query.Annotations), &annotations); err != nil { + utils.BadRequest(w, "annotations", query.Annotations, err) + return + } + } + + // convert label formats var labels = []string{} if _, found := r.URL.Query()["labels"]; found { - var m = map[string]string{} - if err := json.Unmarshal([]byte(query.Labels), &m); err != nil { + if err := json.Unmarshal([]byte(query.Labels), &labels); err != nil { utils.BadRequest(w, "labels", query.Labels, err) return } - - for k, v := range m { - labels = append(labels, k+"="+v) - } } pullPolicy := buildah.PullIfMissing @@ -160,27 +217,14 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { reporter := channel.NewWriter(make(chan []byte, 1)) defer reporter.Close() + buildOptions := imagebuildah.BuildOptions{ - ContextDirectory: contextDirectory, - PullPolicy: pullPolicy, - Registry: query.Registry, - IgnoreUnrecognizedInstructions: true, - Quiet: query.Quiet, - Layers: query.Layers, - Isolation: buildah.IsolationChroot, - Compression: archive.Gzip, - Args: buildArgs, - Output: output, - AdditionalTags: additionalNames, - Out: stdout, - Err: auxout, - ReportWriter: reporter, - OutputFormat: buildah.Dockerv2ImageManifest, - SystemContext: &types.SystemContext{ - AuthFilePath: authfile, - DockerAuthConfig: creds, - }, + AddCapabilities: addCaps, + AdditionalTags: additionalTags, + Annotations: annotations, + Args: buildArgs, CommonBuildOpts: &buildah.CommonBuildOptions{ + AddHost: addhosts, CPUPeriod: query.CpuPeriod, CPUQuota: query.CpuQuota, CPUShares: query.CpuShares, @@ -190,12 +234,37 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { MemorySwap: query.MemSwap, ShmSize: strconv.Itoa(query.ShmSize), }, - Squash: query.Squash, - Labels: labels, - NoCache: query.NoCache, - RemoveIntermediateCtrs: query.Rm, - ForceRmIntermediateCtrs: query.ForceRm, - Target: query.Target, + Compression: archive.Gzip, + ConfigureNetwork: buildah.NetworkConfigurationPolicy(query.ConfigureNetwork), + ContextDirectory: contextDirectory, + Devices: devices, + DropCapabilities: dropCaps, + Err: auxout, + ForceRmIntermediateCtrs: query.ForceRm, + From: query.From, + IgnoreUnrecognizedInstructions: true, + // FIXME, This is very broken. Buildah will only work with chroot + // Isolation: buildah.Isolation(query.Isolation), + Isolation: buildah.IsolationChroot, + + Labels: labels, + Layers: query.Layers, + Manifest: query.Manifest, + NoCache: query.NoCache, + Out: stdout, + Output: output, + OutputFormat: format, + PullPolicy: pullPolicy, + Quiet: query.Quiet, + Registry: query.Registry, + RemoveIntermediateCtrs: query.Rm, + ReportWriter: reporter, + Squash: query.Squash, + SystemContext: &types.SystemContext{ + AuthFilePath: authfile, + DockerAuthConfig: creds, + }, + Target: query.Target, } runtime := r.Context().Value("runtime").(*libpod.Runtime) diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go index 3b72798e4..174bc6234 100644 --- a/pkg/api/handlers/compat/images_history.go +++ b/pkg/api/handlers/compat/images_history.go @@ -17,7 +17,6 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) { if err != nil { utils.Error(w, "Something went wrong.", http.StatusNotFound, errors.Wrapf(err, "failed to find image %s", name)) return - } history, err := newImage.History(r.Context()) if err != nil { diff --git a/pkg/api/handlers/compat/images_remove.go b/pkg/api/handlers/compat/images_remove.go index 9731c521c..dd2d96bbb 100644 --- a/pkg/api/handlers/compat/images_remove.go +++ b/pkg/api/handlers/compat/images_remove.go @@ -54,5 +54,4 @@ func RemoveImage(w http.ResponseWriter, r *http.Request) { } utils.WriteResponse(w, http.StatusOK, response) - } diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index f0b922885..95cb06189 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -277,10 +277,10 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) { return } body := struct { - Id string + ID string `json:"Id"` Warning []string }{ - Id: net.ID, + ID: net.ID, } utils.WriteResponse(w, http.StatusCreated, body) } diff --git a/pkg/api/handlers/compat/system.go b/pkg/api/handlers/compat/system.go index e21ae160a..66b4236f9 100644 --- a/pkg/api/handlers/compat/system.go +++ b/pkg/api/handlers/compat/system.go @@ -19,6 +19,7 @@ func GetDiskUsage(w http.ResponseWriter, r *http.Request) { df, err := ic.SystemDf(r.Context(), options) if err != nil { utils.InternalServerError(w, err) + return } imgs := make([]*docker.ImageSummary, len(df.Images)) diff --git a/pkg/api/handlers/decoder.go b/pkg/api/handlers/decoder.go index 54087168a..123d325aa 100644 --- a/pkg/api/handlers/decoder.go +++ b/pkg/api/handlers/decoder.go @@ -6,6 +6,7 @@ import ( "syscall" "time" + "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/pkg/util" "github.com/gorilla/schema" "github.com/sirupsen/logrus" @@ -19,6 +20,7 @@ func NewAPIDecoder() *schema.Decoder { d.IgnoreUnknownKeys(true) d.RegisterConverter(map[string][]string{}, convertURLValuesString) d.RegisterConverter(time.Time{}, convertTimeString) + d.RegisterConverter(define.ContainerStatus(0), convertContainerStatusString) var Signal syscall.Signal d.RegisterConverter(Signal, convertSignal) @@ -46,6 +48,19 @@ func convertURLValuesString(query string) reflect.Value { return reflect.ValueOf(f) } +func convertContainerStatusString(query string) reflect.Value { + result, err := define.StringToContainerStatus(query) + if err != nil { + logrus.Infof("convertContainerStatusString: Failed to parse %s: %s", query, err.Error()) + + // We return nil here instead of result because reflect.ValueOf().IsValid() will be true + // in github.com/gorilla/schema's decoder, which means there's no parsing error + return reflect.ValueOf(nil) + } + + return reflect.ValueOf(result) +} + // isZero() can be used to determine if parsing failed. func convertTimeString(query string) reflect.Value { var ( diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index 619cbfd8b..4e79e4a42 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -48,7 +48,6 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) { } utils.InternalServerError(w, err) return - } if report.Value { utils.WriteResponse(w, http.StatusNoContent, "") @@ -162,7 +161,6 @@ func UnmountContainer(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) } utils.WriteResponse(w, http.StatusNoContent, "") - } func MountContainer(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) @@ -361,7 +359,6 @@ func ShouldRestart(w http.ResponseWriter, r *http.Request) { } utils.InternalServerError(w, err) return - } if report.Value { utils.WriteResponse(w, http.StatusNoContent, "") diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 97cd5a65e..efc2b53b5 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -266,7 +266,6 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { if len(query.References) > 1 && query.Format != define.V2s2Archive { utils.Error(w, "unsupported format", http.StatusInternalServerError, errors.Errorf("multi-image archives must use format of %s", define.V2s2Archive)) return - } switch query.Format { @@ -445,7 +444,6 @@ func PushImage(w http.ResponseWriter, r *http.Request) { if authconf != nil { username = authconf.Username password = authconf.Password - } options := entities.ImagePushOptions{ Authfile: authfile, diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go index 8511e2733..92279fcc8 100644 --- a/pkg/api/handlers/libpod/networks.go +++ b/pkg/api/handlers/libpod/networks.go @@ -42,7 +42,6 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) { return } utils.WriteResponse(w, http.StatusOK, report) - } func ListNetworks(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) diff --git a/pkg/api/handlers/swagger/swagger.go b/pkg/api/handlers/swagger/swagger.go index 22670d795..32f041dd3 100644 --- a/pkg/api/handlers/swagger/swagger.go +++ b/pkg/api/handlers/swagger/swagger.go @@ -1,7 +1,6 @@ package swagger import ( - "github.com/containers/podman/v2/libpod" "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/libpod/image" "github.com/containers/podman/v2/pkg/api/handlers" @@ -166,7 +165,7 @@ type swagInspectPodResponse struct { type swagInspectVolumeResponse struct { // in:body Body struct { - libpod.InspectVolumeData + define.InspectVolumeData } } diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go index 518309a03..e79def6f3 100644 --- a/pkg/api/handlers/utils/containers.go +++ b/pkg/api/handlers/utils/containers.go @@ -105,6 +105,7 @@ func WaitContainerLibpod(w http.ResponseWriter, r *http.Request) { query := waitQueryLibpod{} if err := decoder.Decode(&query, r.URL.Query()); err != nil { Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return } if _, found := r.URL.Query()["interval"]; found { @@ -130,10 +131,9 @@ func WaitContainerLibpod(w http.ResponseWriter, r *http.Request) { if errors.Cause(err) == define.ErrNoSuchCtr { ContainerNotFound(w, name, err) return - } else { - InternalServerError(w, err) - return } + InternalServerError(w, err) + return } WriteResponse(w, http.StatusOK, strconv.Itoa(int(exitCode))) } @@ -141,7 +141,6 @@ func WaitContainerLibpod(w http.ResponseWriter, r *http.Request) { type containerWaitFn func(conditions ...define.ContainerStatus) (int32, error) func createContainerWaitFn(ctx context.Context, containerName string, interval time.Duration) containerWaitFn { - runtime := ctx.Value("runtime").(*libpod.Runtime) var containerEngine entities.ContainerEngine = &abi.ContainerEngine{Libpod: runtime} @@ -170,7 +169,6 @@ func isValidDockerCondition(cond string) bool { } func waitDockerCondition(ctx context.Context, containerName string, interval time.Duration, dockerCondition string) (int32, error) { - containerWait := createContainerWaitFn(ctx, containerName, interval) var err error @@ -200,9 +198,8 @@ func waitRemoved(ctrWait containerWaitFn) (int32, error) { code, err := ctrWait(define.ContainerStateUnknown) if err != nil && errors.Cause(err) == define.ErrNoSuchCtr { return code, nil - } else { - return code, err } + return code, err } func waitNextExit(ctrWait containerWaitFn) (int32, error) { diff --git a/pkg/api/server/register_ping.go b/pkg/api/server/register_ping.go index 446a12a68..0343d2608 100644 --- a/pkg/api/server/register_ping.go +++ b/pkg/api/server/register_ping.go @@ -8,7 +8,6 @@ import ( ) func (s *APIServer) registerPingHandlers(r *mux.Router) error { - r.Handle("/_ping", s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) r.Handle(VersionedPath("/_ping"), s.APIHandler(compat.Ping)).Methods(http.MethodGet, http.MethodHead) // swagger:operation GET /libpod/_ping libpod libpodPingGet diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index fcbf6fe39..9c1d87c4f 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -41,7 +41,6 @@ func GetCredentials(r *http.Request) (*types.DockerAuthConfig, string, HeaderAut case has(XRegistryAuthHeader): c, f, err := getAuthCredentials(r) return c, f, XRegistryAuthHeader, err - } return nil, "", "", nil } diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go index 7b26037eb..6ff072e75 100644 --- a/pkg/bindings/connection.go +++ b/pkg/bindings/connection.go @@ -124,7 +124,7 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string) ctx = context.WithValue(ctx, clientKey, &connection) if err := pingNewConnection(ctx); err != nil { - return nil, err + return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify that Podman REST API service is running") } return ctx, nil } diff --git a/pkg/bindings/containers/archive.go b/pkg/bindings/containers/archive.go index d1bbc0b95..18871cfd1 100644 --- a/pkg/bindings/containers/archive.go +++ b/pkg/bindings/containers/archive.go @@ -30,7 +30,7 @@ func Stat(ctx context.Context, nameOrID string, path string) (*entities.Containe var finalErr error if response.StatusCode == http.StatusNotFound { - finalErr = copy.ENOENT + finalErr = copy.ErrENOENT } else if response.StatusCode != http.StatusOK { finalErr = errors.New(response.Status) } diff --git a/pkg/bindings/containers/containers.go b/pkg/bindings/containers/containers.go index 8e644b712..c84595011 100644 --- a/pkg/bindings/containers/containers.go +++ b/pkg/bindings/containers/containers.go @@ -137,7 +137,6 @@ func Kill(ctx context.Context, nameOrID string, options *KillOptions) error { return err } return response.Process(nil) - } // Pause pauses a given container. The nameOrID can be a container name @@ -270,8 +269,8 @@ func Top(ctx context.Context, nameOrID string, options *TopOptions) ([]string, e } params := url.Values{} if options.Changed("Descriptors") { - ps_args := strings.Join(options.GetDescriptors(), ",") - params.Add("ps_args", ps_args) + psArgs := strings.Join(options.GetDescriptors(), ",") + params.Add("ps_args", psArgs) } response, err := conn.DoRequest(nil, http.MethodGet, "/containers/%s/top", params, nil, nameOrID) if err != nil { diff --git a/pkg/bindings/containers/types_attach_options.go b/pkg/bindings/containers/types_attach_options.go index ab5a1615c..e806d161b 100644 --- a/pkg/bindings/containers/types_attach_options.go +++ b/pkg/bindings/containers/types_attach_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *AttachOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *AttachOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithDetachKeys diff --git a/pkg/bindings/containers/types_checkpoint_options.go b/pkg/bindings/containers/types_checkpoint_options.go index d239c476f..edac04ec4 100644 --- a/pkg/bindings/containers/types_checkpoint_options.go +++ b/pkg/bindings/containers/types_checkpoint_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CheckpointOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CheckpointOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithExport diff --git a/pkg/bindings/containers/types_commit_options.go b/pkg/bindings/containers/types_commit_options.go index 061f16e25..f3e0a16fc 100644 --- a/pkg/bindings/containers/types_commit_options.go +++ b/pkg/bindings/containers/types_commit_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CommitOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CommitOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAuthor diff --git a/pkg/bindings/containers/types_create_options.go b/pkg/bindings/containers/types_create_options.go index 8cde11335..4ef3be2b4 100644 --- a/pkg/bindings/containers/types_create_options.go +++ b/pkg/bindings/containers/types_create_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CreateOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CreateOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_diff_options.go b/pkg/bindings/containers/types_diff_options.go index e912bf041..952e149e9 100644 --- a/pkg/bindings/containers/types_diff_options.go +++ b/pkg/bindings/containers/types_diff_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *DiffOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *DiffOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_execinspect_options.go b/pkg/bindings/containers/types_execinspect_options.go index b870db46b..2ceb41878 100644 --- a/pkg/bindings/containers/types_execinspect_options.go +++ b/pkg/bindings/containers/types_execinspect_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExecInspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExecInspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_execstart_options.go b/pkg/bindings/containers/types_execstart_options.go index 95f97b1d7..e5b73bc7b 100644 --- a/pkg/bindings/containers/types_execstart_options.go +++ b/pkg/bindings/containers/types_execstart_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExecStartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExecStartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_execstartandattach_options.go b/pkg/bindings/containers/types_execstartandattach_options.go index 1981c319a..1b9276c8c 100644 --- a/pkg/bindings/containers/types_execstartandattach_options.go +++ b/pkg/bindings/containers/types_execstartandattach_options.go @@ -4,12 +4,8 @@ import ( "bufio" "io" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -18,62 +14,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExecStartAndAttachOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExecStartAndAttachOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithOutputStream diff --git a/pkg/bindings/containers/types_exists_options.go b/pkg/bindings/containers/types_exists_options.go index a52777600..ee822ab88 100644 --- a/pkg/bindings/containers/types_exists_options.go +++ b/pkg/bindings/containers/types_exists_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExistsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExistsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithExternal diff --git a/pkg/bindings/containers/types_export_options.go b/pkg/bindings/containers/types_export_options.go index 3943a5a3b..03eac2bad 100644 --- a/pkg/bindings/containers/types_export_options.go +++ b/pkg/bindings/containers/types_export_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExportOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExportOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_healthcheck_options.go b/pkg/bindings/containers/types_healthcheck_options.go index a548232cd..ac6d67f63 100644 --- a/pkg/bindings/containers/types_healthcheck_options.go +++ b/pkg/bindings/containers/types_healthcheck_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *HealthCheckOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *HealthCheckOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_init_options.go b/pkg/bindings/containers/types_init_options.go index 92e8a6c17..7365bcd25 100644 --- a/pkg/bindings/containers/types_init_options.go +++ b/pkg/bindings/containers/types_init_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InitOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InitOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_inspect_options.go b/pkg/bindings/containers/types_inspect_options.go index fdb84bda8..fb3e70a9d 100644 --- a/pkg/bindings/containers/types_inspect_options.go +++ b/pkg/bindings/containers/types_inspect_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithSize diff --git a/pkg/bindings/containers/types_kill_options.go b/pkg/bindings/containers/types_kill_options.go index 45bd790a4..5acb0c67d 100644 --- a/pkg/bindings/containers/types_kill_options.go +++ b/pkg/bindings/containers/types_kill_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *KillOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *KillOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithSignal diff --git a/pkg/bindings/containers/types_list_options.go b/pkg/bindings/containers/types_list_options.go index 3293320ec..8e872c99e 100644 --- a/pkg/bindings/containers/types_list_options.go +++ b/pkg/bindings/containers/types_list_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ListOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ListOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/containers/types_log_options.go b/pkg/bindings/containers/types_log_options.go index e78eb7bd0..a69570d0e 100644 --- a/pkg/bindings/containers/types_log_options.go +++ b/pkg/bindings/containers/types_log_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *LogOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *LogOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFollow diff --git a/pkg/bindings/containers/types_mount_options.go b/pkg/bindings/containers/types_mount_options.go index cc8df1255..e5cc35307 100644 --- a/pkg/bindings/containers/types_mount_options.go +++ b/pkg/bindings/containers/types_mount_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *MountOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *MountOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_mountedcontainerpaths_options.go b/pkg/bindings/containers/types_mountedcontainerpaths_options.go index 78fa2fca0..f0536abaa 100644 --- a/pkg/bindings/containers/types_mountedcontainerpaths_options.go +++ b/pkg/bindings/containers/types_mountedcontainerpaths_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *MountedContainerPathsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *MountedContainerPathsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_pause_options.go b/pkg/bindings/containers/types_pause_options.go index 55f14bef0..8497a24a8 100644 --- a/pkg/bindings/containers/types_pause_options.go +++ b/pkg/bindings/containers/types_pause_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PauseOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PauseOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_prune_options.go b/pkg/bindings/containers/types_prune_options.go index 000c7c0bd..2ea963c97 100644 --- a/pkg/bindings/containers/types_prune_options.go +++ b/pkg/bindings/containers/types_prune_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PruneOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PruneOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/containers/types_remove_options.go b/pkg/bindings/containers/types_remove_options.go index dfb5367eb..b9dea71a1 100644 --- a/pkg/bindings/containers/types_remove_options.go +++ b/pkg/bindings/containers/types_remove_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithIgnore diff --git a/pkg/bindings/containers/types_rename_options.go b/pkg/bindings/containers/types_rename_options.go index f4f5d1426..c148f6730 100644 --- a/pkg/bindings/containers/types_rename_options.go +++ b/pkg/bindings/containers/types_rename_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RenameOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RenameOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithName diff --git a/pkg/bindings/containers/types_resizeexectty_options.go b/pkg/bindings/containers/types_resizeexectty_options.go index e63d965eb..256e5299b 100644 --- a/pkg/bindings/containers/types_resizeexectty_options.go +++ b/pkg/bindings/containers/types_resizeexectty_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ResizeExecTTYOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ResizeExecTTYOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithHeight diff --git a/pkg/bindings/containers/types_resizetty_options.go b/pkg/bindings/containers/types_resizetty_options.go index 3170f4053..4f2958ba0 100644 --- a/pkg/bindings/containers/types_resizetty_options.go +++ b/pkg/bindings/containers/types_resizetty_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ResizeTTYOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ResizeTTYOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithHeight diff --git a/pkg/bindings/containers/types_restart_options.go b/pkg/bindings/containers/types_restart_options.go index d59176e67..8c791ae67 100644 --- a/pkg/bindings/containers/types_restart_options.go +++ b/pkg/bindings/containers/types_restart_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RestartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RestartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithTimeout diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go index e9f14fc47..e0204a677 100644 --- a/pkg/bindings/containers/types_restore_options.go +++ b/pkg/bindings/containers/types_restore_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RestoreOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RestoreOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithIgnoreRootfs diff --git a/pkg/bindings/containers/types_shouldrestart_options.go b/pkg/bindings/containers/types_shouldrestart_options.go index 49f943460..b0aeff09c 100644 --- a/pkg/bindings/containers/types_shouldrestart_options.go +++ b/pkg/bindings/containers/types_shouldrestart_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ShouldRestartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ShouldRestartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_start_options.go b/pkg/bindings/containers/types_start_options.go index a0f0b3077..60e061c79 100644 --- a/pkg/bindings/containers/types_start_options.go +++ b/pkg/bindings/containers/types_start_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithDetachKeys diff --git a/pkg/bindings/containers/types_stats_options.go b/pkg/bindings/containers/types_stats_options.go index 79e35ba62..ce0fdfe87 100644 --- a/pkg/bindings/containers/types_stats_options.go +++ b/pkg/bindings/containers/types_stats_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StatsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StatsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithStream diff --git a/pkg/bindings/containers/types_stop_options.go b/pkg/bindings/containers/types_stop_options.go index f221b16e8..14ece3a43 100644 --- a/pkg/bindings/containers/types_stop_options.go +++ b/pkg/bindings/containers/types_stop_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StopOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StopOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithIgnore diff --git a/pkg/bindings/containers/types_top_options.go b/pkg/bindings/containers/types_top_options.go index 570dd4e90..0481abe9a 100644 --- a/pkg/bindings/containers/types_top_options.go +++ b/pkg/bindings/containers/types_top_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *TopOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *TopOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithDescriptors diff --git a/pkg/bindings/containers/types_unmount_options.go b/pkg/bindings/containers/types_unmount_options.go index 24249073e..c32747e3a 100644 --- a/pkg/bindings/containers/types_unmount_options.go +++ b/pkg/bindings/containers/types_unmount_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *UnmountOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *UnmountOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_unpause_options.go b/pkg/bindings/containers/types_unpause_options.go index 3b1d75001..5f17067af 100644 --- a/pkg/bindings/containers/types_unpause_options.go +++ b/pkg/bindings/containers/types_unpause_options.go @@ -2,12 +2,8 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *UnpauseOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *UnpauseOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/containers/types_wait_options.go b/pkg/bindings/containers/types_wait_options.go index a3f1e3b8c..42ee0c316 100644 --- a/pkg/bindings/containers/types_wait_options.go +++ b/pkg/bindings/containers/types_wait_options.go @@ -2,13 +2,9 @@ package containers import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/libpod/define" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -17,62 +13,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *WaitOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *WaitOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithCondition diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index e75ce898d..51ea487be 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -20,12 +20,12 @@ func handleError(data []byte) error { return e } -func (a APIResponse) Process(unmarshalInto interface{}) error { - data, err := ioutil.ReadAll(a.Response.Body) +func (h APIResponse) Process(unmarshalInto interface{}) error { + data, err := ioutil.ReadAll(h.Response.Body) if err != nil { return errors.Wrap(err, "unable to process API response") } - if a.IsSuccess() || a.IsRedirection() { + if h.IsSuccess() || h.IsRedirection() { if unmarshalInto != nil { return json.Unmarshal(data, unmarshalInto) } diff --git a/pkg/bindings/generate/types_kube_options.go b/pkg/bindings/generate/types_kube_options.go index 218d308e1..5d34f4bee 100644 --- a/pkg/bindings/generate/types_kube_options.go +++ b/pkg/bindings/generate/types_kube_options.go @@ -1,13 +1,9 @@ package generate import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *KubeOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *KubeOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithService diff --git a/pkg/bindings/generate/types_systemd_options.go b/pkg/bindings/generate/types_systemd_options.go index faf981d1b..dc7378888 100644 --- a/pkg/bindings/generate/types_systemd_options.go +++ b/pkg/bindings/generate/types_systemd_options.go @@ -1,13 +1,9 @@ package generate import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *SystemdOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *SystemdOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithUseName diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go index dad154166..fc06fedd9 100644 --- a/pkg/bindings/generator/generator.go +++ b/pkg/bindings/generator/generator.go @@ -27,81 +27,31 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *{{.StructName}}) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *{{.StructName}}) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } -` -var fieldTmpl = ` +{{range $field := .Fields}} // With{{.Name}} -func(o *{{.StructName}}) With{{.Name}}(value {{.Type}}) *{{.StructName}} { - v := {{.TypedValue}} - o.{{.Name}} = v +func(o *{{$field.StructName}}) With{{$field.Name}}(value {{$field.Type}}) *{{$field.StructName}} { + v := {{$field.TypedValue}} + o.{{$field.Name}} = v return o } // Get{{.Name}} -func(o *{{.StructName}}) Get{{.Name}}() {{.Type}} { - var {{.ZeroName}} {{.Type}} - if o.{{.Name}} == nil { - return {{.ZeroName}} +func(o *{{$field.StructName}}) Get{{$field.Name}}() {{$field.Type}} { + var {{$field.ZeroName}} {{$field.Type}} + if o.{{$field.Name}} == nil { + return {{$field.ZeroName}} } - return {{.TypedName}} + return {{$field.TypedName}} } +{{end}} ` type fieldStruct struct { @@ -145,20 +95,7 @@ func main() { out.Close() } }() - bodyStruct := struct { - PackageName string - Imports []string - Date string - StructName string - }{ - PackageName: pkg, - Imports: imports, - Date: time.Now().String(), - StructName: inputStructName, - } - body := template.Must(template.New("body").Parse(bodyTmpl)) - fields := template.Must(template.New("fields").Parse(fieldTmpl)) ast.Inspect(f, func(n ast.Node) bool { ref, refOK := n.(*ast.TypeSpec) if refOK { @@ -202,20 +139,28 @@ func main() { fieldStructs = append(fieldStructs, fStruct) } // for + bodyStruct := struct { + PackageName string + Imports []string + Date string + StructName string + Fields []fieldStruct + }{ + PackageName: pkg, + Imports: imports, + Date: time.Now().String(), + StructName: inputStructName, + Fields: fieldStructs, + } + + body := template.Must(template.New("body").Parse(bodyTmpl)) + // create the body if err := body.Execute(out, bodyStruct); err != nil { fmt.Println(err) os.Exit(1) } - // create with func from the struct fields - for _, fs := range fieldStructs { - if err := fields.Execute(out, fs); err != nil { - fmt.Println(err) - os.Exit(1) - } - } - // close out file if err := out.Close(); err != nil { fmt.Println(err) @@ -239,7 +184,6 @@ func main() { os.Exit(1) } } - } return true }) diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index 02765816f..8ea09b881 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -31,36 +31,31 @@ import ( func Build(ctx context.Context, containerFiles []string, options entities.BuildOptions) (*entities.BuildReport, error) { params := url.Values{} - if t := options.Output; len(t) > 0 { - params.Set("t", t) + if caps := options.AddCapabilities; len(caps) > 0 { + c, err := jsoniter.MarshalToString(caps) + if err != nil { + return nil, err + } + params.Add("addcaps", c) } + + if annotations := options.Annotations; len(annotations) > 0 { + l, err := jsoniter.MarshalToString(annotations) + if err != nil { + return nil, err + } + params.Set("annotations", l) + } + params.Add("t", options.Output) for _, tag := range options.AdditionalTags { params.Add("t", tag) } - if options.Quiet { - params.Set("q", "1") - } - if options.NoCache { - params.Set("nocache", "1") - } - if options.Layers { - params.Set("layers", "1") - } - // TODO cachefrom - if options.PullPolicy == buildah.PullAlways { - params.Set("pull", "1") - } - if options.RemoveIntermediateCtrs { - params.Set("rm", "1") - } - if options.ForceRmIntermediateCtrs { - params.Set("forcerm", "1") - } - if mem := options.CommonBuildOpts.Memory; mem > 0 { - params.Set("memory", strconv.Itoa(int(mem))) - } - if memSwap := options.CommonBuildOpts.MemorySwap; memSwap > 0 { - params.Set("memswap", strconv.Itoa(int(memSwap))) + if buildArgs := options.Args; len(buildArgs) > 0 { + bArgs, err := jsoniter.MarshalToString(buildArgs) + if err != nil { + return nil, err + } + params.Set("buildargs", bArgs) } if cpuShares := options.CommonBuildOpts.CPUShares; cpuShares > 0 { params.Set("cpushares", strconv.Itoa(int(cpuShares))) @@ -74,22 +69,38 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if cpuQuota := options.CommonBuildOpts.CPUQuota; cpuQuota > 0 { params.Set("cpuquota", strconv.Itoa(int(cpuQuota))) } - if buildArgs := options.Args; len(buildArgs) > 0 { - bArgs, err := jsoniter.MarshalToString(buildArgs) + params.Set("networkmode", strconv.Itoa(int(options.ConfigureNetwork))) + params.Set("outputformat", options.OutputFormat) + + if devices := options.Devices; len(devices) > 0 { + d, err := jsoniter.MarshalToString(devices) if err != nil { return nil, err } - params.Set("buildargs", bArgs) + params.Add("devices", d) } - if shmSize := options.CommonBuildOpts.ShmSize; len(shmSize) > 0 { - shmBytes, err := units.RAMInBytes(shmSize) + + if caps := options.DropCapabilities; len(caps) > 0 { + c, err := jsoniter.MarshalToString(caps) if err != nil { return nil, err } - params.Set("shmsize", strconv.Itoa(int(shmBytes))) + params.Add("dropcaps", c) } - if options.Squash { - params.Set("squash", "1") + + if options.ForceRmIntermediateCtrs { + params.Set("forcerm", "1") + } + if len(options.From) > 0 { + params.Set("from", options.From) + } + + params.Set("isolation", strconv.Itoa(int(options.Isolation))) + if options.CommonBuildOpts.HTTPProxy { + params.Set("httpproxy", "1") + } + if options.Jobs != nil { + params.Set("jobs", strconv.FormatUint(uint64(*options.Jobs), 10)) } if labels := options.Labels; len(labels) > 0 { l, err := jsoniter.MarshalToString(labels) @@ -98,10 +109,66 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO } params.Set("labels", l) } - if options.CommonBuildOpts.HTTPProxy { - params.Set("httpproxy", "1") + if options.Layers { + params.Set("layers", "1") + } + if options.LogRusage { + params.Set("rusage", "1") + } + if len(options.Manifest) > 0 { + params.Set("manifest", options.Manifest) + } + if memSwap := options.CommonBuildOpts.MemorySwap; memSwap > 0 { + params.Set("memswap", strconv.Itoa(int(memSwap))) + } + if mem := options.CommonBuildOpts.Memory; mem > 0 { + params.Set("memory", strconv.Itoa(int(mem))) + } + if options.NoCache { + params.Set("nocache", "1") + } + if t := options.Output; len(t) > 0 { + params.Set("output", t) + } + var platform string + if len(options.OS) > 0 { + platform = options.OS + } + if len(options.Architecture) > 0 { + if len(platform) == 0 { + platform = "linux" + } + platform += "/" + options.Architecture + } + if len(platform) > 0 { + params.Set("platform", platform) + } + if options.PullPolicy == buildah.PullAlways { + params.Set("pull", "1") + } + if options.Quiet { + params.Set("q", "1") + } + if options.RemoveIntermediateCtrs { + params.Set("rm", "1") + } + if hosts := options.CommonBuildOpts.AddHost; len(hosts) > 0 { + h, err := jsoniter.MarshalToString(hosts) + if err != nil { + return nil, err + } + params.Set("extrahosts", h) + } + if shmSize := options.CommonBuildOpts.ShmSize; len(shmSize) > 0 { + shmBytes, err := units.RAMInBytes(shmSize) + if err != nil { + return nil, err + } + params.Set("shmsize", strconv.Itoa(int(shmBytes))) + } + if options.Squash { + params.Set("squash", "1") } - var ( headers map[string]string err error @@ -124,19 +191,6 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO stdout = options.Out } - // TODO network? - - var platform string - if OS := options.OS; len(OS) > 0 { - platform += OS - } - if arch := options.Architecture; len(arch) > 0 { - platform += "/" + arch - } - if len(platform) > 0 { - params.Set("platform", platform) - } - entries := make([]string, len(containerFiles)) copy(entries, containerFiles) entries = append(entries, options.ContextDirectory) diff --git a/pkg/bindings/images/pull.go b/pkg/bindings/images/pull.go index 5669c704e..9149b7445 100644 --- a/pkg/bindings/images/pull.go +++ b/pkg/bindings/images/pull.go @@ -93,7 +93,6 @@ func Pull(ctx context.Context, rawImage string, options *PullOptions) ([]string, default: return images, errors.New("failed to parse pull results stream, unexpected input") } - } return images, mErr } diff --git a/pkg/bindings/images/types_diff_options.go b/pkg/bindings/images/types_diff_options.go index edfc7bfa2..ae4b4655b 100644 --- a/pkg/bindings/images/types_diff_options.go +++ b/pkg/bindings/images/types_diff_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *DiffOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *DiffOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/images/types_exists_options.go b/pkg/bindings/images/types_exists_options.go index 649be4862..9de1b9878 100644 --- a/pkg/bindings/images/types_exists_options.go +++ b/pkg/bindings/images/types_exists_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExistsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExistsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/images/types_export_options.go b/pkg/bindings/images/types_export_options.go index ebd053165..dcce565f6 100644 --- a/pkg/bindings/images/types_export_options.go +++ b/pkg/bindings/images/types_export_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExportOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExportOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithCompress diff --git a/pkg/bindings/images/types_get_options.go b/pkg/bindings/images/types_get_options.go index 33ebe2611..b9d00d82c 100644 --- a/pkg/bindings/images/types_get_options.go +++ b/pkg/bindings/images/types_get_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *GetOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *GetOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithSize diff --git a/pkg/bindings/images/types_history_options.go b/pkg/bindings/images/types_history_options.go index b2c37acea..e2cd43852 100644 --- a/pkg/bindings/images/types_history_options.go +++ b/pkg/bindings/images/types_history_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *HistoryOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *HistoryOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/images/types_import_options.go b/pkg/bindings/images/types_import_options.go index e2aed0866..ff409cc7c 100644 --- a/pkg/bindings/images/types_import_options.go +++ b/pkg/bindings/images/types_import_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ImportOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ImportOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithChanges diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go index e194474b9..38d1bde70 100644 --- a/pkg/bindings/images/types_list_options.go +++ b/pkg/bindings/images/types_list_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ListOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ListOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/images/types_load_options.go b/pkg/bindings/images/types_load_options.go index 7e15d4e03..d17e7cc10 100644 --- a/pkg/bindings/images/types_load_options.go +++ b/pkg/bindings/images/types_load_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *LoadOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *LoadOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithReference diff --git a/pkg/bindings/images/types_prune_options.go b/pkg/bindings/images/types_prune_options.go index f86676d53..deef211c1 100644 --- a/pkg/bindings/images/types_prune_options.go +++ b/pkg/bindings/images/types_prune_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PruneOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PruneOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/images/types_pull_options.go b/pkg/bindings/images/types_pull_options.go index 59e2b6354..2220ade26 100644 --- a/pkg/bindings/images/types_pull_options.go +++ b/pkg/bindings/images/types_pull_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PullOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PullOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAllTags diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go index ae946fcde..966bb11fe 100644 --- a/pkg/bindings/images/types_push_options.go +++ b/pkg/bindings/images/types_push_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PushOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PushOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/images/types_remove_options.go b/pkg/bindings/images/types_remove_options.go index d79186565..964fca265 100644 --- a/pkg/bindings/images/types_remove_options.go +++ b/pkg/bindings/images/types_remove_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/images/types_search_options.go b/pkg/bindings/images/types_search_options.go index a55c9ac89..1321d1910 100644 --- a/pkg/bindings/images/types_search_options.go +++ b/pkg/bindings/images/types_search_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *SearchOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *SearchOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAuthfile diff --git a/pkg/bindings/images/types_tag_options.go b/pkg/bindings/images/types_tag_options.go index b323ea41c..74977e10a 100644 --- a/pkg/bindings/images/types_tag_options.go +++ b/pkg/bindings/images/types_tag_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *TagOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *TagOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/images/types_tree_options.go b/pkg/bindings/images/types_tree_options.go index 8e1b16c5c..a07a3a647 100644 --- a/pkg/bindings/images/types_tree_options.go +++ b/pkg/bindings/images/types_tree_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *TreeOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *TreeOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithWhatRequires diff --git a/pkg/bindings/images/types_untag_options.go b/pkg/bindings/images/types_untag_options.go index b28670134..3f7ac4a5a 100644 --- a/pkg/bindings/images/types_untag_options.go +++ b/pkg/bindings/images/types_untag_options.go @@ -2,12 +2,8 @@ package images import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *UntagOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *UntagOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/manifests/types_add_options.go b/pkg/bindings/manifests/types_add_options.go index 61314c479..ae7e914b2 100644 --- a/pkg/bindings/manifests/types_add_options.go +++ b/pkg/bindings/manifests/types_add_options.go @@ -1,13 +1,9 @@ package manifests import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *AddOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *AddOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/manifests/types_create_options.go b/pkg/bindings/manifests/types_create_options.go index 4c7c1397a..a8e11b828 100644 --- a/pkg/bindings/manifests/types_create_options.go +++ b/pkg/bindings/manifests/types_create_options.go @@ -1,13 +1,9 @@ package manifests import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CreateOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CreateOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/manifests/types_inspect_options.go b/pkg/bindings/manifests/types_inspect_options.go index 0b82fc3cf..90be7ebe3 100644 --- a/pkg/bindings/manifests/types_inspect_options.go +++ b/pkg/bindings/manifests/types_inspect_options.go @@ -1,13 +1,9 @@ package manifests import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/manifests/types_remove_options.go b/pkg/bindings/manifests/types_remove_options.go index 6ed0fd329..612d72dac 100644 --- a/pkg/bindings/manifests/types_remove_options.go +++ b/pkg/bindings/manifests/types_remove_options.go @@ -1,13 +1,9 @@ package manifests import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/network/network.go b/pkg/bindings/network/network.go index 7cd251b0e..d747f9bd7 100644 --- a/pkg/bindings/network/network.go +++ b/pkg/bindings/network/network.go @@ -102,7 +102,7 @@ func List(ctx context.Context, options *ListOptions) ([]*entities.NetworkListRep } // Disconnect removes a container from a given network -func Disconnect(ctx context.Context, networkName string, ContainerNameOrId string, options *DisconnectOptions) error { +func Disconnect(ctx context.Context, networkName string, ContainerNameOrID string, options *DisconnectOptions) error { if options == nil { options = new(DisconnectOptions) } @@ -117,7 +117,7 @@ func Disconnect(ctx context.Context, networkName string, ContainerNameOrId strin Container string Force bool }{ - Container: ContainerNameOrId, + Container: ContainerNameOrID, } if force := options.GetForce(); options.Changed("Force") { disconnect.Force = force @@ -136,7 +136,7 @@ func Disconnect(ctx context.Context, networkName string, ContainerNameOrId strin } // Connect adds a container to a network -func Connect(ctx context.Context, networkName string, ContainerNameOrId string, options *ConnectOptions) error { +func Connect(ctx context.Context, networkName string, ContainerNameOrID string, options *ConnectOptions) error { if options == nil { options = new(ConnectOptions) } @@ -151,7 +151,7 @@ func Connect(ctx context.Context, networkName string, ContainerNameOrId string, Container string Aliases []string }{ - Container: ContainerNameOrId, + Container: ContainerNameOrID, } if aliases := options.GetAliases(); options.Changed("Aliases") { connect.Aliases = aliases diff --git a/pkg/bindings/network/types_connect_options.go b/pkg/bindings/network/types_connect_options.go index 4440bbed4..b3cad6164 100644 --- a/pkg/bindings/network/types_connect_options.go +++ b/pkg/bindings/network/types_connect_options.go @@ -2,12 +2,8 @@ package network import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ConnectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ConnectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAliases diff --git a/pkg/bindings/network/types_create_options.go b/pkg/bindings/network/types_create_options.go index 5fbdce93a..553c94ee5 100644 --- a/pkg/bindings/network/types_create_options.go +++ b/pkg/bindings/network/types_create_options.go @@ -3,12 +3,8 @@ package network import ( "net" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -17,62 +13,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CreateOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CreateOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithDisableDNS diff --git a/pkg/bindings/network/types_disconnect_options.go b/pkg/bindings/network/types_disconnect_options.go index 947f2f114..667da0d99 100644 --- a/pkg/bindings/network/types_disconnect_options.go +++ b/pkg/bindings/network/types_disconnect_options.go @@ -2,12 +2,8 @@ package network import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *DisconnectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *DisconnectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithForce diff --git a/pkg/bindings/network/types_inspect_options.go b/pkg/bindings/network/types_inspect_options.go index 144ccbfae..ce8f58e2e 100644 --- a/pkg/bindings/network/types_inspect_options.go +++ b/pkg/bindings/network/types_inspect_options.go @@ -2,12 +2,8 @@ package network import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/network/types_list_options.go b/pkg/bindings/network/types_list_options.go index 60632ce33..c16e4c05e 100644 --- a/pkg/bindings/network/types_list_options.go +++ b/pkg/bindings/network/types_list_options.go @@ -2,12 +2,8 @@ package network import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ListOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ListOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/network/types_remove_options.go b/pkg/bindings/network/types_remove_options.go index 4ad4a2301..8e4dca819 100644 --- a/pkg/bindings/network/types_remove_options.go +++ b/pkg/bindings/network/types_remove_options.go @@ -2,12 +2,8 @@ package network import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithForce diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go index ea3872aae..946c19b28 100644 --- a/pkg/bindings/play/types_kube_options.go +++ b/pkg/bindings/play/types_kube_options.go @@ -1,13 +1,9 @@ package play import ( - "errors" "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *KubeOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *KubeOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAuthfile diff --git a/pkg/bindings/pods/types_create_options.go b/pkg/bindings/pods/types_create_options.go index cfa29c6be..942f25629 100644 --- a/pkg/bindings/pods/types_create_options.go +++ b/pkg/bindings/pods/types_create_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CreateOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CreateOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_exists_options.go b/pkg/bindings/pods/types_exists_options.go index 6149ab1cc..11c6f9c05 100644 --- a/pkg/bindings/pods/types_exists_options.go +++ b/pkg/bindings/pods/types_exists_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ExistsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ExistsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_inspect_options.go b/pkg/bindings/pods/types_inspect_options.go index 281717ff1..172b1303c 100644 --- a/pkg/bindings/pods/types_inspect_options.go +++ b/pkg/bindings/pods/types_inspect_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_kill_options.go b/pkg/bindings/pods/types_kill_options.go index 4c310d50c..e350746db 100644 --- a/pkg/bindings/pods/types_kill_options.go +++ b/pkg/bindings/pods/types_kill_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *KillOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *KillOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithSignal diff --git a/pkg/bindings/pods/types_list_options.go b/pkg/bindings/pods/types_list_options.go index 20f3229e5..fcaeb7c1c 100644 --- a/pkg/bindings/pods/types_list_options.go +++ b/pkg/bindings/pods/types_list_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ListOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ListOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/pods/types_pause_options.go b/pkg/bindings/pods/types_pause_options.go index 0f0f5bd97..b5aee3984 100644 --- a/pkg/bindings/pods/types_pause_options.go +++ b/pkg/bindings/pods/types_pause_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PauseOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PauseOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_prune_options.go b/pkg/bindings/pods/types_prune_options.go index ef8aae17f..80019a2fd 100644 --- a/pkg/bindings/pods/types_prune_options.go +++ b/pkg/bindings/pods/types_prune_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PruneOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PruneOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_remove_options.go b/pkg/bindings/pods/types_remove_options.go index f51f67129..e129d1e29 100644 --- a/pkg/bindings/pods/types_remove_options.go +++ b/pkg/bindings/pods/types_remove_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithForce diff --git a/pkg/bindings/pods/types_restart_options.go b/pkg/bindings/pods/types_restart_options.go index ec05e9fc9..7b95b91a1 100644 --- a/pkg/bindings/pods/types_restart_options.go +++ b/pkg/bindings/pods/types_restart_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RestartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RestartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_start_options.go b/pkg/bindings/pods/types_start_options.go index ec9f5b1de..b0d574020 100644 --- a/pkg/bindings/pods/types_start_options.go +++ b/pkg/bindings/pods/types_start_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StartOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StartOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/pods/types_stats_options.go b/pkg/bindings/pods/types_stats_options.go index 8be7d175d..50a18bc6a 100644 --- a/pkg/bindings/pods/types_stats_options.go +++ b/pkg/bindings/pods/types_stats_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StatsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StatsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/pods/types_stop_options.go b/pkg/bindings/pods/types_stop_options.go index fa3577e72..f80d391c6 100644 --- a/pkg/bindings/pods/types_stop_options.go +++ b/pkg/bindings/pods/types_stop_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *StopOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *StopOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithTimeout diff --git a/pkg/bindings/pods/types_top_options.go b/pkg/bindings/pods/types_top_options.go index c3c701dad..7e05a7937 100644 --- a/pkg/bindings/pods/types_top_options.go +++ b/pkg/bindings/pods/types_top_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *TopOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *TopOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithDescriptors diff --git a/pkg/bindings/pods/types_unpause_options.go b/pkg/bindings/pods/types_unpause_options.go index 281f0ea8d..9575e3949 100644 --- a/pkg/bindings/pods/types_unpause_options.go +++ b/pkg/bindings/pods/types_unpause_options.go @@ -2,12 +2,8 @@ package pods import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *UnpauseOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *UnpauseOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/system/types_disk_options.go b/pkg/bindings/system/types_disk_options.go index 6f0c3735a..118d2e8d2 100644 --- a/pkg/bindings/system/types_disk_options.go +++ b/pkg/bindings/system/types_disk_options.go @@ -2,12 +2,8 @@ package system import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *DiskOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *DiskOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/system/types_events_options.go b/pkg/bindings/system/types_events_options.go index 401a9807e..f6717f38d 100644 --- a/pkg/bindings/system/types_events_options.go +++ b/pkg/bindings/system/types_events_options.go @@ -2,12 +2,8 @@ package system import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *EventsOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *EventsOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/system/types_info_options.go b/pkg/bindings/system/types_info_options.go index 7c07b5081..bc6c67282 100644 --- a/pkg/bindings/system/types_info_options.go +++ b/pkg/bindings/system/types_info_options.go @@ -2,12 +2,8 @@ package system import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InfoOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InfoOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/system/types_prune_options.go b/pkg/bindings/system/types_prune_options.go index c677ccca6..c08a9baf3 100644 --- a/pkg/bindings/system/types_prune_options.go +++ b/pkg/bindings/system/types_prune_options.go @@ -2,12 +2,8 @@ package system import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PruneOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PruneOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithAll diff --git a/pkg/bindings/system/types_version_options.go b/pkg/bindings/system/types_version_options.go index 60ebfced9..fa6956677 100644 --- a/pkg/bindings/system/types_version_options.go +++ b/pkg/bindings/system/types_version_options.go @@ -2,12 +2,8 @@ package system import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *VersionOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *VersionOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/util/util.go b/pkg/bindings/util/util.go index 403846355..c1961308e 100644 --- a/pkg/bindings/util/util.go +++ b/pkg/bindings/util/util.go @@ -1,19 +1,34 @@ package util import ( + "errors" + "fmt" + "net/url" "reflect" "strconv" + "strings" + + jsoniter "github.com/json-iterator/go" ) func IsSimpleType(f reflect.Value) bool { + if _, ok := f.Interface().(fmt.Stringer); ok { + return true + } + switch f.Kind() { case reflect.Bool, reflect.Int, reflect.Int64, reflect.Uint, reflect.Uint64, reflect.String: return true } + return false } func SimpleTypeToParam(f reflect.Value) string { + if s, ok := f.Interface().(fmt.Stringer); ok { + return s.String() + } + switch f.Kind() { case reflect.Bool: return strconv.FormatBool(f.Bool()) @@ -26,5 +41,62 @@ func SimpleTypeToParam(f reflect.Value) string { case reflect.String: return f.String() } + panic("the input parameter is not a simple type") } + +func Changed(o interface{}, fieldName string) bool { + r := reflect.ValueOf(o) + value := reflect.Indirect(r).FieldByName(fieldName) + return !value.IsNil() +} + +func ToParams(o interface{}) (url.Values, error) { + params := url.Values{} + if o == nil || reflect.ValueOf(o).IsNil() { + return params, nil + } + json := jsoniter.ConfigCompatibleWithStandardLibrary + s := reflect.ValueOf(o) + if reflect.Ptr == s.Kind() { + s = s.Elem() + } + sType := s.Type() + for i := 0; i < s.NumField(); i++ { + fieldName := sType.Field(i).Name + if !Changed(o, fieldName) { + continue + } + fieldName = strings.ToLower(fieldName) + f := s.Field(i) + if reflect.Ptr == f.Kind() { + f = f.Elem() + } + switch { + case IsSimpleType(f): + params.Set(fieldName, SimpleTypeToParam(f)) + case f.Kind() == reflect.Slice: + for i := 0; i < f.Len(); i++ { + elem := f.Index(i) + if IsSimpleType(elem) { + params.Add(fieldName, SimpleTypeToParam(elem)) + } else { + return nil, errors.New("slices must contain only simple types") + } + } + case f.Kind() == reflect.Map: + lowerCaseKeys := make(map[string][]string) + iter := f.MapRange() + for iter.Next() { + lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) + } + s, err := json.MarshalToString(lowerCaseKeys) + if err != nil { + return nil, err + } + + params.Set(fieldName, s) + } + } + return params, nil +} diff --git a/pkg/bindings/volumes/types_create_options.go b/pkg/bindings/volumes/types_create_options.go index 2254f8c13..45053e261 100644 --- a/pkg/bindings/volumes/types_create_options.go +++ b/pkg/bindings/volumes/types_create_options.go @@ -2,12 +2,8 @@ package volumes import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *CreateOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *CreateOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/volumes/types_inspect_options.go b/pkg/bindings/volumes/types_inspect_options.go index 51ac2d348..e6397a0d2 100644 --- a/pkg/bindings/volumes/types_inspect_options.go +++ b/pkg/bindings/volumes/types_inspect_options.go @@ -2,12 +2,8 @@ package volumes import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,60 +12,10 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *InspectOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *InspectOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } diff --git a/pkg/bindings/volumes/types_list_options.go b/pkg/bindings/volumes/types_list_options.go index c96e647b0..103515e99 100644 --- a/pkg/bindings/volumes/types_list_options.go +++ b/pkg/bindings/volumes/types_list_options.go @@ -2,12 +2,8 @@ package volumes import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *ListOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *ListOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/volumes/types_prune_options.go b/pkg/bindings/volumes/types_prune_options.go index 06d16b659..eb910e05d 100644 --- a/pkg/bindings/volumes/types_prune_options.go +++ b/pkg/bindings/volumes/types_prune_options.go @@ -2,12 +2,8 @@ package volumes import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *PruneOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *PruneOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithFilters diff --git a/pkg/bindings/volumes/types_remove_options.go b/pkg/bindings/volumes/types_remove_options.go index 4b0037234..30cb923c7 100644 --- a/pkg/bindings/volumes/types_remove_options.go +++ b/pkg/bindings/volumes/types_remove_options.go @@ -2,12 +2,8 @@ package volumes import ( "net/url" - "reflect" - "strings" "github.com/containers/podman/v2/pkg/bindings/util" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" ) /* @@ -16,62 +12,12 @@ This file is generated automatically by go generate. Do not edit. // Changed func (o *RemoveOptions) Changed(fieldName string) bool { - r := reflect.ValueOf(o) - value := reflect.Indirect(r).FieldByName(fieldName) - return !value.IsNil() + return util.Changed(o, fieldName) } // ToParams func (o *RemoveOptions) ToParams() (url.Values, error) { - params := url.Values{} - if o == nil { - return params, nil - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - s := reflect.ValueOf(o) - if reflect.Ptr == s.Kind() { - s = s.Elem() - } - sType := s.Type() - for i := 0; i < s.NumField(); i++ { - fieldName := sType.Field(i).Name - if !o.Changed(fieldName) { - continue - } - fieldName = strings.ToLower(fieldName) - f := s.Field(i) - if reflect.Ptr == f.Kind() { - f = f.Elem() - } - switch { - case util.IsSimpleType(f): - params.Set(fieldName, util.SimpleTypeToParam(f)) - case f.Kind() == reflect.Slice: - for i := 0; i < f.Len(); i++ { - elem := f.Index(i) - if util.IsSimpleType(elem) { - params.Add(fieldName, util.SimpleTypeToParam(elem)) - } else { - return nil, errors.New("slices must contain only simple types") - } - } - case f.Kind() == reflect.Map: - lowerCaseKeys := make(map[string][]string) - iter := f.MapRange() - for iter.Next() { - lowerCaseKeys[iter.Key().Interface().(string)] = iter.Value().Interface().([]string) - - } - s, err := json.MarshalToString(lowerCaseKeys) - if err != nil { - return nil, err - } - - params.Set(fieldName, s) - } - - } - return params, nil + return util.ToParams(o) } // WithForce diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go index a73187dc8..05223c2e1 100644 --- a/pkg/cgroups/cpu.go +++ b/pkg/cgroups/cpu.go @@ -155,7 +155,6 @@ func GetSystemCPUUsage() (uint64, error) { } total += v * 1000 } - } return total, nil } diff --git a/pkg/copy/fileinfo.go b/pkg/copy/fileinfo.go index ddb9b629c..b95bcd90c 100644 --- a/pkg/copy/fileinfo.go +++ b/pkg/copy/fileinfo.go @@ -16,9 +16,9 @@ import ( // base64 encoded JSON payload of stating a path in a container. const XDockerContainerPathStatHeader = "X-Docker-Container-Path-Stat" -// ENOENT mimics the stdlib's ENOENT and can be used to implement custom logic +// ErrENOENT mimics the stdlib's ErrENOENT and can be used to implement custom logic // while preserving the user-visible error message. -var ENOENT = errors.New("No such file or directory") +var ErrENOENT = errors.New("No such file or directory") // FileInfo describes a file or directory and is returned by // (*CopyItem).Stat(). @@ -70,7 +70,7 @@ func ResolveHostPath(path string) (*FileInfo, error) { statInfo, err := os.Stat(resolvedHostPath) if err != nil { if os.IsNotExist(err) { - return nil, ENOENT + return nil, ErrENOENT } return nil, err } diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go index b76bfcac7..95608f01b 100644 --- a/pkg/domain/entities/network.go +++ b/pkg/domain/entities/network.go @@ -31,6 +31,7 @@ type NetworkReloadOptions struct { // NetworkReloadReport describes the results of reloading a container network. type NetworkReloadReport struct { + // nolint:stylecheck,golint Id string Err error } diff --git a/pkg/domain/infra/abi/containers_stat.go b/pkg/domain/infra/abi/containers_stat.go index f3d0799a0..1844f4019 100644 --- a/pkg/domain/infra/abi/containers_stat.go +++ b/pkg/domain/infra/abi/containers_stat.go @@ -35,7 +35,7 @@ func (ic *ContainerEngine) containerStat(container *libpod.Container, containerM // ENOENT let's the API handlers return the correct status code // which is crucial for the remote client. if os.IsNotExist(err) || strings.Contains(statInfoErr.Error(), "o such file or directory") { - statInfoErr = copy.ENOENT + statInfoErr = copy.ErrENOENT } // If statInfo is nil, there's nothing we can do anymore. A // non-nil statInfo may indicate a symlink where we must have @@ -129,7 +129,7 @@ func secureStat(root string, path string) (*buildahCopiah.StatForItem, error) { stat, exists := globStats[0].Results[glob] // only one glob passed, so that's okay if !exists { - return nil, copy.ENOENT + return nil, copy.ErrENOENT } var statErr error diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index f2d0f2c39..fb01c72b6 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -40,10 +40,9 @@ func (ir *ImageEngine) Exists(_ context.Context, nameOrID string) (*entities.Boo if err != nil { if errors.Cause(err) == define.ErrMultipleImages { return &entities.BoolReport{Value: true}, nil - } else { - if errors.Cause(err) != define.ErrNoSuchImage { - return nil, err - } + } + if errors.Cause(err) != define.ErrNoSuchImage { + return nil, err } } return &entities.BoolReport{Value: err == nil}, nil @@ -270,7 +269,6 @@ func pull(ctx context.Context, runtime *image.Runtime, rawImage string, options } if _, isTagged := namedRef.(reference.Tagged); isTagged { return nil, errors.New("--all-tags requires a reference without a tag") - } systemContext := image.GetSystemContext("", options.Authfile, false) @@ -503,7 +501,6 @@ func (ir *ImageEngine) Config(_ context.Context) (*config.Config, error) { } func (ir *ImageEngine) Build(ctx context.Context, containerFiles []string, opts entities.BuildOptions) (*entities.BuildReport, error) { - id, _, err := ir.Libpod.Build(ctx, opts.BuildOptions, containerFiles...) if err != nil { return nil, err diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go index 139032ad6..e3cf20863 100644 --- a/pkg/domain/infra/abi/manifest.go +++ b/pkg/domain/infra/abi/manifest.go @@ -1,5 +1,3 @@ -// +build !remote - package abi import ( diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index 70c7104f1..35a84106f 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -60,7 +60,6 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, path string, options en default: return nil, errors.Errorf("invalid YAML kind: %q. [Pod|Deployment] are the only supported Kubernetes Kinds", kubeObject.Kind) } - } func (ic *ContainerEngine) playKubeDeployment(ctx context.Context, deploymentYAML *v1apps.Deployment, options entities.PlayKubeOptions) (*entities.PlayKubeReport, error) { diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index f29b98696..c68a12414 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -82,7 +82,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, cmd *cobra.Command) unitName := fmt.Sprintf("podman-%d.scope", os.Getpid()) if runsUnderSystemd || conf.Engine.CgroupManager == config.SystemdCgroupsManager { if err := utils.RunUnderSystemdScope(os.Getpid(), "user.slice", unitName); err != nil { - logrus.Warnf("Failed to add podman to systemd sandbox cgroup: %v", err) + logrus.Debugf("Failed to add podman to systemd sandbox cgroup: %v", err) } } } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index e9c513f8e..c2c282ef9 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -290,7 +290,6 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [ ctrs = append(ctrs, c) } } - } else { ctrs, err = getContainersByContext(ic.ClientCtx, false, false, namesOrIds) if err != nil { @@ -326,7 +325,6 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st ctrs = append(ctrs, c) } } - } else { ctrs, err = getContainersByContext(ic.ClientCtx, false, false, namesOrIds) if err != nil { @@ -570,7 +568,6 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri } // Start the container if it's not running already. if !ctrRunning { - err = containers.Start(ic.ClientCtx, name, new(containers.StartOptions).WithDetachKeys(options.DetachKeys)) if err != nil { if ctr.AutoRemove { diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go index 0a806d860..e40e27596 100644 --- a/pkg/domain/infra/tunnel/helpers.go +++ b/pkg/domain/infra/tunnel/helpers.go @@ -55,7 +55,6 @@ func getContainersByContext(contextWithConnection context.Context, all, ignore b found = true break } - } if !found && !ignore { @@ -107,7 +106,6 @@ func getPodsByContext(contextWithConnection context.Context, all bool, namesOrID found = true break } - } if !found { diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index 0fe2387d7..b5f09ab22 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -32,7 +32,6 @@ func (ir *ImageEngine) Remove(ctx context.Context, imagesArg []string, opts enti } func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions) ([]*entities.ImageSummary, error) { - filters := make(map[string][]string, len(opts.Filter)) for _, filter := range opts.Filter { f := strings.Split(filter, "=") @@ -350,17 +349,6 @@ func (ir *ImageEngine) Build(_ context.Context, containerFiles []string, opts en if err != nil { return nil, err } - // For remote clients, if the option for writing to a file was - // selected, we need to write to the *client's* filesystem. - if len(opts.IIDFile) > 0 { - f, err := os.Create(opts.IIDFile) - if err != nil { - return nil, err - } - if _, err := f.WriteString(report.ID); err != nil { - return nil, err - } - } return report, nil } diff --git a/pkg/lookup/lookup.go b/pkg/lookup/lookup.go index 8f241edf2..0b22a1974 100644 --- a/pkg/lookup/lookup.go +++ b/pkg/lookup/lookup.go @@ -66,7 +66,6 @@ func GetUserGroupInfo(containerMount, containerUser string, override *Overrides) // Gid: 0, // Home: "/", defaultExecUser = nil - } return user.GetExecUserPath(containerUser, defaultExecUser, passwdDest, groupDest) diff --git a/pkg/netns/netns_linux.go b/pkg/netns/netns_linux.go index 6817a3abd..95b50e073 100644 --- a/pkg/netns/netns_linux.go +++ b/pkg/netns/netns_linux.go @@ -51,7 +51,6 @@ func getNSRunDir() (string, error) { // NewNS creates a new persistent (bind-mounted) network namespace and returns // an object representing that namespace, without switching to it. func NewNS() (ns.NetNS, error) { - nsRunDir, err := getNSRunDir() if err != nil { return nil, err @@ -92,7 +91,6 @@ func NewNS() (ns.NetNS, error) { if err != nil { return nil, fmt.Errorf("mount --make-rshared %s failed: %q", nsRunDir, err) } - } nsName := fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index df35c0d6b..b5538efc3 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -61,9 +61,9 @@ var ( gidMapOnce sync.Once ) -// GetAvailableUidMap returns the UID mappings in the +// GetAvailableUIDMap returns the UID mappings in the // current user namespace. -func GetAvailableUidMap() ([]user.IDMap, error) { +func GetAvailableUIDMap() ([]user.IDMap, error) { uidMapOnce.Do(func() { var err error uidMap, err = user.ParseIDMapFile("/proc/self/uid_map") @@ -75,9 +75,9 @@ func GetAvailableUidMap() ([]user.IDMap, error) { return uidMap, uidMapError } -// GetAvailableGidMap returns the GID mappings in the +// GetAvailableGIDMap returns the GID mappings in the // current user namespace. -func GetAvailableGidMap() ([]user.IDMap, error) { +func GetAvailableGIDMap() ([]user.IDMap, error) { gidMapOnce.Do(func() { var err error gidMap, err = user.ParseIDMapFile("/proc/self/gid_map") @@ -92,11 +92,11 @@ func GetAvailableGidMap() ([]user.IDMap, error) { // GetAvailableIDMaps returns the UID and GID mappings in the // current user namespace. func GetAvailableIDMaps() ([]user.IDMap, []user.IDMap, error) { - u, err := GetAvailableUidMap() + u, err := GetAvailableUIDMap() if err != nil { return nil, nil, err } - g, err := GetAvailableGidMap() + g, err := GetAvailableGIDMap() if err != nil { return nil, nil, err } @@ -114,7 +114,7 @@ func countAvailableIDs(mappings []user.IDMap) int64 { // GetAvailableUids returns how many UIDs are available in the // current user namespace. func GetAvailableUids() (int64, error) { - uids, err := GetAvailableUidMap() + uids, err := GetAvailableUIDMap() if err != nil { return -1, err } @@ -125,7 +125,7 @@ func GetAvailableUids() (int64, error) { // GetAvailableGids returns how many GIDs are available in the // current user namespace. func GetAvailableGids() (int64, error) { - gids, err := GetAvailableGidMap() + gids, err := GetAvailableGIDMap() if err != nil { return -1, err } diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go index 80e1309a5..7cb54a7c3 100644 --- a/pkg/rootlessport/rootlessport_linux.go +++ b/pkg/rootlessport/rootlessport_linux.go @@ -64,7 +64,6 @@ func init() { os.Exit(1) } }) - } func loadConfig(r io.Reader) (*Config, io.ReadCloser, io.WriteCloser, error) { diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go index 81cb8b78d..042e20e02 100644 --- a/pkg/specgen/container_validate.go +++ b/pkg/specgen/container_validate.go @@ -29,7 +29,6 @@ func exclusiveOptions(opt1, opt2 string) error { // Validate verifies that the given SpecGenerator is valid and satisfies required // input for creating a container. func (s *SpecGenerator) Validate() error { - if rootless.IsRootless() && len(s.CNINetworks) == 0 { if s.StaticIP != nil || s.StaticIPv6 != nil { return ErrNoStaticIPRootless diff --git a/pkg/specgen/generate/config_linux.go b/pkg/specgen/generate/config_linux.go index 1290a8eb6..b9f024814 100644 --- a/pkg/specgen/generate/config_linux.go +++ b/pkg/specgen/generate/config_linux.go @@ -113,7 +113,6 @@ func DevicesFromPath(g *generate.Generator, devicePath string) error { // mount the internal devices recursively if err := filepath.Walk(resolvedDevicePath, func(dpath string, f os.FileInfo, e error) error { - if f.Mode()&os.ModeDevice == os.ModeDevice { found = true device := fmt.Sprintf("%s:%s", dpath, filepath.Join(dest, strings.TrimPrefix(dpath, src))) diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go index 98ab82259..e04ced3d3 100644 --- a/pkg/specgen/generate/kube/kube.go +++ b/pkg/specgen/generate/kube/kube.go @@ -384,7 +384,6 @@ func getPodPorts(containers []v1.Container) []specgen.PortMapping { if p.HostPort != 0 { infraPorts = append(infraPorts, portBinding) } - } } return infraPorts diff --git a/pkg/specgen/generate/kube/seccomp.go b/pkg/specgen/generate/kube/seccomp.go index 4cbdf6e2e..353f9cbf2 100644 --- a/pkg/specgen/generate/kube/seccomp.go +++ b/pkg/specgen/generate/kube/seccomp.go @@ -11,6 +11,7 @@ import ( // KubeSeccompPaths holds information about a pod YAML's seccomp configuration // it holds both container and pod seccomp paths +// nolint:golint type KubeSeccompPaths struct { containerPaths map[string]string podPath string diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go index f5687f60d..c3241a49e 100644 --- a/pkg/specgen/generate/kube/volume.go +++ b/pkg/specgen/generate/kube/volume.go @@ -17,6 +17,7 @@ const ( kubeFilePermission = 0644 ) +// nolint:golint type KubeVolumeType int const ( @@ -24,6 +25,7 @@ const ( KubeVolumeTypeNamed KubeVolumeType = iota ) +// nolint:golint type KubeVolume struct { // Type of volume to create Type KubeVolumeType diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index e62131244..eefe45dfe 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -105,7 +105,10 @@ func makeCommand(ctx context.Context, s *specgen.SpecGenerator, img *image.Image entrypoint = newEntry } - finalCommand = append(finalCommand, entrypoint...) + // Don't append the entrypoint if it is [""] + if len(entrypoint) != 1 || entrypoint[0] != "" { + finalCommand = append(finalCommand, entrypoint...) + } // Only use image command if the user did not manually set an // entrypoint. @@ -219,7 +222,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt if !mappingFound { gid5Available = false } - } if !gid5Available { // If we have no GID mappings, the gid=5 default option would fail, so drop it. diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go index 390b19beb..fb45d87db 100644 --- a/pkg/specgen/generate/security.go +++ b/pkg/specgen/generate/security.go @@ -109,17 +109,15 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } } if !s.Privileged && len(capsRequiredRequested) > 0 { - // Pass capRequiredRequested in CapAdd field to normalize capabilities names capsRequired, err := capabilities.MergeCapabilities(nil, capsRequiredRequested, nil) if err != nil { return errors.Wrapf(err, "capabilities requested by user or image are not valid: %q", strings.Join(capsRequired, ",")) - } else { - // Verify all capRequired are in the capList - for _, cap := range capsRequired { - if !util.StringInSlice(cap, caplist) { - privCapsRequired = append(privCapsRequired, cap) - } + } + // Verify all capRequired are in the capList + for _, cap := range capsRequired { + if !util.StringInSlice(cap, caplist) { + privCapsRequired = append(privCapsRequired, cap) } } if len(privCapsRequired) == 0 { @@ -189,7 +187,6 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, return err } for sysctlKey, sysctlVal := range defaultSysctls { - // Ignore mqueue sysctls if --ipc=host if noUseIPC && strings.HasPrefix(sysctlKey, "fs.mqueue.") { logrus.Infof("Sysctl %s=%s ignored in containers.conf, since IPC Namespace set to host", sysctlKey, sysctlVal) @@ -213,7 +210,6 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, } for sysctlKey, sysctlVal := range s.Sysctl { - if s.IpcNS.IsHost() && strings.HasPrefix(sysctlKey, "fs.mqueue.") { return errors.Wrapf(define.ErrInvalidArg, "sysctl %s=%s can't be set since IPC Namespace set to host", sysctlKey, sysctlVal) } diff --git a/pkg/specgen/pod_validate.go b/pkg/specgen/pod_validate.go index 518adb32f..c9bcdf623 100644 --- a/pkg/specgen/pod_validate.go +++ b/pkg/specgen/pod_validate.go @@ -19,7 +19,6 @@ func exclusivePodOptions(opt1, opt2 string) error { // Validate verifies the input is valid func (p *PodSpecGenerator) Validate() error { - if rootless.IsRootless() && len(p.CNINetworks) == 0 { if p.StaticIP != nil { return ErrNoStaticIPRootless diff --git a/pkg/systemd/generate/common_test.go b/pkg/systemd/generate/common_test.go index a0691d1ad..3787e461e 100644 --- a/pkg/systemd/generate/common_test.go +++ b/pkg/systemd/generate/common_test.go @@ -8,7 +8,6 @@ import ( ) func TestFilterPodFlags(t *testing.T) { - tests := []struct { input []string }{ diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index abe159812..acee7be65 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -68,7 +68,7 @@ type containerInfo struct { // If not nil, the container is part of the pod. We can use the // podInfo to extract the relevant data. - pod *podInfo + Pod *podInfo } const containerTemplate = headerTemplate + ` @@ -215,8 +215,8 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst ) // If the container is in a pod, make sure that the // --pod-id-file is set correctly. - if info.pod != nil { - podFlags := []string{"--pod-id-file", info.pod.PodIDFile} + if info.Pod != nil { + podFlags := []string{"--pod-id-file", "{{{{.Pod.PodIDFile}}}}"} startCommand = append(startCommand, podFlags...) info.CreateCommand = filterPodFlags(info.CreateCommand) } diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index be14e4c28..dad14ece9 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -170,7 +170,7 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=always TimeoutStopSec=70 ExecStartPre=/bin/rm -f %t/jadda-jadda.pid %t/jadda-jadda.ctr-id -ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file /tmp/pod-foobar.pod-id-file --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN +ExecStart=/usr/bin/podman run --conmon-pidfile %t/jadda-jadda.pid --cidfile %t/jadda-jadda.ctr-id --cgroups=no-conmon --pod-id-file %t/pod-foobar.pod-id-file --replace -d --name jadda-jadda --hostname hello-world awesome-image:latest command arg1 ... argN ExecStop=/usr/bin/podman stop --ignore --cidfile %t/jadda-jadda.ctr-id -t 10 ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/jadda-jadda.ctr-id PIDFile=%t/jadda-jadda.pid @@ -487,8 +487,8 @@ WantedBy=multi-user.target default.target PodmanVersion: "CI", CreateCommand: []string{"I'll get stripped", "run", "-d", "--name", "jadda-jadda", "--hostname", "hello-world", "awesome-image:latest", "command", "arg1", "...", "argN"}, EnvVariable: EnvVariable, - pod: &podInfo{ - PodIDFile: "/tmp/pod-foobar.pod-id-file", + Pod: &podInfo{ + PodIDFile: "%t/pod-foobar.pod-id-file", }, }, goodNameNewWithPodFile, diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index d6ede19af..ff8ce3a03 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -162,7 +162,7 @@ func PodUnits(pod *libpod.Pod, options entities.GenerateSystemdOptions) (map[str } units[podInfo.ServiceName] = out for _, info := range containerInfos { - info.pod = podInfo + info.Pod = podInfo out, err := executeContainerTemplate(info, options) if err != nil { return nil, err diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go index a30611b74..18a6a1717 100644 --- a/pkg/trust/trust.go +++ b/pkg/trust/trust.go @@ -179,7 +179,6 @@ func CreateTmpFile(dir, pattern string, content []byte) (string, error) { if _, err := tmpfile.Write(content); err != nil { return "", err - } return tmpfile.Name(), nil } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index e0f631eb4..32bb66332 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -388,7 +388,6 @@ func GetKeepIDMapping() (*storage.IDMappingOptions, int, int, error) { options.HostUIDMapping = false options.HostGIDMapping = false - } // Simply ignore the setting and do not setup an inner namespace for root as it is a no-op return &options, uid, gid, nil @@ -530,9 +529,9 @@ func ParseInputTime(inputTime string) (time.Time, error) { } } - unix_timestamp, err := strconv.ParseInt(inputTime, 10, 64) + unixTimestamp, err := strconv.ParseInt(inputTime, 10, 64) if err == nil { - return time.Unix(unix_timestamp, 0), nil + return time.Unix(unixTimestamp, 0), nil } // input might be a duration diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index 7b500bf57..a650cf958 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -41,10 +41,17 @@ t GET images/$iid/json 200 \ .Id=sha256:$iid \ .RepoTags[0]=$IMAGE -t POST "images/create?fromImage=alpine" '' 200 +t POST "images/create?fromImage=alpine" '' 200 .error=null .status~".*Download complete.*" t POST "images/create?fromImage=alpine&tag=latest" '' 200 +# Make sure that new images are pulled +old_iid=$(podman image inspect --format "{{.ID}}" docker.io/library/alpine:latest) +podman rmi -f docker.io/library/alpine:latest +podman tag $IMAGE docker.io/library/alpine:latest +t POST "images/create?fromImage=alpine" '' 200 .error=null .status~".*$old_iid.*" +podman untag $IMAGE docker.io/library/alpine:latest + t POST "images/create?fromImage=quay.io/libpod/alpine&tag=sha256:fa93b01658e3a5a1686dc3ae55f170d8de487006fb53a28efcd12ab0710a2e5f" '' 200 # Display the image history diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 0da196e46..a99e9a184 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -63,7 +63,7 @@ cid=$(jq -r '.Id' <<<"$output") # Prior to the fix in #6835, this would fail 500 "args must not be empty" t POST libpod/containers/${cid}/start '' 204 # Container should exit almost immediately. Wait for it, confirm successful run -t POST libpod/containers/${cid}/wait '' 200 '0' +t POST "libpod/containers/${cid}/wait?condition=stopped&condition=exited" '' 200 '0' t GET libpod/containers/${cid}/json 200 \ .Id=$cid \ .State.Status~\\\(exited\\\|stopped\\\) \ diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 71b4c0089..9bab4c926 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -194,7 +194,7 @@ var _ = Describe("Podman build", func() { inspect := podmanTest.Podman([]string{"inspect", string(id)}) inspect.WaitWithDefaultTimeout() data := inspect.InspectImageJSON() - Expect(data[0].ID).To(Equal(string(id))) + Expect("sha256:" + data[0].ID).To(Equal(string(id))) }) It("podman Test PATH in built image", func() { @@ -458,4 +458,55 @@ RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR` Expect(ok).To(BeTrue()) }) + It("podman build --from, --add-host, --cap-drop, --cap-add", func() { + targetPath, err := CreateTempDirInTempDir() + Expect(err).To(BeNil()) + + containerFile := filepath.Join(targetPath, "Containerfile") + content := `FROM scratch +RUN cat /etc/hosts +RUN grep CapEff /proc/self/status` + + Expect(ioutil.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) + + defer func() { + Expect(os.RemoveAll(containerFile)).To(BeNil()) + }() + + // When + session := podmanTest.Podman([]string{ + "build", "--cap-drop=all", "--cap-add=net_bind_service", "--add-host", "testhost:1.2.3.4", "--from", "alpine", targetPath, + }) + session.WaitWithDefaultTimeout() + + // Then + Expect(session.ExitCode()).To(Equal(0)) + Expect(strings.Fields(session.OutputToString())). + To(ContainElement("alpine")) + Expect(strings.Fields(session.OutputToString())). + To(ContainElement("testhost")) + Expect(strings.Fields(session.OutputToString())). + To(ContainElement("0000000000000400")) + }) + + It("podman build --arch", func() { + targetPath, err := CreateTempDirInTempDir() + Expect(err).To(BeNil()) + + containerFile := filepath.Join(targetPath, "Containerfile") + Expect(ioutil.WriteFile(containerFile, []byte("FROM alpine"), 0755)).To(BeNil()) + + defer func() { + Expect(os.RemoveAll(containerFile)).To(BeNil()) + }() + + // When + session := podmanTest.Podman([]string{ + "build", "--arch", "arm64", targetPath, + }) + session.WaitWithDefaultTimeout() + + // Then + Expect(session.ExitCode()).To(Equal(0)) + }) }) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 8a452f340..88cd7dd9c 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -432,13 +432,20 @@ func (p *PodmanTestIntegration) RunLsContainerInPod(name, pod string) (*PodmanSe // BuildImage uses podman build and buildah to build an image // called imageName based on a string dockerfile -func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) { +func (p *PodmanTestIntegration) BuildImage(dockerfile, imageName string, layers string) string { dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) - session := p.Podman([]string{"build", "--layers=" + layers, "-t", imageName, "--file", dockerfilePath, p.TempDir}) + cmd := []string{"build", "--layers=" + layers, "--file", dockerfilePath} + if len(imageName) > 0 { + cmd = append(cmd, []string{"-t", imageName}...) + } + cmd = append(cmd, p.TempDir) + session := p.Podman(cmd) session.Wait(240) Expect(session).Should(Exit(0), fmt.Sprintf("BuildImage session output: %q", session.OutputToString())) + output := session.OutputToStringArray() + return output[len(output)-1] } // PodmanPID execs podman and returns its PID diff --git a/test/e2e/images_test.go b/test/e2e/images_test.go index 2dab4858e..b79115c71 100644 --- a/test/e2e/images_test.go +++ b/test/e2e/images_test.go @@ -194,7 +194,7 @@ WORKDIR /test result := podmanTest.Podman([]string{"images", "-q", "-f", "since=quay.io/libpod/alpine:latest"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - Expect(len(result.OutputToStringArray())).To(Equal(7)) + Expect(len(result.OutputToStringArray())).To(Equal(8)) }) It("podman image list filter after image", func() { @@ -204,7 +204,7 @@ WORKDIR /test result := podmanTest.Podman([]string{"image", "list", "-q", "-f", "after=quay.io/libpod/alpine:latest"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) - Expect(result.OutputToStringArray()).Should(HaveLen(7), "list filter output: %q", result.OutputToString()) + Expect(result.OutputToStringArray()).Should(HaveLen(8), "list filter output: %q", result.OutputToString()) }) It("podman images filter dangling", func() { diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index df8ff0684..b1cabdbf8 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -407,6 +407,7 @@ var _ = Describe("Podman network", func() { Expect(lines[0]).To(Equal(netName1)) Expect(lines[1]).To(Equal(netName2)) }) + It("podman network with multiple aliases", func() { var worked bool netName := "aliasTest" + stringid.GenerateNonCryptoID() @@ -415,16 +416,28 @@ var _ = Describe("Podman network", func() { defer podmanTest.removeCNINetwork(netName) Expect(session.ExitCode()).To(BeZero()) + interval := time.Duration(250 * time.Millisecond) + for i := 0; i < 6; i++ { + n := podmanTest.Podman([]string{"network", "exists", netName}) + n.WaitWithDefaultTimeout() + worked = n.ExitCode() == 0 + if worked { + break + } + time.Sleep(interval) + interval *= 2 + } + top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) top.WaitWithDefaultTimeout() Expect(top.ExitCode()).To(BeZero()) - interval := time.Duration(250 * time.Millisecond) + interval = time.Duration(250 * time.Millisecond) // Wait for the nginx service to be running for i := 0; i < 6; i++ { // Test curl against the container's name - c1 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web"}) + c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web"}) c1.WaitWithDefaultTimeout() - worked = Expect(c1.ExitCode()).To(BeZero()) + worked = c1.ExitCode() == 0 if worked { break } @@ -435,12 +448,12 @@ var _ = Describe("Podman network", func() { // Nginx is now running so no need to do a loop // Test against the first alias - c2 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web1"}) + c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web1"}) c2.WaitWithDefaultTimeout() Expect(c2.ExitCode()).To(BeZero()) // Test against the second alias - c3 := podmanTest.Podman([]string{"run", "--network=" + netName, nginx, "curl", "web2"}) + c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web2"}) c3.WaitWithDefaultTimeout() Expect(c3.ExitCode()).To(BeZero()) }) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index e57712f62..0a7a5101e 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -501,4 +501,18 @@ entrypoint ["/fromimage"] Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo")) Expect(len(session.OutputToStringArray())).To(Equal(1)) }) + + It("podman pod create --infra-image w/untagged image", func() { + podmanTest.AddImageToRWStore(ALPINE) + dockerfile := `FROM quay.io/libpod/alpine:latest +ENTRYPOINT ["sleep","99999"] + ` + // This builds a none/none image + iid := podmanTest.BuildImage(dockerfile, "", "true") + + create := podmanTest.Podman([]string{"pod", "create", "--infra-image", iid}) + create.WaitWithDefaultTimeout() + Expect(create.ExitCode()).To(BeZero()) + }) + }) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 225bd538e..016b4c8cd 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -350,6 +350,21 @@ var _ = Describe("Podman ps", func() { Expect(session).To(ExitWithError()) }) + It("podman --format by size", func() { + session := podmanTest.Podman([]string{"create", "busybox", "ls"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"create", "-t", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + session = podmanTest.Podman([]string{"ps", "-a", "--format", "{{.Size}}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.ErrorToString()).To(ContainSubstring("Size format requires --size option")) + }) + It("podman --sort by size", func() { session := podmanTest.Podman([]string{"create", "busybox", "ls"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go index cac3d759d..389f142b1 100644 --- a/test/e2e/run_entrypoint_test.go +++ b/test/e2e/run_entrypoint_test.go @@ -43,6 +43,18 @@ CMD [] Expect(session.ExitCode()).To(Equal(125)) }) + It("podman run entrypoint == [\"\"]", func() { + dockerfile := `FROM quay.io/libpod/alpine:latest +ENTRYPOINT [""] +CMD [] +` + podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") + session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest", "echo", "hello"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal("hello")) + }) + It("podman run entrypoint", func() { dockerfile := `FROM quay.io/libpod/alpine:latest ENTRYPOINT ["grep", "Alpine", "/etc/os-release"] diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 7d367cccf..bff3995df 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -47,6 +47,29 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) }) + It("podman run check /run/.containerenv", func() { + session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/run/.containerenv"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal("")) + + session = podmanTest.Podman([]string{"run", "--privileged", "--name=test1", ALPINE, "cat", "/run/.containerenv"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("name=\"test1\"")) + Expect(session.OutputToString()).To(ContainSubstring("image=\"" + ALPINE + "\"")) + + session = podmanTest.Podman([]string{"run", "-v", "/:/host", ALPINE, "cat", "/run/.containerenv"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) + + session = podmanTest.Podman([]string{"run", "-v", "/:/host", "--privileged", ALPINE, "cat", "/run/.containerenv"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) + }) + It("podman run a container based on a complex local image name", func() { imageName := strings.TrimPrefix(nginx, "quay.io/") session := podmanTest.Podman([]string{"run", imageName, "ls"}) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index 19d82c974..d81fb769d 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -322,6 +322,30 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"` Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) }) + It("podman named volume copyup empty directory", func() { + baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", ALPINE, "ls", "/srv"}) + baselineSession.WaitWithDefaultTimeout() + Expect(baselineSession.ExitCode()).To(Equal(0)) + baselineOutput := baselineSession.OutputToString() + + outputSession := podmanTest.Podman([]string{"run", "-t", "-i", "-v", "/srv", ALPINE, "ls", "/srv"}) + outputSession.WaitWithDefaultTimeout() + Expect(outputSession.ExitCode()).To(Equal(0)) + Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) + }) + + It("podman named volume copyup of /var", func() { + baselineSession := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", fedoraMinimal, "ls", "/var"}) + baselineSession.WaitWithDefaultTimeout() + Expect(baselineSession.ExitCode()).To(Equal(0)) + baselineOutput := baselineSession.OutputToString() + + outputSession := podmanTest.Podman([]string{"run", "-t", "-i", "-v", "/var", fedoraMinimal, "ls", "/var"}) + outputSession.WaitWithDefaultTimeout() + Expect(outputSession.ExitCode()).To(Equal(0)) + Expect(outputSession.OutputToString()).To(Equal(baselineOutput)) + }) + It("podman read-only tmpfs conflict with volume", func() { session := podmanTest.Podman([]string{"run", "--rm", "-t", "-i", "--read-only", "-v", "tmp_volume:" + dest, ALPINE, "touch", dest + "/a"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/run_working_dir_test.go b/test/e2e/run_working_dir_test.go index 59538448e..948ed05e7 100644 --- a/test/e2e/run_working_dir_test.go +++ b/test/e2e/run_working_dir_test.go @@ -47,7 +47,7 @@ var _ = Describe("Podman run", func() { It("podman run a container on an image with a workdir", func() { dockerfile := `FROM alpine -RUN mkdir -p /home/foobar +RUN mkdir -p /home/foobar /etc/foobar; chown bin:bin /etc/foobar WORKDIR /etc/foobar` podmanTest.BuildImage(dockerfile, "test", "false") @@ -56,6 +56,10 @@ WORKDIR /etc/foobar` Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(Equal("/etc/foobar")) + session = podmanTest.Podman([]string{"run", "test", "ls", "-ld", "."}) + session.WaitWithDefaultTimeout() + Expect(session.LineInOutputContains("bin")).To(BeTrue()) + session = podmanTest.Podman([]string{"run", "--workdir", "/home/foobar", "test", "pwd"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/python/docker/test_containers.py b/test/python/docker/test_containers.py index 5c2a5fef2..337cacd5c 100644 --- a/test/python/docker/test_containers.py +++ b/test/python/docker/test_containers.py @@ -86,6 +86,13 @@ class TestContainers(unittest.TestCase): containers = self.client.containers.list(all=True) self.assertEqual(len(containers), 2) + def test_start_container_with_random_port_bind(self): + container = self.client.containers.create(image=constant.ALPINE, + name="containerWithRandomBind", + ports={'1234/tcp': None}) + containers = self.client.containers.list(all=True) + self.assertTrue(container in containers) + def test_stop_container(self): top = self.client.containers.get(TestContainers.topContainerId) self.assertEqual(top.status, "running") diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 98e34238e..49fa92f57 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -623,4 +623,10 @@ json-file | f fi } +@test "podman run - do not set empty HOME" { + # Regression test for #9378. + run_podman run --rm --user 100 $IMAGE printenv + is "$output" ".*HOME=/.*" +} + # vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index bf9fa789c..000998f3a 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -46,6 +46,31 @@ EOF is "$output" ".*invalidflag" "failed when passing undefined flags to the runtime" } +@test "podman build - set runtime" { + skip_if_remote "--runtime flag not supported for remote" + # Test on the CLI and via containers.conf + + tmpdir=$PODMAN_TMPDIR/build-test + run mkdir -p $tmpdir + containerfile=$tmpdir/Containerfile + cat >$containerfile <<EOF +FROM $IMAGE +RUN echo $rand_content +EOF + + run_podman 125 --runtime=idonotexist build -t build_test $tmpdir + is "$output" ".*\"idonotexist\" not found.*" "failed when passing invalid OCI runtime via CLI" + + containersconf=$tmpdir/containers.conf + cat >$containersconf <<EOF +[engine] +runtime="idonotexist" +EOF + + CONTAINERS_CONF="$containersconf" run_podman 125 build -t build_test $tmpdir + is "$output" ".*\"idonotexist\" not found.*" "failed when passing invalid OCI runtime via containers.conf" +} + # Regression from v1.5.0. This test passes fine in v1.5.0, fails in 1.6 @test "podman build - cache (#3920)" { # Make an empty test directory, with a subdirectory used for tar diff --git a/vendor/github.com/containers/buildah/CHANGELOG.md b/vendor/github.com/containers/buildah/CHANGELOG.md index 25f02db19..ccf46b324 100644 --- a/vendor/github.com/containers/buildah/CHANGELOG.md +++ b/vendor/github.com/containers/buildah/CHANGELOG.md @@ -2,6 +2,32 @@ # Changelog +## v1.19.4 (2021-02-06) + run: fix check for host pid namespace + bump containernetworking/cni library to v0.8.1 - fix for CVE-2021-20206 + Finish plumbing for buildah bud --manifest + buildah manifest add localimage should work + Fix build arg check + --iidfile: print hash prefix + +## v1.19.3 (2021-01-28) + [ci:docs] Fix man page for buildah push + Vendor in containers/image v5.10.1 + Rebuild layer if a change in ARG is detected + Bump golang.org/x/crypto to latest rel-1.19 + local image lookup by digest + Use build-arg ENV val from local environment if set + Pick default OCI Runtime from containers.conf + +## v1.19.2 (2021-01-15) + If overlay mount point destination does not exists, do not throw error + Vendor in containers/common + +## v1.19.1 (2021-01-14) + Cherry pick localhost fix and update CI configuration for release-1.19 + use local image name for pull policy checks + Vendor in common 0.33.1 + ## v1.19.0 (2021-01-08) Update vendor of containers/storage and containers/common Buildah inspect should be able to inspect manifests diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index 89fc860dd..7065e00e4 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -28,7 +28,7 @@ const ( Package = "buildah" // Version for the Package. Bump version in contrib/rpm/buildah.spec // too. - Version = "1.19.2" + Version = "1.19.4" // The value we use to identify what type of information, currently a // serialized Builder structure, we are using as per-container state. // This should only be changed when we make incompatible changes to diff --git a/vendor/github.com/containers/buildah/changelog.txt b/vendor/github.com/containers/buildah/changelog.txt index ce2f2696f..4a0f81b04 100644 --- a/vendor/github.com/containers/buildah/changelog.txt +++ b/vendor/github.com/containers/buildah/changelog.txt @@ -1,3 +1,29 @@ +- Changelog for v1.19.4 (2021-02-06) + * run: fix check for host pid namespace + * bump containernetworking/cni library to v0.8.1 - fix for CVE-2021-20206 + * Finish plumbing for buildah bud --manifest + * buildah manifest add localimage should work + * Fix build arg check + * --iidfile: print hash prefix + +- Changelog for v1.19.3 (2021-01-28) + * [ci:docs] Fix man page for buildah push + * Vendor in containers/image v5.10.1 + * Rebuild layer if a change in ARG is detected + * Bump golang.org/x/crypto to latest rel-1.19 + * local image lookup by digest + * Use build-arg ENV val from local environment if set + * Pick default OCI Runtime from containers.conf + +- Changelog for v1.19.2 (2021-01-15) + * If overlay mount point destination does not exists, do not throw error + * Vendor in containers/common + +- Changelog for v1.19.1 (2021-01-14) + * Cherry pick localhost fix and update CI configuration for release-1.19 + * use local image name for pull policy checks + * Vendor in common 0.33.1 + - Changelog for v1.19.0 (2021-01-08) * Update vendor of containers/storage and containers/common * Buildah inspect should be able to inspect manifests diff --git a/vendor/github.com/containers/buildah/commit.go b/vendor/github.com/containers/buildah/commit.go index 9c6831601..f588c8043 100644 --- a/vendor/github.com/containers/buildah/commit.go +++ b/vendor/github.com/containers/buildah/commit.go @@ -224,7 +224,7 @@ func checkRegistrySourcesAllows(forWhat string, dest types.ImageReference) (inse return false, nil } -func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpec string) error { +func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpec string) (string, error) { var create bool systemContext := &types.SystemContext{} var list manifests.List @@ -235,13 +235,13 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe } else { _, list, err = manifests.LoadFromImage(b.store, listImage.ID) if err != nil { - return err + return "", err } } names, err := util.ExpandNames([]string{manifestName}, "", systemContext, b.store) if err != nil { - return errors.Wrapf(err, "error encountered while expanding image name %q", manifestName) + return "", errors.Wrapf(err, "error encountered while expanding image name %q", manifestName) } ref, err := alltransports.ParseImageName(imageSpec) @@ -249,13 +249,13 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe if ref, err = alltransports.ParseImageName(util.DefaultTransport + imageSpec); err != nil { // check if the local image exists if ref, _, err = util.FindImage(b.store, "", systemContext, imageSpec); err != nil { - return err + return "", err } } } if _, err = list.Add(ctx, systemContext, ref, true); err != nil { - return err + return "", err } var imageID string if create { @@ -263,10 +263,7 @@ func (b *Builder) addManifest(ctx context.Context, manifestName string, imageSpe } else { imageID, err = list.SaveToImage(b.store, listImage.ID, nil, "") } - if err == nil { - fmt.Printf("%s\n", imageID) - } - return err + return imageID, err } // Commit writes the contents of the container, along with its updated @@ -469,7 +466,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options dest = dest2 } if options.IIDFile != "" { - if err = ioutil.WriteFile(options.IIDFile, []byte(img.ID), 0644); err != nil { + if err = ioutil.WriteFile(options.IIDFile, []byte("sha256:"+img.ID), 0644); err != nil { return imgID, nil, "", err } } @@ -489,9 +486,12 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options } if options.Manifest != "" { - if err := b.addManifest(ctx, options.Manifest, imgID); err != nil { + manifestID, err := b.addManifest(ctx, options.Manifest, imgID) + if err != nil { return imgID, nil, "", err } + logrus.Debugf("added imgID %s to manifestID %s", imgID, manifestID) + } return imgID, ref, manifestDigest, nil } diff --git a/vendor/github.com/containers/buildah/go.mod b/vendor/github.com/containers/buildah/go.mod index 135926116..17469ad12 100644 --- a/vendor/github.com/containers/buildah/go.mod +++ b/vendor/github.com/containers/buildah/go.mod @@ -4,9 +4,9 @@ go 1.12 require ( github.com/containerd/containerd v1.4.1 // indirect - github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 + github.com/containernetworking/cni v0.8.1 github.com/containers/common v0.33.1 - github.com/containers/image/v5 v5.9.0 + github.com/containers/image/v5 v5.10.1 github.com/containers/ocicrypt v1.0.3 github.com/containers/storage v1.24.5 github.com/docker/distribution v2.7.1+incompatible @@ -33,12 +33,12 @@ require ( github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 go.etcd.io/bbolt v1.3.5 - golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 + golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a - golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 + golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 gotest.tools/v3 v3.0.3 // indirect k8s.io/klog v1.0.0 // indirect ) diff --git a/vendor/github.com/containers/buildah/go.sum b/vendor/github.com/containers/buildah/go.sum index 6a5f70a36..cab904fcf 100644 --- a/vendor/github.com/containers/buildah/go.sum +++ b/vendor/github.com/containers/buildah/go.sum @@ -76,12 +76,14 @@ github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784 h1:rqUVLD8I859xRgUx/WMC3v7QAFqbLKZbs+0kqYboRJc= -github.com/containernetworking/cni v0.7.2-0.20190904153231-83439463f784/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1 h1:7zpDnQ3T3s4ucOuJ/ZCLrYBxzkg0AELFfII3Epo9TmI= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= github.com/containers/common v0.33.1 h1:XpDiq8Cta8+u1s4kpYSEWdB140ZmqgyIXfWkLqKx3z0= github.com/containers/common v0.33.1/go.mod h1:mjDo/NKeweL/onaspLhZ38WnHXaYmrELHclIdvSnYpY= github.com/containers/image/v5 v5.9.0 h1:dRmUtcluQcmasNo3DpnRoZjfU0rOu1qZeL6wlDJr10Q= github.com/containers/image/v5 v5.9.0/go.mod h1:blOEFd/iFdeyh891ByhCVUc+xAcaI3gBegXECwz9UbQ= +github.com/containers/image/v5 v5.10.1 h1:tHhGQ8RCMxJfJLD/PEW1qrOKX8nndledW9qz6UiAxns= +github.com/containers/image/v5 v5.10.1/go.mod h1:JlRLJZv7elVbtHaaaR6Kz8i6G3k2ttj4t7fubwxD9Hs= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6GzVe1c= @@ -238,6 +240,8 @@ github.com/klauspost/compress v1.11.3 h1:dB4Bn0tN3wdCzQxnS8r06kV74qN/TAfaIS0bVE8 github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.5 h1:xNCE0uE6yvTPRS+0wGNMHPo3NIpwnk6aluQZ6R6kRcc= github.com/klauspost/compress v1.11.5/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= @@ -404,6 +408,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -412,6 +418,8 @@ github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I= +github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= @@ -419,6 +427,8 @@ github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02 github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g= github.com/vbauerster/mpb/v5 v5.3.0 h1:vgrEJjUzHaSZKDRRxul5Oh4C72Yy/5VEMb0em+9M0mQ= github.com/vbauerster/mpb/v5 v5.3.0/go.mod h1:4yTkvAb8Cm4eylAp6t0JRq6pXDkFJ4krUlDqWYkakAs= +github.com/vbauerster/mpb/v5 v5.4.0 h1:n8JPunifvQvh6P1D1HAl2Ur9YcmKT1tpoUuiea5mlmg= +github.com/vbauerster/mpb/v5 v5.4.0/go.mod h1:fi4wVo7BVQ22QcvFObm+VwliQXlV1eBT8JDaKXR4JGI= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= @@ -456,6 +466,8 @@ golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -527,6 +539,7 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -543,6 +556,10 @@ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3 h1:kzM6+9dur93BcC2kVlYl34cHU+TYZLanmpSJHVMmL64= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ= +golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/vendor/github.com/containers/buildah/imagebuildah/executor.go b/vendor/github.com/containers/buildah/imagebuildah/executor.go index a72e24eea..74ed9a42b 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/executor.go @@ -115,6 +115,7 @@ type Executor struct { imageInfoLock sync.Mutex imageInfoCache map[string]imageTypeAndHistoryAndDiffIDs fromOverride string + manifest string } type imageTypeAndHistoryAndDiffIDs struct { @@ -231,6 +232,7 @@ func NewExecutor(store storage.Store, options BuildOptions, mainNode *parser.Nod logRusage: options.LogRusage, imageInfoCache: make(map[string]imageTypeAndHistoryAndDiffIDs), fromOverride: options.From, + manifest: options.Manifest, } if exec.err == nil { exec.err = os.Stderr @@ -679,7 +681,7 @@ func (b *Executor) Build(ctx context.Context, stages imagebuilder.Stages) (image } logrus.Debugf("printing final image id %q", imageID) if b.iidfile != "" { - if err = ioutil.WriteFile(b.iidfile, []byte(imageID), 0644); err != nil { + if err = ioutil.WriteFile(b.iidfile, []byte("sha256:"+imageID), 0644); err != nil { return imageID, ref, errors.Wrapf(err, "failed to write image ID to file %q", b.iidfile) } } else { diff --git a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go index 191645b89..13631108e 100644 --- a/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go +++ b/vendor/github.com/containers/buildah/imagebuildah/stage_executor.go @@ -834,7 +834,11 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // Check if there's already an image based on our parent that // has the same change that we're about to make, so far as we // can tell. - if checkForLayers { + // Only do this if there were no build args given by the user, + // we need to call ib.Run() to correctly put the args together before + // determining if a cached layer with the same build args already exists + // and that is done in the if block below. + if checkForLayers && len(s.builder.Args) == 0 { cacheID, err = s.intermediateImageExists(ctx, node, addedContentSummary, s.stepRequiresLayer(step)) if err != nil { return "", nil, errors.Wrap(err, "error checking if cached image exists from a previous build") @@ -1022,6 +1026,9 @@ func (s *StageExecutor) getCreatedBy(node *parser.Node, addedContentSummary stri return "/bin/sh" } switch strings.ToUpper(node.Value) { + case "ARG": + buildArgs := s.getBuildArgs() + return "/bin/sh -c #(nop) ARG " + buildArgs case "RUN": buildArgs := s.getBuildArgs() if buildArgs != "" { @@ -1269,6 +1276,7 @@ func (s *StageExecutor) commit(ctx context.Context, createdBy string, emptyLayer MaxRetries: s.executor.maxPullPushRetries, RetryDelay: s.executor.retryPullPushDelay, HistoryTimestamp: s.executor.timestamp, + Manifest: s.executor.manifest, } imgID, _, manifestDigest, err := s.builder.Commit(ctx, imageRef, options) if err != nil { diff --git a/vendor/github.com/containers/buildah/new.go b/vendor/github.com/containers/buildah/new.go index 4d70e0146..2ee86dd13 100644 --- a/vendor/github.com/containers/buildah/new.go +++ b/vendor/github.com/containers/buildah/new.go @@ -150,10 +150,10 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store return nil, "", nil, err } - // If we could resolve the image locally, check if it was referenced by - // ID. In that case, we don't need to bother any further and can - // prevent prompting the user. - if localImage != nil && strings.HasPrefix(localImage.ID, options.FromImage) { + // If we could resolve the image locally, check if it was clearly + // referring to a local image, either by ID or digest. In that case, + // we don't need to perform a remote lookup. + if localImage != nil && (strings.HasPrefix(localImage.ID, options.FromImage) || strings.HasPrefix(options.FromImage, "sha256:")) { return localImageRef, localImageRef.Transport().Name(), localImage, nil } diff --git a/vendor/github.com/containers/buildah/run_linux.go b/vendor/github.com/containers/buildah/run_linux.go index 66c856884..8c7c1bbc0 100644 --- a/vendor/github.com/containers/buildah/run_linux.go +++ b/vendor/github.com/containers/buildah/run_linux.go @@ -2210,7 +2210,7 @@ func checkAndOverrideIsolationOptions(isolation Isolation, options *RunOptions) case IsolationOCI: pidns := options.NamespaceOptions.Find(string(specs.PIDNamespace)) userns := options.NamespaceOptions.Find(string(specs.UserNamespace)) - if (pidns == nil || pidns.Host) && (userns != nil && !userns.Host) { + if (pidns != nil && pidns.Host) && (userns != nil && !userns.Host) { return errors.Errorf("not allowed to mix host PID namespace with container user namespace") } } diff --git a/vendor/github.com/containers/buildah/util/types.go b/vendor/github.com/containers/buildah/util/types.go index dc5f4b6c8..ca0f31532 100644 --- a/vendor/github.com/containers/buildah/util/types.go +++ b/vendor/github.com/containers/buildah/util/types.go @@ -1,7 +1,7 @@ package util const ( - // DefaultRuntime is the default command to use to run the container. + // Deprecated: Default runtime should come from containers.conf DefaultRuntime = "runc" // DefaultCNIPluginPath is the default location of CNI plugin helpers. DefaultCNIPluginPath = "/usr/libexec/cni:/opt/cni/bin" diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go index 99f68d9e1..338c4503a 100644 --- a/vendor/github.com/containers/buildah/util/util.go +++ b/vendor/github.com/containers/buildah/util/util.go @@ -20,6 +20,7 @@ import ( "github.com/containers/image/v5/types" "github.com/containers/storage" "github.com/docker/distribution/registry/api/errcode" + "github.com/opencontainers/go-digest" specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -68,6 +69,19 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto return []string{img.ID}, "", false, nil } } + // If we're referring to an image by digest, it *must* be local and we + // should not have any fall through/back logic. + if strings.HasPrefix(name, "sha256:") { + d, err := digest.Parse(name) + if err != nil { + return nil, "", false, err + } + img, err := store.Image(d.Encoded()) + if err != nil { + return nil, "", false, err + } + return []string{img.ID}, "", false, nil + } // Transports are not supported for local image look ups. srcRef, err := alltransports.ParseImageName(name) @@ -263,7 +277,12 @@ func Runtime() string { return "crun" } - return DefaultRuntime + conf, err := config.Default() + if err != nil { + logrus.Warnf("Error loading container config when searching for local runtime: %v", err) + return DefaultRuntime + } + return conf.Engine.OCIRuntime } // StringInSlice returns a boolean indicating if the exact value s is present diff --git a/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go b/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go new file mode 100644 index 000000000..288296ea5 --- /dev/null +++ b/vendor/github.com/containers/ocicrypt/helpers/parse_helpers.go @@ -0,0 +1,301 @@ +package helpers + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "github.com/containers/ocicrypt" + encconfig "github.com/containers/ocicrypt/config" + encutils "github.com/containers/ocicrypt/utils" + + "github.com/pkg/errors" +) + +// processRecipientKeys sorts the array of recipients by type. Recipients may be either +// x509 certificates, public keys, or PGP public keys identified by email address or name +func processRecipientKeys(recipients []string) ([][]byte, [][]byte, [][]byte, error) { + var ( + gpgRecipients [][]byte + pubkeys [][]byte + x509s [][]byte + ) + for _, recipient := range recipients { + + idx := strings.Index(recipient, ":") + if idx < 0 { + return nil, nil, nil, errors.New("Invalid recipient format") + } + + protocol := recipient[:idx] + value := recipient[idx+1:] + + switch protocol { + case "pgp": + gpgRecipients = append(gpgRecipients, []byte(value)) + + case "jwe": + tmp, err := ioutil.ReadFile(value) + if err != nil { + return nil, nil, nil, errors.Wrap(err, "Unable to read file") + } + if !encutils.IsPublicKey(tmp) { + return nil, nil, nil, errors.New("File provided is not a public key") + } + pubkeys = append(pubkeys, tmp) + + case "pkcs7": + tmp, err := ioutil.ReadFile(value) + if err != nil { + return nil, nil, nil, errors.Wrap(err, "Unable to read file") + } + if !encutils.IsCertificate(tmp) { + return nil, nil, nil, errors.New("File provided is not an x509 cert") + } + x509s = append(x509s, tmp) + + default: + return nil, nil, nil, errors.New("Provided protocol not recognized") + } + } + return gpgRecipients, pubkeys, x509s, nil +} + +// processx509Certs processes x509 certificate files +func processx509Certs(keys []string) ([][]byte, error) { + var x509s [][]byte + for _, key := range keys { + tmp, err := ioutil.ReadFile(key) + if err != nil { + return nil, errors.Wrap(err, "Unable to read file") + } + if !encutils.IsCertificate(tmp) { + continue + } + x509s = append(x509s, tmp) + + } + return x509s, nil +} + +// processPwdString process a password that may be in any of the following formats: +// - file=<passwordfile> +// - pass=<password> +// - fd=<filedescriptor> +// - <password> +func processPwdString(pwdString string) ([]byte, error) { + if strings.HasPrefix(pwdString, "file=") { + return ioutil.ReadFile(pwdString[5:]) + } else if strings.HasPrefix(pwdString, "pass=") { + return []byte(pwdString[5:]), nil + } else if strings.HasPrefix(pwdString, "fd=") { + fdStr := pwdString[3:] + fd, err := strconv.Atoi(fdStr) + if err != nil { + return nil, errors.Wrapf(err, "could not parse file descriptor %s", fdStr) + } + f := os.NewFile(uintptr(fd), "pwdfile") + if f == nil { + return nil, fmt.Errorf("%s is not a valid file descriptor", fdStr) + } + defer f.Close() + pwd := make([]byte, 64) + n, err := f.Read(pwd) + if err != nil { + return nil, errors.Wrapf(err, "could not read from file descriptor") + } + return pwd[:n], nil + } + return []byte(pwdString), nil +} + +// processPrivateKeyFiles sorts the different types of private key files; private key files may either be +// private keys or GPG private key ring files. The private key files may include the password for the +// private key and take any of the following forms: +// - <filename> +// - <filename>:file=<passwordfile> +// - <filename>:pass=<password> +// - <filename>:fd=<filedescriptor> +// - <filename>:<password> +func processPrivateKeyFiles(keyFilesAndPwds []string) ([][]byte, [][]byte, [][]byte, [][]byte, error) { + var ( + gpgSecretKeyRingFiles [][]byte + gpgSecretKeyPasswords [][]byte + privkeys [][]byte + privkeysPasswords [][]byte + err error + ) + // keys needed for decryption in case of adding a recipient + for _, keyfileAndPwd := range keyFilesAndPwds { + var password []byte + + parts := strings.Split(keyfileAndPwd, ":") + if len(parts) == 2 { + password, err = processPwdString(parts[1]) + if err != nil { + return nil, nil, nil, nil, err + } + } + + keyfile := parts[0] + tmp, err := ioutil.ReadFile(keyfile) + if err != nil { + return nil, nil, nil, nil, err + } + isPrivKey, err := encutils.IsPrivateKey(tmp, password) + if encutils.IsPasswordError(err) { + return nil, nil, nil, nil, err + } + if isPrivKey { + privkeys = append(privkeys, tmp) + privkeysPasswords = append(privkeysPasswords, password) + } else if encutils.IsGPGPrivateKeyRing(tmp) { + gpgSecretKeyRingFiles = append(gpgSecretKeyRingFiles, tmp) + gpgSecretKeyPasswords = append(gpgSecretKeyPasswords, password) + } else { + // ignore if file is not recognized, so as not to error if additional + // metadata/cert files exists + continue + } + } + return gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privkeys, privkeysPasswords, nil +} + +// CreateDecryptCryptoConfig creates the CryptoConfig object that contains the necessary +// information to perform decryption from command line options and possibly +// LayerInfos describing the image and helping us to query for the PGP decryption keys +func CreateDecryptCryptoConfig(keys []string, decRecipients []string) (encconfig.CryptoConfig, error) { + ccs := []encconfig.CryptoConfig{} + + // x509 cert is needed for PKCS7 decryption + _, _, x509s, err := processRecipientKeys(decRecipients) + if err != nil { + return encconfig.CryptoConfig{}, err + } + + // x509 certs can also be passed in via keys + x509FromKeys, err := processx509Certs(keys) + if err != nil { + return encconfig.CryptoConfig{}, err + } + x509s = append(x509s, x509FromKeys...) + + gpgSecretKeyRingFiles, gpgSecretKeyPasswords, privKeys, privKeysPasswords, err := processPrivateKeyFiles(keys) + if err != nil { + return encconfig.CryptoConfig{}, err + } + + if len(gpgSecretKeyRingFiles) > 0 { + gpgCc, err := encconfig.DecryptWithGpgPrivKeys(gpgSecretKeyRingFiles, gpgSecretKeyPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, gpgCc) + } + + /* TODO: Add in GPG client query for secret keys in the future. + _, err = createGPGClient(context) + gpgInstalled := err == nil + if gpgInstalled { + if len(gpgSecretKeyRingFiles) == 0 && len(privKeys) == 0 && descs != nil { + // Get pgp private keys from keyring only if no private key was passed + gpgPrivKeys, gpgPrivKeyPasswords, err := getGPGPrivateKeys(context, gpgSecretKeyRingFiles, descs, true) + if err != nil { + return encconfig.CryptoConfig{}, err + } + + gpgCc, err := encconfig.DecryptWithGpgPrivKeys(gpgPrivKeys, gpgPrivKeyPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, gpgCc) + + } else if len(gpgSecretKeyRingFiles) > 0 { + gpgCc, err := encconfig.DecryptWithGpgPrivKeys(gpgSecretKeyRingFiles, gpgSecretKeyPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, gpgCc) + + } + } + */ + + x509sCc, err := encconfig.DecryptWithX509s(x509s) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, x509sCc) + + privKeysCc, err := encconfig.DecryptWithPrivKeys(privKeys, privKeysPasswords) + if err != nil { + return encconfig.CryptoConfig{}, err + } + ccs = append(ccs, privKeysCc) + + return encconfig.CombineCryptoConfigs(ccs), nil +} + +// CreateCryptoConfig from the list of recipient strings and list of key paths of private keys +func CreateCryptoConfig(recipients []string, keys []string) (encconfig.CryptoConfig, error) { + var decryptCc *encconfig.CryptoConfig + ccs := []encconfig.CryptoConfig{} + if len(keys) > 0 { + dcc, err := CreateDecryptCryptoConfig(keys, []string{}) + if err != nil { + return encconfig.CryptoConfig{}, err + } + decryptCc = &dcc + ccs = append(ccs, dcc) + } + + if len(recipients) > 0 { + gpgRecipients, pubKeys, x509s, err := processRecipientKeys(recipients) + if err != nil { + return encconfig.CryptoConfig{}, err + } + encryptCcs := []encconfig.CryptoConfig{} + + // Create GPG client with guessed GPG version and default homedir + gpgClient, err := ocicrypt.NewGPGClient("", "") + gpgInstalled := err == nil + if len(gpgRecipients) > 0 && gpgInstalled { + gpgPubRingFile, err := gpgClient.ReadGPGPubRingFile() + if err != nil { + return encconfig.CryptoConfig{}, err + } + + gpgCc, err := encconfig.EncryptWithGpg(gpgRecipients, gpgPubRingFile) + if err != nil { + return encconfig.CryptoConfig{}, err + } + encryptCcs = append(encryptCcs, gpgCc) + } + + // Create Encryption Crypto Config + pkcs7Cc, err := encconfig.EncryptWithPkcs7(x509s) + if err != nil { + return encconfig.CryptoConfig{}, err + } + encryptCcs = append(encryptCcs, pkcs7Cc) + + jweCc, err := encconfig.EncryptWithJwe(pubKeys) + if err != nil { + return encconfig.CryptoConfig{}, err + } + encryptCcs = append(encryptCcs, jweCc) + ecc := encconfig.CombineCryptoConfigs(encryptCcs) + if decryptCc != nil { + ecc.EncryptConfig.AttachDecryptConfig(decryptCc.DecryptConfig) + } + ccs = append(ccs, ecc) + } + + if len(ccs) > 0 { + return encconfig.CombineCryptoConfigs(ccs), nil + } else { + return encconfig.CryptoConfig{}, nil + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ffda75dff..ad6465022 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -70,7 +70,7 @@ github.com/containernetworking/plugins/pkg/utils/hwaddr github.com/containernetworking/plugins/pkg/utils/sysctl github.com/containernetworking/plugins/plugins/ipam/host-local/backend github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator -# github.com/containers/buildah v1.19.2 +# github.com/containers/buildah v1.19.4 github.com/containers/buildah github.com/containers/buildah/bind github.com/containers/buildah/chroot @@ -159,6 +159,7 @@ github.com/containers/libtrust github.com/containers/ocicrypt github.com/containers/ocicrypt/blockcipher github.com/containers/ocicrypt/config +github.com/containers/ocicrypt/helpers github.com/containers/ocicrypt/keywrap github.com/containers/ocicrypt/keywrap/jwe github.com/containers/ocicrypt/keywrap/pgp diff --git a/version/version.go b/version/version.go index 8785dd9fd..5291f048e 100644 --- a/version/version.go +++ b/version/version.go @@ -8,7 +8,7 @@ import ( // NOTE: remember to bump the version at the top // of the top-level README.md file when this is // bumped. -var Version = semver.MustParse("3.0.1-dev") +var Version = semver.MustParse("3.0.2-dev") // APIVersion is the version for the remote // client API. It is used to determine compatibility |