summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/podman/common/completion.go4
-rw-r--r--cmd/podman/common/netflags.go13
-rw-r--r--cmd/podman/generate/generate.go6
-rw-r--r--cmd/podman/generate/kube.go80
-rw-r--r--cmd/podman/generate/spec.go4
-rw-r--r--cmd/podman/generate/systemd.go4
-rw-r--r--cmd/podman/kube/down.go2
-rw-r--r--cmd/podman/kube/generate.go109
-rw-r--r--cmd/podman/kube/kube.go4
-rw-r--r--cmd/podman/kube/play.go9
-rw-r--r--cmd/podman/manifest/add.go12
-rw-r--r--cmd/podman/manifest/create.go32
-rw-r--r--cmd/podman/manifest/push.go15
-rw-r--r--cmd/podman/root.go15
14 files changed, 207 insertions, 102 deletions
diff --git a/cmd/podman/common/completion.go b/cmd/podman/common/completion.go
index 71c62a7af..b3a816aa4 100644
--- a/cmd/podman/common/completion.go
+++ b/cmd/podman/common/completion.go
@@ -544,6 +544,10 @@ func AutocompleteForKube(cmd *cobra.Command, args []string, toComplete string) (
return objs, cobra.ShellCompDirectiveNoFileComp
}
+func AutocompleteForGenerate(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ return AutocompleteForKube(cmd, args, toComplete)
+}
+
// AutocompleteContainersAndPods - Autocomplete container names and pod names.
func AutocompleteContainersAndPods(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
if !validCurrentCmdLine(cmd, args, toComplete) {
diff --git a/cmd/podman/common/netflags.go b/cmd/podman/common/netflags.go
index e7aa265d1..90f05ab15 100644
--- a/cmd/podman/common/netflags.go
+++ b/cmd/podman/common/netflags.go
@@ -39,6 +39,11 @@ func DefineNetFlags(cmd *cobra.Command) {
"Set custom DNS options",
)
_ = cmd.RegisterFlagCompletionFunc(dnsOptFlagName, completion.AutocompleteNone)
+ netFlags.StringSlice(
+ "dns-option", containerConfig.DNSOptions(),
+ "Docker compatibility option== --dns-opt",
+ )
+ _ = netFlags.MarkHidden("dns-option")
dnsSearchFlagName := "dns-search"
netFlags.StringSlice(
@@ -146,6 +151,14 @@ func NetFlagsToNetOptions(opts *entities.NetOptions, flags pflag.FlagSet) (*enti
opts.DNSOptions = options
}
+ if flags.Changed("dns-option") {
+ options, err := flags.GetStringSlice("dns-option")
+ if err != nil {
+ return nil, err
+ }
+ opts.DNSOptions = append(opts.DNSOptions, options...)
+ }
+
if flags.Changed("dns-search") {
dnsSearches, err := flags.GetStringSlice("dns-search")
if err != nil {
diff --git a/cmd/podman/generate/generate.go b/cmd/podman/generate/generate.go
index 0a12961f4..f1dea6816 100644
--- a/cmd/podman/generate/generate.go
+++ b/cmd/podman/generate/generate.go
@@ -1,4 +1,4 @@
-package pods
+package generate
import (
"github.com/containers/podman/v4/cmd/podman/registry"
@@ -9,7 +9,7 @@ import (
var (
// Command: podman _generate_
- generateCmd = &cobra.Command{
+ GenerateCmd = &cobra.Command{
Use: "generate",
Short: "Generate structured data based on containers, pods or volumes",
Long: "Generate structured data (e.g., Kubernetes YAML or systemd units) based on containers, pods or volumes.",
@@ -20,6 +20,6 @@ var (
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
- Command: generateCmd,
+ Command: GenerateCmd,
})
}
diff --git a/cmd/podman/generate/kube.go b/cmd/podman/generate/kube.go
deleted file mode 100644
index 7bfc3dcf7..000000000
--- a/cmd/podman/generate/kube.go
+++ /dev/null
@@ -1,80 +0,0 @@
-package pods
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
-
- "github.com/containers/common/pkg/completion"
- "github.com/containers/podman/v4/cmd/podman/common"
- "github.com/containers/podman/v4/cmd/podman/registry"
- "github.com/containers/podman/v4/cmd/podman/utils"
- "github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/spf13/cobra"
-)
-
-var (
- kubeOptions = entities.GenerateKubeOptions{}
- kubeFile = ""
- kubeDescription = `Command generates Kubernetes Pod, Service or PersistenVolumeClaim YAML (v1 specification) from Podman containers, pods or volumes.
-
- Whether the input is for a container or pod, Podman will always generate the specification as a pod.`
-
- kubeCmd = &cobra.Command{
- Use: "kube [options] {CONTAINER...|POD...|VOLUME...}",
- Short: "Generate Kubernetes YAML from containers, pods or volumes.",
- Long: kubeDescription,
- RunE: kube,
- Args: cobra.MinimumNArgs(1),
- ValidArgsFunction: common.AutocompleteForKube,
- Example: `podman generate kube ctrID
- podman generate kube podID
- podman generate kube --service podID
- podman generate kube volumeName
- podman generate kube ctrID podID volumeName --service`,
- }
-)
-
-func init() {
- registry.Commands = append(registry.Commands, registry.CliCommand{
- Command: kubeCmd,
- Parent: generateCmd,
- })
- flags := kubeCmd.Flags()
- flags.BoolVarP(&kubeOptions.Service, "service", "s", false, "Generate YAML for a Kubernetes service object")
-
- filenameFlagName := "filename"
- flags.StringVarP(&kubeFile, filenameFlagName, "f", "", "Write output to the specified path")
- _ = kubeCmd.RegisterFlagCompletionFunc(filenameFlagName, completion.AutocompleteDefault)
-
- flags.SetNormalizeFunc(utils.AliasFlags)
-}
-
-func kube(cmd *cobra.Command, args []string) error {
- report, err := registry.ContainerEngine().GenerateKube(registry.GetContext(), args, kubeOptions)
- if err != nil {
- return err
- }
-
- content, err := ioutil.ReadAll(report.Reader)
- if err != nil {
- return err
- }
- if r, ok := report.Reader.(io.ReadCloser); ok {
- defer r.Close()
- }
-
- if cmd.Flags().Changed("filename") {
- if _, err := os.Stat(kubeFile); err == nil {
- return fmt.Errorf("cannot write to %q; file exists", kubeFile)
- }
- if err := ioutil.WriteFile(kubeFile, content, 0644); err != nil {
- return fmt.Errorf("cannot write to %q: %w", kubeFile, err)
- }
- return nil
- }
-
- fmt.Println(string(content))
- return nil
-}
diff --git a/cmd/podman/generate/spec.go b/cmd/podman/generate/spec.go
index 1cf967424..bf451ebc5 100644
--- a/cmd/podman/generate/spec.go
+++ b/cmd/podman/generate/spec.go
@@ -1,4 +1,4 @@
-package pods
+package generate
import (
"fmt"
@@ -31,7 +31,7 @@ var (
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: specCmd,
- Parent: generateCmd,
+ Parent: GenerateCmd,
})
opts = &entities.GenerateSpecOptions{}
flags := specCmd.Flags()
diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go
index 1ece64a30..e40416534 100644
--- a/cmd/podman/generate/systemd.go
+++ b/cmd/podman/generate/systemd.go
@@ -1,4 +1,4 @@
-package pods
+package generate
import (
"encoding/json"
@@ -57,7 +57,7 @@ var (
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: systemdCmd,
- Parent: generateCmd,
+ Parent: GenerateCmd,
})
flags := systemdCmd.Flags()
flags.BoolVarP(&systemdOptions.Name, "name", "n", false, "Use container/pod names instead of IDs")
diff --git a/cmd/podman/kube/down.go b/cmd/podman/kube/down.go
index b8c025928..a670d911c 100644
--- a/cmd/podman/kube/down.go
+++ b/cmd/podman/kube/down.go
@@ -1,4 +1,4 @@
-package pods
+package kube
import (
"github.com/containers/podman/v4/cmd/podman/common"
diff --git a/cmd/podman/kube/generate.go b/cmd/podman/kube/generate.go
new file mode 100644
index 000000000..6df4b55fc
--- /dev/null
+++ b/cmd/podman/kube/generate.go
@@ -0,0 +1,109 @@
+package kube
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v4/cmd/podman/common"
+ "github.com/containers/podman/v4/cmd/podman/generate"
+ "github.com/containers/podman/v4/cmd/podman/registry"
+ "github.com/containers/podman/v4/cmd/podman/utils"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/spf13/cobra"
+)
+
+var (
+ generateOptions = entities.GenerateKubeOptions{}
+ generateFile = ""
+ generateDescription = `Command generates Kubernetes Pod, Service or PersistenVolumeClaim YAML (v1 specification) from Podman containers, pods or volumes.
+
+ Whether the input is for a container or pod, Podman will always generate the specification as a pod.`
+
+ generateKubeCmd = &cobra.Command{
+ Use: "generate [options] {CONTAINER...|POD...|VOLUME...}",
+ Short: "Generate Kubernetes YAML from containers, pods or volumes.",
+ Long: generateDescription,
+ RunE: generateKube,
+ Args: cobra.MinimumNArgs(1),
+ ValidArgsFunction: common.AutocompleteForGenerate,
+ Example: `podman kube generate ctrID
+ podman kube generate podID
+ podman kube generate --service podID
+ podman kube generate volumeName
+ podman kube generate ctrID podID volumeName --service`,
+ }
+ kubeGenerateDescription = generateDescription
+
+ kubeGenerateCmd = &cobra.Command{
+ Use: "kube [options] {CONTAINER...|POD...|VOLUME...}",
+ Short: "Generate Kubernetes YAML from containers, pods or volumes.",
+ Long: kubeGenerateDescription,
+ RunE: kubeGenerate,
+ Args: cobra.MinimumNArgs(1),
+ ValidArgsFunction: common.AutocompleteForGenerate,
+ Example: `podman kube generate ctrID
+ podman kube generate podID
+ podman kube generate --service podID
+ podman kube generate volumeName
+ podman kube generate ctrID podID volumeName --service`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: generateKubeCmd,
+ Parent: kubeCmd,
+ })
+ generateFlags(generateKubeCmd)
+
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: kubeGenerateCmd,
+ Parent: generate.GenerateCmd,
+ })
+ generateFlags(kubeGenerateCmd)
+}
+
+func generateFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+ flags.BoolVarP(&generateOptions.Service, "service", "s", false, "Generate YAML for a Kubernetes service object")
+
+ filenameFlagName := "filename"
+ flags.StringVarP(&generateFile, filenameFlagName, "f", "", "Write output to the specified path")
+ _ = cmd.RegisterFlagCompletionFunc(filenameFlagName, completion.AutocompleteDefault)
+
+ flags.SetNormalizeFunc(utils.AliasFlags)
+}
+
+func generateKube(cmd *cobra.Command, args []string) error {
+ report, err := registry.ContainerEngine().GenerateKube(registry.GetContext(), args, generateOptions)
+ if err != nil {
+ return err
+ }
+ content, err := ioutil.ReadAll(report.Reader)
+ if err != nil {
+ return err
+ }
+ if r, ok := report.Reader.(io.ReadCloser); ok {
+ defer r.Close()
+ }
+
+ if cmd.Flags().Changed("filename") {
+ if _, err := os.Stat(generateFile); err == nil {
+ return fmt.Errorf("cannot write to %q; file exists", generateFile)
+ }
+ if err := ioutil.WriteFile(generateFile, content, 0644); err != nil {
+ return fmt.Errorf("cannot write to %q: %w", generateFile, err)
+ }
+ return nil
+ }
+
+ fmt.Println(string(content))
+ return nil
+}
+
+func kubeGenerate(cmd *cobra.Command, args []string) error {
+ return generateKube(cmd, args)
+}
diff --git a/cmd/podman/kube/kube.go b/cmd/podman/kube/kube.go
index 68f55a157..2dab68c19 100644
--- a/cmd/podman/kube/kube.go
+++ b/cmd/podman/kube/kube.go
@@ -1,4 +1,4 @@
-package pods
+package kube
import (
"github.com/containers/podman/v4/cmd/podman/registry"
@@ -14,7 +14,7 @@ var (
Long: "Play structured data (e.g., Kubernetes YAML) based on containers, pods or volumes.",
RunE: validate.SubCommandExists,
}
-
+ // Command: podman _play_
playKubeParentCmd = &cobra.Command{
Use: "play",
Short: "Play containers, pods or volumes from a structured file",
diff --git a/cmd/podman/kube/play.go b/cmd/podman/kube/play.go
index 07c4b59b9..d7719e28e 100644
--- a/cmd/podman/kube/play.go
+++ b/cmd/podman/kube/play.go
@@ -1,4 +1,4 @@
-package pods
+package kube
import (
"bytes"
@@ -47,7 +47,7 @@ var (
Use: "play [options] KUBEFILE|-",
Short: "Play a pod or volume based on Kubernetes YAML.",
Long: playDescription,
- RunE: Play,
+ RunE: play,
Args: cobra.ExactArgs(1),
ValidArgsFunction: common.AutocompleteDefaultOneArg,
Example: `podman kube play nginx.yml
@@ -181,11 +181,10 @@ func playFlags(cmd *cobra.Command) {
}
}
-func Play(cmd *cobra.Command, args []string) error {
+func play(cmd *cobra.Command, args []string) error {
if playOptions.ServiceContainer && !playOptions.StartCLI { // Sanity check to be future proof
return fmt.Errorf("--service-container does not work with --start=stop")
}
-
// TLS verification in c/image is controlled via a `types.OptionalBool`
// which allows for distinguishing among set-true, set-false, unspecified
// which is important to implement a sane way of dealing with defaults of
@@ -260,7 +259,7 @@ func Play(cmd *cobra.Command, args []string) error {
}
func playKube(cmd *cobra.Command, args []string) error {
- return Play(cmd, args)
+ return play(cmd, args)
}
func readerFromArg(fileName string) (*bytes.Reader, error) {
diff --git a/cmd/podman/manifest/add.go b/cmd/podman/manifest/add.go
index 35583ffcb..09a1a9a36 100644
--- a/cmd/podman/manifest/add.go
+++ b/cmd/podman/manifest/add.go
@@ -2,6 +2,7 @@ package manifest
import (
"context"
+ "errors"
"fmt"
"github.com/containers/common/pkg/auth"
@@ -20,6 +21,7 @@ type manifestAddOptsWrapper struct {
entities.ManifestAddOptions
TLSVerifyCLI bool // CLI only
+ Insecure bool // CLI only
CredentialsCLI string
}
@@ -77,6 +79,8 @@ func init() {
flags.StringVar(&manifestAddOpts.OSVersion, osVersionFlagName, "", "override the OS `version` of the specified image")
_ = addCmd.RegisterFlagCompletionFunc(osVersionFlagName, completion.AutocompleteNone)
+ flags.BoolVar(&manifestAddOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
+ _ = flags.MarkHidden("insecure")
flags.BoolVar(&manifestAddOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
variantFlagName := "variant"
@@ -89,7 +93,7 @@ func init() {
}
func add(cmd *cobra.Command, args []string) error {
- if err := auth.CheckAuthFile(manifestPushOpts.Authfile); err != nil {
+ if err := auth.CheckAuthFile(manifestAddOpts.Authfile); err != nil {
return err
}
@@ -109,6 +113,12 @@ func add(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("tls-verify") {
manifestAddOpts.SkipTLSVerify = types.NewOptionalBool(!manifestAddOpts.TLSVerifyCLI)
}
+ if cmd.Flags().Changed("insecure") {
+ if manifestAddOpts.SkipTLSVerify != types.OptionalBoolUndefined {
+ return errors.New("--insecure may not be used with --tls-verify")
+ }
+ manifestAddOpts.SkipTLSVerify = types.NewOptionalBool(manifestAddOpts.Insecure)
+ }
listID, err := registry.ImageEngine().ManifestAdd(context.Background(), args[0], args[1:], manifestAddOpts.ManifestAddOptions)
if err != nil {
diff --git a/cmd/podman/manifest/create.go b/cmd/podman/manifest/create.go
index 435b4a57c..0a0ea1d88 100644
--- a/cmd/podman/manifest/create.go
+++ b/cmd/podman/manifest/create.go
@@ -1,16 +1,26 @@
package manifest
import (
+ "errors"
"fmt"
+ "github.com/containers/image/v5/types"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/spf13/cobra"
)
+// manifestCreateOptsWrapper wraps entities.ManifestCreateOptions and prevents leaking
+// CLI-only fields into the API types.
+type manifestCreateOptsWrapper struct {
+ entities.ManifestCreateOptions
+
+ TLSVerifyCLI, Insecure bool // CLI only
+}
+
var (
- manifestCreateOpts = entities.ManifestCreateOptions{}
+ manifestCreateOpts = manifestCreateOptsWrapper{}
createCmd = &cobra.Command{
Use: "create [options] LIST [IMAGE...]",
Short: "Create manifest list or image index",
@@ -32,10 +42,28 @@ func init() {
})
flags := createCmd.Flags()
flags.BoolVar(&manifestCreateOpts.All, "all", false, "add all of the lists' images if the images to add are lists")
+ flags.BoolVar(&manifestCreateOpts.Amend, "amend", false, "modify an existing list if one with the desired name already exists")
+ flags.BoolVar(&manifestCreateOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
+ _ = flags.MarkHidden("insecure")
+ flags.BoolVar(&manifestCreateOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
}
func create(cmd *cobra.Command, args []string) error {
- imageID, err := registry.ImageEngine().ManifestCreate(registry.Context(), args[0], args[1:], manifestCreateOpts)
+ // TLS verification in c/image is controlled via a `types.OptionalBool`
+ // which allows for distinguishing among set-true, set-false, unspecified
+ // which is important to implement a sane way of dealing with defaults of
+ // boolean CLI flags.
+ if cmd.Flags().Changed("tls-verify") {
+ manifestCreateOpts.SkipTLSVerify = types.NewOptionalBool(!manifestCreateOpts.TLSVerifyCLI)
+ }
+ if cmd.Flags().Changed("insecure") {
+ if manifestCreateOpts.SkipTLSVerify != types.OptionalBoolUndefined {
+ return errors.New("--insecure may not be used with --tls-verify")
+ }
+ manifestCreateOpts.SkipTLSVerify = types.NewOptionalBool(manifestCreateOpts.Insecure)
+ }
+
+ imageID, err := registry.ImageEngine().ManifestCreate(registry.Context(), args[0], args[1:], manifestCreateOpts.ManifestCreateOptions)
if err != nil {
return err
}
diff --git a/cmd/podman/manifest/push.go b/cmd/podman/manifest/push.go
index 756ed2a74..fd67769b8 100644
--- a/cmd/podman/manifest/push.go
+++ b/cmd/podman/manifest/push.go
@@ -1,6 +1,7 @@
package manifest
import (
+ "errors"
"fmt"
"io/ioutil"
@@ -20,9 +21,9 @@ import (
type manifestPushOptsWrapper struct {
entities.ImagePushOptions
- TLSVerifyCLI bool // CLI only
- CredentialsCLI string
- SignPassphraseFileCLI string
+ TLSVerifyCLI, Insecure bool // CLI only
+ CredentialsCLI string
+ SignPassphraseFileCLI string
}
var (
@@ -82,6 +83,8 @@ func init() {
_ = pushCmd.RegisterFlagCompletionFunc(signPassphraseFileFlagName, completion.AutocompleteDefault)
flags.BoolVar(&manifestPushOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
+ flags.BoolVar(&manifestPushOpts.Insecure, "insecure", false, "neither require HTTPS nor verify certificates when accessing the registry")
+ _ = flags.MarkHidden("insecure")
flags.BoolVarP(&manifestPushOpts.Quiet, "quiet", "q", false, "don't output progress information when pushing lists")
flags.SetNormalizeFunc(utils.AliasFlags)
@@ -130,6 +133,12 @@ func push(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("tls-verify") {
manifestPushOpts.SkipTLSVerify = types.NewOptionalBool(!manifestPushOpts.TLSVerifyCLI)
}
+ if cmd.Flags().Changed("insecure") {
+ if manifestPushOpts.SkipTLSVerify != types.OptionalBoolUndefined {
+ return errors.New("--insecure may not be used with --tls-verify")
+ }
+ manifestPushOpts.SkipTLSVerify = types.NewOptionalBool(manifestPushOpts.Insecure)
+ }
digest, err := registry.ImageEngine().ManifestPush(registry.Context(), args[0], args[1], manifestPushOpts.ImagePushOptions)
if err != nil {
return err
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index 3637b2674..f45dc94b2 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -71,7 +71,10 @@ var (
DisableFlagsInUseLine: true,
}
- logLevel = "warn"
+ defaultLogLevel = "warn"
+ logLevel = defaultLogLevel
+ debug bool
+
useSyslog bool
requireCleanup = true
)
@@ -310,6 +313,13 @@ func persistentPostRunE(cmd *cobra.Command, args []string) error {
func loggingHook() {
var found bool
+ if debug {
+ if logLevel != defaultLogLevel {
+ fmt.Fprintf(os.Stderr, "Setting --log-level and --debug is not allowed\n")
+ os.Exit(1)
+ }
+ logLevel = "debug"
+ }
for _, l := range common.LogLevels {
if l == strings.ToLower(logLevel) {
found = true
@@ -465,6 +475,9 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
pFlags.StringVar(&logLevel, logLevelFlagName, logLevel, fmt.Sprintf("Log messages above specified level (%s)", strings.Join(common.LogLevels, ", ")))
_ = rootCmd.RegisterFlagCompletionFunc(logLevelFlagName, common.AutocompleteLogLevel)
+ pFlags.BoolVar(&debug, "debug", false, "Docker compatibility, force setting of log-level")
+ _ = pFlags.MarkHidden("debug")
+
// Only create these flags for ABI connections
if !registry.IsRemote() {
runtimeflagFlagName := "runtime-flag"