diff options
184 files changed, 1751 insertions, 1047 deletions
diff --git a/cmd/podman-mac-helper/main.go b/cmd/podman-mac-helper/main.go index 937cb8433..ef57341bc 100644 --- a/cmd/podman-mac-helper/main.go +++ b/cmd/podman-mac-helper/main.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "regexp" @@ -131,7 +130,7 @@ func readCapped(reader io.Reader) string { // Cap output buffer := make([]byte, 2048) n, _ := io.ReadFull(reader, buffer) - _, _ = io.Copy(ioutil.Discard, reader) + _, _ = io.Copy(io.Discard, reader) if n > 0 { return string(buffer[:n]) } diff --git a/cmd/podman/containers/commit.go b/cmd/podman/containers/commit.go index fb6dccad4..77f74395e 100644 --- a/cmd/podman/containers/commit.go +++ b/cmd/podman/containers/commit.go @@ -3,7 +3,6 @@ package containers import ( "context" "fmt" - "io/ioutil" "os" "strings" @@ -107,7 +106,7 @@ func commit(cmd *cobra.Command, args []string) error { return err } if len(iidFile) > 0 { - if err = ioutil.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(iidFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write image ID: %w", err) } } diff --git a/cmd/podman/containers/cp.go b/cmd/podman/containers/cp.go index 93477feb8..9e63169a0 100644 --- a/cmd/podman/containers/cp.go +++ b/cmd/podman/containers/cp.go @@ -3,7 +3,6 @@ package containers import ( "fmt" "io" - "io/ioutil" "os" "os/user" "path/filepath" @@ -379,7 +378,7 @@ func copyToContainer(container string, containerPath string, hostPath string) er // Copy from stdin to a temporary file *before* throwing it // over the wire. This allows for proper client-side error // reporting. - tmpFile, err := ioutil.TempFile("", "") + tmpFile, err := os.CreateTemp("", "") if err != nil { return err } diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go index 86a7e3ff2..3c9bf6b71 100644 --- a/cmd/podman/containers/kill.go +++ b/cmd/podman/containers/kill.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -96,7 +96,7 @@ func kill(_ *cobra.Command, args []string) error { return errors.New("valid signals are 1 through 64") } for _, cidFile := range killCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go index 591523cf9..ea5dd3a0c 100644 --- a/cmd/podman/containers/pause.go +++ b/cmd/podman/containers/pause.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -92,7 +92,7 @@ func pause(cmd *cobra.Command, args []string) error { ) for _, cidFile := range pauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/restart.go b/cmd/podman/containers/restart.go index 0cc7901f9..db2759f0b 100644 --- a/cmd/podman/containers/restart.go +++ b/cmd/podman/containers/restart.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func restart(cmd *cobra.Command, args []string) error { } for _, cidFile := range restartCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go index 44d03e9de..da5c24ab8 100644 --- a/cmd/podman/containers/rm.go +++ b/cmd/podman/containers/rm.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -108,7 +108,7 @@ func rm(cmd *cobra.Command, args []string) error { rmOptions.Timeout = &stopTimeout } for _, cidFile := range rmCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go index 412c513e1..a1e3a0c46 100644 --- a/cmd/podman/containers/stop.go +++ b/cmd/podman/containers/stop.go @@ -3,7 +3,7 @@ package containers import ( "context" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/completion" @@ -105,7 +105,7 @@ func stop(cmd *cobra.Command, args []string) error { stopOptions.Timeout = &stopTimeout } for _, cidFile := range stopCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go index 988964266..fea05ee22 100644 --- a/cmd/podman/containers/unpause.go +++ b/cmd/podman/containers/unpause.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "strings" "github.com/containers/common/pkg/cgroups" @@ -99,7 +99,7 @@ func unpause(cmd *cobra.Command, args []string) error { } for _, cidFile := range unpauseCidFiles { - content, err := ioutil.ReadFile(cidFile) + content, err := os.ReadFile(cidFile) if err != nil { return fmt.Errorf("reading CIDFile: %w", err) } diff --git a/cmd/podman/generate/spec.go b/cmd/podman/generate/spec.go index bf451ebc5..0c3d7884c 100644 --- a/cmd/podman/generate/spec.go +++ b/cmd/podman/generate/spec.go @@ -2,7 +2,7 @@ package generate import ( "fmt" - "io/ioutil" + "os" "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" @@ -59,7 +59,7 @@ func spec(cmd *cobra.Command, args []string) error { // if we are looking to print the output, do not mess it up by printing the path // if we are using -v the user probably expects to pipe the output somewhere else if len(opts.FileName) > 0 { - err = ioutil.WriteFile(opts.FileName, report.Data, 0644) + err = os.WriteFile(opts.FileName, report.Data, 0644) if err != nil { return err } diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 2b24c1cff..a4d6614e2 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -635,7 +634,7 @@ func getDecryptConfig(decryptionKeys []string) (*encconfig.DecryptConfig, error) func parseDockerignore(ignoreFile string) ([]string, error) { excludes := []string{} - ignore, err := ioutil.ReadFile(ignoreFile) + ignore, err := os.ReadFile(ignoreFile) if err != nil { return excludes, err } diff --git a/cmd/podman/images/import.go b/cmd/podman/images/import.go index 8343a0bda..7532bf7a9 100644 --- a/cmd/podman/images/import.go +++ b/cmd/podman/images/import.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -116,7 +115,7 @@ func importCon(cmd *cobra.Command, args []string) error { } if source == "-" { - outFile, err := ioutil.TempFile("", "podman") + outFile, err := os.CreateTemp("", "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/load.go b/cmd/podman/images/load.go index 367b628c7..4aae5217d 100644 --- a/cmd/podman/images/load.go +++ b/cmd/podman/images/load.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "strings" @@ -93,7 +92,7 @@ func load(cmd *cobra.Command, args []string) error { if term.IsTerminal(int(os.Stdin.Fd())) { return errors.New("cannot read from terminal, use command-line redirection or the --input flag") } - outFile, err := ioutil.TempFile(util.Tmpdir(), "podman") + outFile, err := os.CreateTemp(util.Tmpdir(), "podman") if err != nil { return fmt.Errorf("creating file %v", err) } diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go index ecff0f841..426684d49 100644 --- a/cmd/podman/images/save.go +++ b/cmd/podman/images/save.go @@ -96,6 +96,11 @@ func saveFlags(cmd *cobra.Command) { flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") flags.BoolVarP(&saveOpts.MultiImageArchive, "multi-image-archive", "m", containerConfig.Engine.MultiImageArchive, "Interpret additional arguments as images not tags and create a multi-image-archive (only for docker-archive)") + + if !registry.IsRemote() { + flags.StringVar(&saveOpts.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") + _ = flags.MarkHidden("signature-policy") + } } func save(cmd *cobra.Command, args []string) (finalErr error) { diff --git a/cmd/podman/images/utils_linux.go b/cmd/podman/images/utils_linux.go index 935a45667..a2f471a48 100644 --- a/cmd/podman/images/utils_linux.go +++ b/cmd/podman/images/utils_linux.go @@ -3,7 +3,6 @@ package images import ( "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -16,7 +15,7 @@ import ( // the caller should use the returned function to clean up the pipeDir func setupPipe() (string, func() <-chan error, error) { errc := make(chan error) - pipeDir, err := ioutil.TempDir(os.TempDir(), "pipeDir") + pipeDir, err := os.MkdirTemp(os.TempDir(), "pipeDir") if err != nil { return "", nil, err } diff --git a/cmd/podman/kube/generate.go b/cmd/podman/kube/generate.go index ee2ea51ae..30b06b0c5 100644 --- a/cmd/podman/kube/generate.go +++ b/cmd/podman/kube/generate.go @@ -3,7 +3,6 @@ package kube import ( "fmt" "io" - "io/ioutil" "os" "github.com/containers/common/pkg/completion" @@ -77,7 +76,7 @@ func generateKube(cmd *cobra.Command, args []string) error { if err != nil { return err } - content, err := ioutil.ReadAll(report.Reader) + content, err := io.ReadAll(report.Reader) if err != nil { return err } @@ -89,7 +88,7 @@ func generateKube(cmd *cobra.Command, args []string) error { 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 { + if err := os.WriteFile(generateFile, content, 0644); err != nil { return fmt.Errorf("cannot write to %q: %w", generateFile, err) } return nil diff --git a/cmd/podman/kube/play.go b/cmd/podman/kube/play.go index c846ec32c..1163a6ff6 100644 --- a/cmd/podman/kube/play.go +++ b/cmd/podman/kube/play.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -284,7 +283,7 @@ func readerFromArg(fileName string) (*bytes.Reader, error) { } defer response.Body.Close() - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return nil, err } diff --git a/cmd/podman/manifest/push.go b/cmd/podman/manifest/push.go index c8893ff2e..2b4c570a5 100644 --- a/cmd/podman/manifest/push.go +++ b/cmd/podman/manifest/push.go @@ -3,7 +3,6 @@ package manifest import ( "errors" "fmt" - "io/ioutil" "os" "github.com/containers/common/pkg/auth" @@ -149,7 +148,7 @@ func push(cmd *cobra.Command, args []string) error { return err } if manifestPushOpts.DigestFile != "" { - if err := ioutil.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { + if err := os.WriteFile(manifestPushOpts.DigestFile, []byte(digest), 0644); err != nil { return err } } diff --git a/cmd/podman/parse/net_test.go b/cmd/podman/parse/net_test.go index a11edc2ca..88bfaa894 100644 --- a/cmd/podman/parse/net_test.go +++ b/cmd/podman/parse/net_test.go @@ -3,7 +3,6 @@ package parse import ( - "io/ioutil" "os" "testing" @@ -15,7 +14,7 @@ var ( ) func createTmpFile(content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(os.TempDir(), "unittest") + tmpfile, err := os.CreateTemp(os.TempDir(), "unittest") if err != nil { return "", err } diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go index 1f8152f32..fc2e07894 100644 --- a/cmd/podman/pods/create.go +++ b/cmd/podman/pods/create.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "runtime" "sort" @@ -300,7 +299,7 @@ func create(cmd *cobra.Command, args []string) error { } if len(podIDFile) > 0 { - if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { + if err = os.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil { return fmt.Errorf("failed to write pod ID to file: %w", err) } } diff --git a/cmd/podman/registry/remote.go b/cmd/podman/registry/remote.go index afe32e0b9..02aa31c58 100644 --- a/cmd/podman/registry/remote.go +++ b/cmd/podman/registry/remote.go @@ -32,6 +32,8 @@ func IsRemote() bool { fs.BoolVarP(&remoteFromCLI.Value, "remote", "r", remote, "") connectionFlagName := "connection" fs.StringP(connectionFlagName, "c", "", "") + contextFlagName := "context" + fs.String(contextFlagName, "", "") hostFlagName := "host" fs.StringP(hostFlagName, "H", "", "") urlFlagName := "url" @@ -46,7 +48,7 @@ func IsRemote() bool { } _ = fs.Parse(os.Args[start:]) // --connection or --url implies --remote - remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) + remoteFromCLI.Value = remoteFromCLI.Value || fs.Changed(connectionFlagName) || fs.Changed(urlFlagName) || fs.Changed(hostFlagName) || fs.Changed(contextFlagName) }) return podmanOptions.EngineMode == entities.TunnelMode || remoteFromCLI.Value } diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 2e00777a4..9e3ff48aa 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -174,11 +174,7 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - // --connection is not as "special" as --remote so we can wait and process it here - conn := cmd.Root().LocalFlags().Lookup("connection") - if conn != nil && conn.Changed { - cfg.Engine.ActiveService = conn.Value.String() - + setupConnection := func() error { var err error cfg.URI, cfg.Identity, err = cfg.ActiveDestination() if err != nil { @@ -192,6 +188,29 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { if err := cmd.Root().LocalFlags().Set("identity", cfg.Identity); err != nil { return fmt.Errorf("failed to override --identity flag: %w", err) } + return nil + } + + // --connection is not as "special" as --remote so we can wait and process it here + contextConn := cmd.Root().LocalFlags().Lookup("context") + conn := cmd.Root().LocalFlags().Lookup("connection") + if conn != nil && conn.Changed { + if contextConn != nil && contextConn.Changed { + return fmt.Errorf("use of --connection and --context at the same time is not allowed") + } + cfg.Engine.ActiveService = conn.Value.String() + if err := setupConnection(); err != nil { + return err + } + } + if contextConn != nil && contextConn.Changed { + service := contextConn.Value.String() + if service != "default" { + cfg.Engine.ActiveService = service + if err := setupConnection(); err != nil { + return err + } + } } // Special case if command is hidden completion command ("__complete","__completeNoDesc") @@ -232,10 +251,6 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { } } - context := cmd.Root().LocalFlags().Lookup("context") - if context.Value.String() != "default" { - return errors.New("podman does not support swarm, the only --context value allowed is \"default\"") - } if !registry.IsRemote() { if cmd.Flag("cpu-profile").Changed { f, err := os.Create(cfg.CPUProfile) @@ -362,7 +377,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) { _ = cmd.RegisterFlagCompletionFunc(sshFlagName, common.AutocompleteSSH) connectionFlagName := "connection" - lFlags.StringVarP(&opts.Engine.ActiveService, connectionFlagName, "c", srv, "Connection to use for remote Podman service") + lFlags.StringP(connectionFlagName, "c", srv, "Connection to use for remote Podman service") _ = cmd.RegisterFlagCompletionFunc(connectionFlagName, common.AutocompleteSystemConnections) urlFlagName := "url" diff --git a/cmd/podman/secrets/create.go b/cmd/podman/secrets/create.go index 01775f563..293da2103 100644 --- a/cmd/podman/secrets/create.go +++ b/cmd/podman/secrets/create.go @@ -10,6 +10,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/podman/v4/cmd/podman/common" + "github.com/containers/podman/v4/cmd/podman/parse" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/spf13/cobra" @@ -31,6 +32,7 @@ var ( var ( createOpts = entities.SecretCreateOptions{} env = false + labels []string ) func init() { @@ -38,21 +40,24 @@ func init() { Command: createCmd, Parent: secretCmd, }) + cfg := registry.PodmanConfig() flags := createCmd.Flags() driverFlagName := "driver" - optsFlagName := "driver-opts" - - cfg := registry.PodmanConfig() - flags.StringVarP(&createOpts.Driver, driverFlagName, "d", cfg.Secrets.Driver, "Specify secret driver") - flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(driverFlagName, completion.AutocompleteNone) + + optsFlagName := "driver-opts" + flags.StringToStringVar(&createOpts.DriverOpts, optsFlagName, cfg.Secrets.Opts, "Specify driver specific options") _ = createCmd.RegisterFlagCompletionFunc(optsFlagName, completion.AutocompleteNone) envFlagName := "env" flags.BoolVar(&env, envFlagName, false, "Read secret data from environment variable") + + labelFlagName := "label" + flags.StringArrayVarP(&labels, labelFlagName, "l", nil, "Specify labels on the secret") + _ = createCmd.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone) } func create(cmd *cobra.Command, args []string) error { @@ -87,6 +92,11 @@ func create(cmd *cobra.Command, args []string) error { reader = file } + createOpts.Labels, err = parse.GetAllLabels([]string{}, labels) + if err != nil { + return fmt.Errorf("unable to process labels: %w", err) + } + report, err := registry.ContainerEngine().SecretCreate(context.Background(), name, reader, createOpts) if err != nil { return err diff --git a/cmd/podman/system/connection/add.go b/cmd/podman/system/connection/add.go index f3b61b254..2730ebfb7 100644 --- a/cmd/podman/system/connection/add.go +++ b/cmd/podman/system/connection/add.go @@ -6,6 +6,7 @@ import ( "net/url" "os" "regexp" + "strings" "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" @@ -37,6 +38,17 @@ var ( `, } + createCmd = &cobra.Command{ + Use: "create [options] NAME DESTINATION", + Args: cobra.ExactArgs(1), + Short: addCmd.Short, + Long: addCmd.Long, + RunE: create, + ValidArgsFunction: completion.AutocompleteNone, + } + + dockerPath string + cOpts = struct { Identity string Port int @@ -50,7 +62,6 @@ func init() { Command: addCmd, Parent: system.ConnectionCmd, }) - flags := addCmd.Flags() portFlagName := "port" @@ -66,6 +77,21 @@ func init() { _ = addCmd.RegisterFlagCompletionFunc(socketPathFlagName, completion.AutocompleteDefault) flags.BoolVarP(&cOpts.Default, "default", "d", false, "Set connection to be default") + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: createCmd, + Parent: system.ContextCmd, + }) + + flags = createCmd.Flags() + dockerFlagName := "docker" + flags.StringVar(&dockerPath, dockerFlagName, "", "Description of the context") + + _ = createCmd.RegisterFlagCompletionFunc(dockerFlagName, completion.AutocompleteNone) + flags.String("description", "", "Ignored. Just for script compatibility") + flags.String("from", "", "Ignored. Just for script compatibility") + flags.String("kubernetes", "", "Ignored. Just for script compatibility") + flags.String("default-stack-orchestrator", "", "Ignored. Just for script compatibility") } func add(cmd *cobra.Command, args []string) error { @@ -171,3 +197,59 @@ func add(cmd *cobra.Command, args []string) error { } return cfg.Write() } + +func create(cmd *cobra.Command, args []string) error { + dest, err := translateDest(dockerPath) + if err != nil { + return err + } + if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil { + return fmt.Errorf("invalid destination: %w", err) + } else if !match { + dest = "ssh://" + dest + } + + uri, err := url.Parse(dest) + if err != nil { + return err + } + + cfg, err := config.ReadCustomConfig() + if err != nil { + return err + } + + dst := config.Destination{ + URI: uri.String(), + } + + if cfg.Engine.ServiceDestinations == nil { + cfg.Engine.ServiceDestinations = map[string]config.Destination{ + args[0]: dst, + } + cfg.Engine.ActiveService = args[0] + } else { + cfg.Engine.ServiceDestinations[args[0]] = dst + } + return cfg.Write() +} + +func translateDest(path string) (string, error) { + if path == "" { + return "", nil + } + split := strings.SplitN(path, "=", 2) + if len(split) == 1 { + return split[0], nil + } + if split[0] != "host" { + return "", fmt.Errorf("\"host\" is requited for --docker option") + } + // "host=tcp://myserver:2376,ca=~/ca-file,cert=~/cert-file,key=~/key-file" + vals := strings.Split(split[1], ",") + if len(vals) > 1 { + return "", fmt.Errorf("--docker additional options %q not supported", strings.Join(vals[1:], ",")) + } + // for now we ignore other fields specified on command line + return vals[0], nil +} diff --git a/cmd/podman/system/connection/default.go b/cmd/podman/system/connection/default.go index 81866df55..8d1709e9f 100644 --- a/cmd/podman/system/connection/default.go +++ b/cmd/podman/system/connection/default.go @@ -21,10 +21,24 @@ var ( RunE: defaultRunE, Example: `podman system connection default testing`, } + + useCmd = &cobra.Command{ + Use: "use NAME", + Args: cobra.ExactArgs(1), + Short: dfltCmd.Short, + Long: dfltCmd.Long, + ValidArgsFunction: dfltCmd.ValidArgsFunction, + RunE: dfltCmd.RunE, + Example: `podman context use testing`, + } ) func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: useCmd, + Parent: system.ContextCmd, + }) + registry.Commands = append(registry.Commands, registry.CliCommand{ Command: dfltCmd, Parent: system.ConnectionCmd, }) diff --git a/cmd/podman/system/connection/list.go b/cmd/podman/system/connection/list.go index 2c5f6a310..190a68d52 100644 --- a/cmd/podman/system/connection/list.go +++ b/cmd/podman/system/connection/list.go @@ -8,6 +8,7 @@ import ( "github.com/containers/common/pkg/completion" "github.com/containers/common/pkg/config" "github.com/containers/common/pkg/report" + "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/cmd/podman/common" "github.com/containers/podman/v4/cmd/podman/registry" "github.com/containers/podman/v4/cmd/podman/system" @@ -29,16 +30,36 @@ var ( RunE: list, TraverseChildren: false, } + inspectCmd = &cobra.Command{ + Use: "inspect [options] [CONTEXT] [CONTEXT...]", + Short: "Inspect destination for a Podman service(s)", + ValidArgsFunction: completion.AutocompleteNone, + RunE: inspect, + } ) func init() { + initFlags := func(cmd *cobra.Command) { + cmd.Flags().StringP("format", "f", "", "Custom Go template for printing connections") + _ = cmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + cmd.Flags().BoolP("quiet", "q", false, "Custom Go template for printing connections") + } + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: listCmd, + Parent: system.ContextCmd, + }) registry.Commands = append(registry.Commands, registry.CliCommand{ Command: listCmd, Parent: system.ConnectionCmd, }) + initFlags(listCmd) - listCmd.Flags().String("format", "", "Custom Go template for printing connections") - _ = listCmd.RegisterFlagCompletionFunc("format", common.AutocompleteFormat(&namedDestination{})) + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: inspectCmd, + Parent: system.ContextCmd, + }) + initFlags(inspectCmd) } type namedDestination struct { @@ -48,13 +69,34 @@ type namedDestination struct { } func list(cmd *cobra.Command, _ []string) error { + return inspect(cmd, nil) +} + +func inspect(cmd *cobra.Command, args []string) error { cfg, err := config.ReadCustomConfig() if err != nil { return err } + format := cmd.Flag("format").Value.String() + if format == "" && args != nil { + format = "json" + } + + quiet, err := cmd.Flags().GetBool("quiet") + if err != nil { + return err + } rows := make([]namedDestination, 0) for k, v := range cfg.Engine.ServiceDestinations { + if args != nil && !util.StringInSlice(k, args) { + continue + } + + if quiet { + fmt.Println(k) + continue + } def := false if k == cfg.Engine.ActiveService { def = true @@ -71,6 +113,10 @@ func list(cmd *cobra.Command, _ []string) error { rows = append(rows, r) } + if quiet { + return nil + } + sort.Slice(rows, func(i, j int) bool { return rows[i].Name < rows[j].Name }) @@ -78,7 +124,7 @@ func list(cmd *cobra.Command, _ []string) error { rpt := report.New(os.Stdout, cmd.Name()) defer rpt.Flush() - if report.IsJSON(cmd.Flag("format").Value.String()) { + if report.IsJSON(format) { buf, err := registry.JSONLibrary().MarshalIndent(rows, "", " ") if err == nil { fmt.Println(string(buf)) @@ -86,8 +132,8 @@ func list(cmd *cobra.Command, _ []string) error { return err } - if cmd.Flag("format").Changed { - rpt, err = rpt.Parse(report.OriginUser, cmd.Flag("format").Value.String()) + if format != "" { + rpt, err = rpt.Parse(report.OriginUser, format) } else { rpt, err = rpt.Parse(report.OriginPodman, "{{range .}}{{.Name}}\t{{.URI}}\t{{.Identity}}\t{{.Default}}\n{{end -}}") diff --git a/cmd/podman/system/connection/remove.go b/cmd/podman/system/connection/remove.go index 29bf98c43..5ff0000d6 100644 --- a/cmd/podman/system/connection/remove.go +++ b/cmd/podman/system/connection/remove.go @@ -31,11 +31,19 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ Command: rmCmd, + Parent: system.ContextCmd, + }) + + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: rmCmd, Parent: system.ConnectionCmd, }) flags := rmCmd.Flags() flags.BoolVarP(&rmOpts.All, "all", "a", false, "Remove all connections") + + flags.BoolP("force", "f", false, "Ignored: for Docker compatibility") + _ = flags.MarkHidden("force") } func rm(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/system/context.go b/cmd/podman/system/context.go new file mode 100644 index 000000000..926e4a443 --- /dev/null +++ b/cmd/podman/system/context.go @@ -0,0 +1,28 @@ +package system + +import ( + "github.com/containers/podman/v4/cmd/podman/registry" + "github.com/containers/podman/v4/cmd/podman/validate" + "github.com/spf13/cobra" +) + +var ( + // ContextCmd skips creating engines (PersistentPreRunE/PersistentPostRunE are No-Op's) since + // sub-commands will obtain connection information to said engines + ContextCmd = &cobra.Command{ + Use: "context", + Short: "Manage remote API service destinations", + Long: `Manage remote API service destination information in podman configuration`, + PersistentPreRunE: validate.NoOp, + RunE: validate.SubCommandExists, + PersistentPostRunE: validate.NoOp, + Hidden: true, + TraverseChildren: false, + } +) + +func init() { + registry.Commands = append(registry.Commands, registry.CliCommand{ + Command: ContextCmd, + }) +} diff --git a/cmd/rootlessport/main.go b/cmd/rootlessport/main.go index d8d6ffcee..2508eb1c2 100644 --- a/cmd/rootlessport/main.go +++ b/cmd/rootlessport/main.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -50,7 +49,7 @@ func main() { } func loadConfig(r io.Reader) (*rootlessport.Config, io.ReadCloser, io.WriteCloser, error) { - stdin, err := ioutil.ReadAll(r) + stdin, err := io.ReadAll(r) if err != nil { return nil, nil, nil, err } @@ -92,7 +91,7 @@ func parent() error { } // create the parent driver - stateDir, err := ioutil.TempDir(cfg.TmpDir, "rootlessport") + stateDir, err := os.MkdirTemp(cfg.TmpDir, "rootlessport") if err != nil { return err } @@ -240,7 +239,7 @@ outer: // wait for ExitFD to be closed logrus.Info("Waiting for exitfd to be closed") - if _, err := ioutil.ReadAll(exitR); err != nil { + if _, err := io.ReadAll(exitR); err != nil { return err } return nil @@ -357,7 +356,7 @@ func child() error { }() // wait for stdin to be closed - if _, err := ioutil.ReadAll(os.Stdin); err != nil { + if _, err := io.ReadAll(os.Stdin); err != nil { return err } return nil diff --git a/docs/source/markdown/podman-events.1.md b/docs/source/markdown/podman-events.1.md index d0c95fe06..dd62ef5a2 100644 --- a/docs/source/markdown/podman-events.1.md +++ b/docs/source/markdown/podman-events.1.md @@ -95,6 +95,20 @@ In the case where an ID is used, the ID may be in its full or shortened form. Format the output to JSON Lines or using the given Go template. +| **Placeholder** | **Description** | +|--------------------|-----------------------------------------------| +| .Attributes | created_at, _by, labels, and more (map[]) | +| .ContainerExitCode | Exit code (int) | +| .Details ... | Internal structure, not actually useful | +| .HealthStatus | Health Status (string) | +| .ID | Container ID (full 64-bit SHA) | +| .Image | Name of image being run (string) | +| .Name | Container name (string) | +| .Network | Name of network being used (string) | +| .Status | Event status (e.g., create, start, died, ...) | +| .Time | Event timestamp (string) | +| .Type | Event type (e.g., image, container, pod, ...) | + #### **--help** Print usage statement. diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md index b733cff8d..190b21b71 100644 --- a/docs/source/markdown/podman-generate-systemd.1.md +++ b/docs/source/markdown/podman-generate-systemd.1.md @@ -141,7 +141,8 @@ RequiresMountsFor=/var/run/container/storage [Service] Restart=always ExecStart=/usr/bin/podman start de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 -ExecStop=/usr/bin/podman stop -t 1 de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 +ExecStop=/usr/bin/podman stop \ + -t 1 de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6 KillMode=none Type=forking PIDFile=/run/user/1000/overlay-containers/de1e3223b1b888bc02d0962dd6cb5855eb00734061013ffdd3479d225abacdc6/userdata/conmon.pid @@ -171,14 +172,19 @@ RequiresMountsFor=/var/run/container/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure ExecStartPre=/bin/rm -f %t/%n-pid %t/%n-cid -ExecStart=/usr/local/bin/podman run - --conmon-pidfile %t/%n-pid - --cidfile %t/%n-cid - --cgroups=no-conmon - -d +ExecStart=/usr/local/bin/podman run \ + --conmon-pidfile %t/%n-pid \ + --cidfile %t/%n-cid \ + --cgroups=no-conmon \ + -d \ -dit alpine -ExecStop=/usr/local/bin/podman stop --ignore --cidfile %t/%n-cid -t 10 -ExecStopPost=/usr/local/bin/podman rm --ignore -f --cidfile %t/%n-cid +ExecStop=/usr/local/bin/podman stop \ + --ignore \ + --cidfile %t/%n-cid -t 10 +ExecStopPost=/usr/local/bin/podman rm \ + --ignore \ + -f \ + --cidfile %t/%n-cid PIDFile=%t/%n-pid KillMode=none Type=forking @@ -217,7 +223,8 @@ RequiresMountsFor=/var/run/container/storage [Service] Restart=on-failure ExecStart=/usr/bin/podman start 77a818221650-infra -ExecStop=/usr/bin/podman stop -t 10 77a818221650-infra +ExecStop=/usr/bin/podman stop \ + -t 10 77a818221650-infra KillMode=none Type=forking PIDFile=/run/user/1000/overlay-containers/ccfd5c71a088768774ca7bd05888d55cc287698dde06f475c8b02f696a25adcd/userdata/conmon.pid diff --git a/docs/source/markdown/podman-secret-create.1.md b/docs/source/markdown/podman-secret-create.1.md index 1aafc6c11..fc6d72efb 100644 --- a/docs/source/markdown/podman-secret-create.1.md +++ b/docs/source/markdown/podman-secret-create.1.md @@ -26,16 +26,20 @@ Specify the secret driver (default **file**, which is unencrypted). #### **--driver-opts**=*key1=val1,key2=val2* -Specify driver specific options +Specify driver specific options. #### **--env**=*false* -Read secret data from environment variable +Read secret data from environment variable. #### **--help** Print usage statement. +#### **--label**, **-l**=*key=val1,key2=val2* + +Add label to secret. These labels can be viewed in podman secrete inspect or ls. + ## EXAMPLES ``` diff --git a/docs/source/markdown/podman-system-connection-list.1.md b/docs/source/markdown/podman-system-connection-list.1.md index 325c78a5c..99804f77f 100644 --- a/docs/source/markdown/podman-system-connection-list.1.md +++ b/docs/source/markdown/podman-system-connection-list.1.md @@ -13,7 +13,7 @@ List ssh destination(s) for podman service(s). ## OPTIONS -#### **--format**=*format* +#### **--format**, **-f**=*format* Change the default output format. This can be of a supported type like 'json' or a Go template. Valid placeholders for the Go template listed below: @@ -25,6 +25,10 @@ Valid placeholders for the Go template listed below: | .URI | URI to podman service. Valid schemes are ssh://[user@]*host*[:port]*Unix domain socket*[?secure=True], unix://*Unix domain socket*, and tcp://localhost[:*port*] | | .Default | Indicates whether connection is the default | +#### **--quiet**, **-q** + +Only show connection names + ## EXAMPLE ``` $ podman system connection list diff --git a/libpod/container.go b/libpod/container.go index cfffd8ea1..a4eb33c49 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -3,7 +3,7 @@ package libpod import ( "bytes" "fmt" - "io/ioutil" + "io" "net" "os" "strings" @@ -351,7 +351,7 @@ func (c *Container) specFromState() (*spec.Spec, error) { if f, err := os.Open(c.state.ConfigPath); err == nil { returnSpec = new(spec.Spec) - content, err := ioutil.ReadAll(f) + content, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("reading container config: %w", err) } @@ -990,7 +990,7 @@ func (c *Container) cGroupPath() (string, error) { // the lookup. // See #10602 for more details. procPath := fmt.Sprintf("/proc/%d/cgroup", c.state.PID) - lines, err := ioutil.ReadFile(procPath) + lines, err := os.ReadFile(procPath) if err != nil { // If the file doesn't exist, it means the container could have been terminated // so report it. diff --git a/libpod/container_api.go b/libpod/container_api.go index dd47b4d12..be0ca0128 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "sync" @@ -479,7 +478,7 @@ func (c *Container) AddArtifact(name string, data []byte) error { return define.ErrCtrRemoved } - return ioutil.WriteFile(c.getArtifactPath(name), data, 0o740) + return os.WriteFile(c.getArtifactPath(name), data, 0o740) } // GetArtifact reads the specified artifact file from the container @@ -488,7 +487,7 @@ func (c *Container) GetArtifact(name string) ([]byte, error) { return nil, define.ErrCtrRemoved } - return ioutil.ReadFile(c.getArtifactPath(name)) + return os.ReadFile(c.getArtifactPath(name)) } // RemoveArtifact deletes the specified artifacts file diff --git a/libpod/container_copy_common.go b/libpod/container_copy_common.go new file mode 100644 index 000000000..d07b4c692 --- /dev/null +++ b/libpod/container_copy_common.go @@ -0,0 +1,213 @@ +//go:build linux || freebsd +// +build linux freebsd + +package libpod + +import ( + "errors" + "io" + "path/filepath" + "strings" + + buildahCopiah "github.com/containers/buildah/copier" + "github.com/containers/buildah/pkg/chrootuser" + "github.com/containers/buildah/util" + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/rootless" + "github.com/containers/storage/pkg/archive" + "github.com/containers/storage/pkg/idtools" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" +) + +func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) { + var ( + mountPoint string + resolvedRoot string + resolvedPath string + unmount func() + err error + ) + + // Make sure that "/" copies the *contents* of the mount point and not + // the directory. + if path == "/" { + path = "/." + } + + // Optimization: only mount if the container is not already. + if c.state.Mounted { + mountPoint = c.state.Mountpoint + unmount = func() {} + } else { + // NOTE: make sure to unmount in error paths. + mountPoint, err = c.mount() + if err != nil { + return nil, err + } + unmount = func() { + if err := c.unmount(false); err != nil { + logrus.Errorf("Failed to unmount container: %v", err) + } + } + } + + resolvedRoot, resolvedPath, err = c.resolveCopyTarget(mountPoint, path) + if err != nil { + unmount() + return nil, err + } + + var idPair *idtools.IDPair + if chown { + // Make sure we chown the files to the container's main user and group ID. + user, err := getContainerUser(c, mountPoint) + if err != nil { + unmount() + return nil, err + } + idPair = &idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} + } + + decompressed, err := archive.DecompressStream(reader) + if err != nil { + unmount() + return nil, err + } + + logrus.Debugf("Container copy *to* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) + + return func() error { + defer unmount() + defer decompressed.Close() + putOptions := buildahCopiah.PutOptions{ + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: idPair, + ChownFiles: idPair, + NoOverwriteDirNonDir: noOverwriteDirNonDir, + NoOverwriteNonDirDir: noOverwriteDirNonDir, + Rename: rename, + } + + return c.joinMountAndExec( + func() error { + return buildahCopiah.Put(resolvedRoot, resolvedPath, putOptions, decompressed) + }, + ) + }, nil +} + +func (c *Container) copyToArchive(path string, writer io.Writer) (func() error, error) { + var ( + mountPoint string + unmount func() + err error + ) + + // Optimization: only mount if the container is not already. + if c.state.Mounted { + mountPoint = c.state.Mountpoint + unmount = func() {} + } else { + // NOTE: make sure to unmount in error paths. + mountPoint, err = c.mount() + if err != nil { + return nil, err + } + unmount = func() { + if err := c.unmount(false); err != nil { + logrus.Errorf("Failed to unmount container: %v", err) + } + } + } + + statInfo, resolvedRoot, resolvedPath, err := c.stat(mountPoint, path) + if err != nil { + unmount() + return nil, err + } + + // We optimistically chown to the host user. In case of a hypothetical + // container-to-container copy, the reading side will chown back to the + // container user. + user, err := getContainerUser(c, mountPoint) + if err != nil { + unmount() + return nil, err + } + hostUID, hostGID, err := util.GetHostIDs( + idtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), + idtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), + user.UID, + user.GID, + ) + if err != nil { + unmount() + return nil, err + } + idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} + + logrus.Debugf("Container copy *from* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) + + return func() error { + defer unmount() + getOptions := buildahCopiah.GetOptions{ + // Unless the specified points to ".", we want to copy the base directory. + KeepDirectoryNames: statInfo.IsDir && filepath.Base(path) != ".", + UIDMap: c.config.IDMappings.UIDMap, + GIDMap: c.config.IDMappings.GIDMap, + ChownDirs: &idPair, + ChownFiles: &idPair, + Excludes: []string{"dev", "proc", "sys"}, + // Ignore EPERMs when copying from rootless containers + // since we cannot read TTY devices. Those are owned + // by the host's root and hence "nobody" inside the + // container's user namespace. + IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, + } + return c.joinMountAndExec( + func() error { + return buildahCopiah.Get(resolvedRoot, "", getOptions, []string{resolvedPath}, writer) + }, + ) + }, nil +} + +// getContainerUser returns the specs.User and ID mappings of the container. +func getContainerUser(container *Container, mountPoint string) (specs.User, error) { + userspec := container.config.User + + uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec) + u := specs.User{ + UID: uid, + GID: gid, + Username: userspec, + } + + if !strings.Contains(userspec, ":") { + groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID)) + if err2 != nil { + if !errors.Is(err2, chrootuser.ErrNoSuchUser) && err == nil { + err = err2 + } + } else { + u.AdditionalGids = groups + } + } + + return u, err +} + +// idtoolsToRuntimeSpec converts idtools ID mapping to the one of the runtime spec. +func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping) { + for _, idmap := range idMaps { + tempIDMap := specs.LinuxIDMapping{ + ContainerID: uint32(idmap.ContainerID), + HostID: uint32(idmap.HostID), + Size: uint32(idmap.Size), + } + convertedIDMap = append(convertedIDMap, tempIDMap) + } + return convertedIDMap +} diff --git a/libpod/container_copy_freebsd.go b/libpod/container_copy_freebsd.go new file mode 100644 index 000000000..218f3917f --- /dev/null +++ b/libpod/container_copy_freebsd.go @@ -0,0 +1,13 @@ +package libpod + +// On FreeBSD, the container's mounts are in the global mount +// namespace so we can just execute the function directly. +func (c *Container) joinMountAndExec(f func() error) error { + return f() +} + +// Similarly, we can just use resolvePath for both running and stopped +// containers. +func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) { + return c.resolvePath(mountPoint, containerPath) +} diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go index 557fead1e..3b029f08f 100644 --- a/libpod/container_copy_linux.go +++ b/libpod/container_copy_linux.go @@ -1,226 +1,14 @@ -//go:build linux -// +build linux - package libpod import ( - "errors" "fmt" - "io" "os" - "path/filepath" "runtime" - "strings" - buildahCopiah "github.com/containers/buildah/copier" - "github.com/containers/buildah/pkg/chrootuser" - "github.com/containers/buildah/util" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/rootless" - "github.com/containers/storage/pkg/archive" - "github.com/containers/storage/pkg/idtools" - "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) -func (c *Container) copyFromArchive(path string, chown, noOverwriteDirNonDir bool, rename map[string]string, reader io.Reader) (func() error, error) { - var ( - mountPoint string - resolvedRoot string - resolvedPath string - unmount func() - err error - ) - - // Make sure that "/" copies the *contents* of the mount point and not - // the directory. - if path == "/" { - path = "/." - } - - // Optimization: only mount if the container is not already. - if c.state.Mounted { - mountPoint = c.state.Mountpoint - unmount = func() {} - } else { - // NOTE: make sure to unmount in error paths. - mountPoint, err = c.mount() - if err != nil { - return nil, err - } - unmount = func() { - if err := c.unmount(false); err != nil { - logrus.Errorf("Failed to unmount container: %v", err) - } - } - } - - if c.state.State == define.ContainerStateRunning { - resolvedRoot = "/" - resolvedPath = c.pathAbs(path) - } else { - resolvedRoot, resolvedPath, err = c.resolvePath(mountPoint, path) - if err != nil { - unmount() - return nil, err - } - } - - var idPair *idtools.IDPair - if chown { - // Make sure we chown the files to the container's main user and group ID. - user, err := getContainerUser(c, mountPoint) - if err != nil { - unmount() - return nil, err - } - idPair = &idtools.IDPair{UID: int(user.UID), GID: int(user.GID)} - } - - decompressed, err := archive.DecompressStream(reader) - if err != nil { - unmount() - return nil, err - } - - logrus.Debugf("Container copy *to* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) - - return func() error { - defer unmount() - defer decompressed.Close() - putOptions := buildahCopiah.PutOptions{ - UIDMap: c.config.IDMappings.UIDMap, - GIDMap: c.config.IDMappings.GIDMap, - ChownDirs: idPair, - ChownFiles: idPair, - NoOverwriteDirNonDir: noOverwriteDirNonDir, - NoOverwriteNonDirDir: noOverwriteDirNonDir, - Rename: rename, - } - - return c.joinMountAndExec( - func() error { - return buildahCopiah.Put(resolvedRoot, resolvedPath, putOptions, decompressed) - }, - ) - }, nil -} - -func (c *Container) copyToArchive(path string, writer io.Writer) (func() error, error) { - var ( - mountPoint string - unmount func() - err error - ) - - // Optimization: only mount if the container is not already. - if c.state.Mounted { - mountPoint = c.state.Mountpoint - unmount = func() {} - } else { - // NOTE: make sure to unmount in error paths. - mountPoint, err = c.mount() - if err != nil { - return nil, err - } - unmount = func() { - if err := c.unmount(false); err != nil { - logrus.Errorf("Failed to unmount container: %v", err) - } - } - } - - statInfo, resolvedRoot, resolvedPath, err := c.stat(mountPoint, path) - if err != nil { - unmount() - return nil, err - } - - // We optimistically chown to the host user. In case of a hypothetical - // container-to-container copy, the reading side will chown back to the - // container user. - user, err := getContainerUser(c, mountPoint) - if err != nil { - unmount() - return nil, err - } - hostUID, hostGID, err := util.GetHostIDs( - idtoolsToRuntimeSpec(c.config.IDMappings.UIDMap), - idtoolsToRuntimeSpec(c.config.IDMappings.GIDMap), - user.UID, - user.GID, - ) - if err != nil { - unmount() - return nil, err - } - idPair := idtools.IDPair{UID: int(hostUID), GID: int(hostGID)} - - logrus.Debugf("Container copy *from* %q (resolved: %q) on container %q (ID: %s)", path, resolvedPath, c.Name(), c.ID()) - - return func() error { - defer unmount() - getOptions := buildahCopiah.GetOptions{ - // Unless the specified points to ".", we want to copy the base directory. - KeepDirectoryNames: statInfo.IsDir && filepath.Base(path) != ".", - UIDMap: c.config.IDMappings.UIDMap, - GIDMap: c.config.IDMappings.GIDMap, - ChownDirs: &idPair, - ChownFiles: &idPair, - Excludes: []string{"dev", "proc", "sys"}, - // Ignore EPERMs when copying from rootless containers - // since we cannot read TTY devices. Those are owned - // by the host's root and hence "nobody" inside the - // container's user namespace. - IgnoreUnreadable: rootless.IsRootless() && c.state.State == define.ContainerStateRunning, - } - return c.joinMountAndExec( - func() error { - return buildahCopiah.Get(resolvedRoot, "", getOptions, []string{resolvedPath}, writer) - }, - ) - }, nil -} - -// getContainerUser returns the specs.User and ID mappings of the container. -func getContainerUser(container *Container, mountPoint string) (specs.User, error) { - userspec := container.config.User - - uid, gid, _, err := chrootuser.GetUser(mountPoint, userspec) - u := specs.User{ - UID: uid, - GID: gid, - Username: userspec, - } - - if !strings.Contains(userspec, ":") { - groups, err2 := chrootuser.GetAdditionalGroupsForUser(mountPoint, uint64(u.UID)) - if err2 != nil { - if !errors.Is(err2, chrootuser.ErrNoSuchUser) && err == nil { - err = err2 - } - } else { - u.AdditionalGids = groups - } - } - - return u, err -} - -// idtoolsToRuntimeSpec converts idtools ID mapping to the one of the runtime spec. -func idtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxIDMapping) { - for _, idmap := range idMaps { - tempIDMap := specs.LinuxIDMapping{ - ContainerID: uint32(idmap.ContainerID), - HostID: uint32(idmap.HostID), - Size: uint32(idmap.Size), - } - convertedIDMap = append(convertedIDMap, tempIDMap) - } - return convertedIDMap -} - // joinMountAndExec executes the specified function `f` inside the container's // mount and PID namespace. That allows for having the exact view on the // container's file system. @@ -288,3 +76,13 @@ func (c *Container) joinMountAndExec(f func() error) error { }() return <-errChan } + +func (c *Container) resolveCopyTarget(mountPoint string, containerPath string) (string, string, error) { + // If the container is running, we will execute the copy + // inside the container's mount namespace so we return a path + // relative to the container's root. + if c.state.State == define.ContainerStateRunning { + return "/", c.pathAbs(containerPath), nil + } + return c.resolvePath(mountPoint, containerPath) +} diff --git a/libpod/container_copy_unsupported.go b/libpod/container_copy_unsupported.go index 62937279a..703b0a74e 100644 --- a/libpod/container_copy_unsupported.go +++ b/libpod/container_copy_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/container_exec.go b/libpod/container_exec.go index 3a2cba52f..7896d1932 100644 --- a/libpod/container_exec.go +++ b/libpod/container_exec.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -928,7 +927,7 @@ func (c *Container) readExecExitCode(sessionID string) (int, error) { if err != nil { return -1, err } - ec, err := ioutil.ReadFile(exitFile) + ec, err := os.ReadFile(exitFile) if err != nil { return -1, err } diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 994243805..9bf93412d 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -201,7 +200,7 @@ func (c *Container) waitForExitFileAndSync() error { // This assumes the exit file already exists. func (c *Container) handleExitFile(exitFile string, fi os.FileInfo) error { c.state.FinishedTime = ctime.Created(fi) - statusCodeStr, err := ioutil.ReadFile(exitFile) + statusCodeStr, err := os.ReadFile(exitFile) if err != nil { return fmt.Errorf("failed to read exit file for container %s: %w", c.ID(), err) } @@ -2089,7 +2088,7 @@ func (c *Container) saveSpec(spec *spec.Spec) error { if err != nil { return fmt.Errorf("exporting runtime spec for container %s to JSON: %w", c.ID(), err) } - if err := ioutil.WriteFile(jsonPath, fileJSON, 0644); err != nil { + if err := os.WriteFile(jsonPath, fileJSON, 0644); err != nil { return fmt.Errorf("writing runtime spec JSON for container %s to disk: %w", c.ID(), err) } @@ -2343,7 +2342,7 @@ func (c *Container) extractSecretToCtrStorage(secr *ContainerSecret) error { if err != nil { return fmt.Errorf("unable to extract secret: %w", err) } - err = ioutil.WriteFile(secretFile, data, 0644) + err = os.WriteFile(secretFile, data, 0644) if err != nil { return fmt.Errorf("unable to create %s: %w", secretFile, err) } diff --git a/libpod/container_internal_common.go b/libpod/container_internal_common.go index 9c4a3bb67..29107d4b6 100644 --- a/libpod/container_internal_common.go +++ b/libpod/container_internal_common.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math" "os" "os/user" @@ -110,7 +109,11 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // If the flag to mount all devices is set for a privileged container, add // all the devices from the host's machine into the container if c.config.MountAllDevices { - if err := util.AddPrivilegedDevices(&g); err != nil { + systemdMode := false + if c.config.Systemd != nil { + systemdMode = *c.config.Systemd + } + if err := util.AddPrivilegedDevices(&g, systemdMode); err != nil { return nil, err } } @@ -788,7 +791,7 @@ func (c *Container) createCheckpointImage(ctx context.Context, options Container } // Export checkpoint into temporary tar file - tmpDir, err := ioutil.TempDir("", "checkpoint_image_") + tmpDir, err := os.MkdirTemp("", "checkpoint_image_") if err != nil { return err } @@ -2442,7 +2445,7 @@ func (c *Container) generatePasswdAndGroup() (string, string, error) { if err != nil { return "", "", fmt.Errorf("creating path to container %s /etc/passwd: %w", c.ID(), err) } - orig, err := ioutil.ReadFile(originPasswdFile) + orig, err := os.ReadFile(originPasswdFile) if err != nil && !os.IsNotExist(err) { return "", "", err } @@ -2488,7 +2491,7 @@ func (c *Container) generatePasswdAndGroup() (string, string, error) { if err != nil { return "", "", fmt.Errorf("creating path to container %s /etc/group: %w", c.ID(), err) } - orig, err := ioutil.ReadFile(originGroupFile) + orig, err := os.ReadFile(originGroupFile) if err != nil && !os.IsNotExist(err) { return "", "", err } @@ -2659,7 +2662,7 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error { return nil } -func (c *Container) relabel(src, mountLabel string, recurse bool) error { +func (c *Container) relabel(src, mountLabel string, shared bool) error { if !selinux.GetEnabled() || mountLabel == "" { return nil } @@ -2674,7 +2677,7 @@ func (c *Container) relabel(src, mountLabel string, recurse bool) error { return nil } } - return label.Relabel(src, mountLabel, recurse) + return label.Relabel(src, mountLabel, shared) } func (c *Container) ChangeHostPathOwnership(src string, recurse bool, uid, gid int) error { diff --git a/libpod/container_internal_test.go b/libpod/container_internal_test.go index 1b4e62e91..46a2da544 100644 --- a/libpod/container_internal_test.go +++ b/libpod/container_internal_test.go @@ -3,7 +3,7 @@ package libpod import ( "context" "fmt" - "io/ioutil" + "os" "path/filepath" "runtime" "testing" @@ -60,7 +60,7 @@ func TestPostDeleteHooks(t *testing.T) { for _, p := range []string{statePath, copyPath} { path := p t.Run(path, func(t *testing.T) { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { t.Fatal(err) } diff --git a/libpod/container_stat_common.go b/libpod/container_stat_common.go new file mode 100644 index 000000000..e59a52ede --- /dev/null +++ b/libpod/container_stat_common.go @@ -0,0 +1,155 @@ +//go:build linux || freebsd +// +build linux freebsd + +package libpod + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/containers/buildah/copier" + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/copy" +) + +// statOnHost stats the specified path *on the host*. It returns the file info +// along with the resolved root and the resolved path. Both paths are absolute +// to the host's root. Note that the paths may resolved outside the +// container's mount point (e.g., to a volume or bind mount). +func (c *Container) statOnHost(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { + // Now resolve the container's path. It may hit a volume, it may hit a + // bind mount, it may be relative. + resolvedRoot, resolvedPath, err := c.resolvePath(mountPoint, containerPath) + if err != nil { + return nil, "", "", err + } + + statInfo, err := secureStat(resolvedRoot, resolvedPath) + return statInfo, resolvedRoot, resolvedPath, err +} + +func (c *Container) stat(containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) { + var ( + resolvedRoot string + resolvedPath string + absContainerPath string + statInfo *copier.StatForItem + statErr error + ) + + // Make sure that "/" copies the *contents* of the mount point and not + // the directory. + if containerPath == "/" { + containerPath = "/." + } + + // Wildcards are not allowed. + // TODO: it's now technically possible wildcards. + // We may consider enabling support in the future. + if strings.Contains(containerPath, "*") { + return nil, "", "", copy.ErrENOENT + } + + statInfo, resolvedRoot, resolvedPath, statErr = c.statInContainer(containerMountPoint, containerPath) + if statErr != nil { + if statInfo == nil { + return nil, "", "", statErr + } + // Not all errors from secureStat map to ErrNotExist, so we + // have to look into the error string. Turning it into an + // ENOENT let's the API handlers return the correct status code + // which is crucial for the remote client. + if os.IsNotExist(statErr) || strings.Contains(statErr.Error(), "o such file or directory") { + statErr = copy.ErrENOENT + } + } + + switch { + case statInfo.IsSymlink: + // Symlinks are already evaluated and always relative to the + // container's mount point. + absContainerPath = statInfo.ImmediateTarget + case strings.HasPrefix(resolvedPath, containerMountPoint): + // If the path is on the container's mount point, strip it off. + absContainerPath = strings.TrimPrefix(resolvedPath, containerMountPoint) + absContainerPath = filepath.Join("/", absContainerPath) + default: + // No symlink and not on the container's mount point, so let's + // move it back to the original input. It must have evaluated + // to a volume or bind mount but we cannot return host paths. + absContainerPath = containerPath + } + + // Preserve the base path as specified by the user. The `filepath` + // packages likes to remove trailing slashes and dots that are crucial + // to the copy logic. + absContainerPath = copy.PreserveBasePath(containerPath, absContainerPath) + resolvedPath = copy.PreserveBasePath(containerPath, resolvedPath) + + info := &define.FileInfo{ + IsDir: statInfo.IsDir, + Name: filepath.Base(absContainerPath), + Size: statInfo.Size, + Mode: statInfo.Mode, + ModTime: statInfo.ModTime, + LinkTarget: absContainerPath, + } + + return info, resolvedRoot, resolvedPath, statErr +} + +// secureStat extracts file info for path in a chroot'ed environment in root. +func secureStat(root string, path string) (*copier.StatForItem, error) { + var glob string + var err error + + // If root and path are equal, then dir must be empty and the glob must + // be ".". + if filepath.Clean(root) == filepath.Clean(path) { + glob = "." + } else { + glob, err = filepath.Rel(root, path) + if err != nil { + return nil, err + } + } + + globStats, err := copier.Stat(root, "", copier.StatOptions{}, []string{glob}) + if err != nil { + return nil, err + } + + if len(globStats) != 1 { + return nil, fmt.Errorf("internal error: secureStat: expected 1 item but got %d", len(globStats)) + } + if len(globStats) != 1 { + return nil, fmt.Errorf("internal error: secureStat: expected 1 result but got %d", len(globStats[0].Results)) + } + + // NOTE: the key in the map differ from `glob` when hitting symlink. + // Hence, we just take the first (and only) key/value pair. + for _, stat := range globStats[0].Results { + var statErr error + if stat.Error != "" { + statErr = errors.New(stat.Error) + } + // If necessary evaluate the symlink + if stat.IsSymlink { + target, err := copier.Eval(root, path, copier.EvalOptions{}) + if err != nil { + return nil, fmt.Errorf("evaluating symlink in container: %w", err) + } + // Need to make sure the symlink is relative to the root! + target = strings.TrimPrefix(target, root) + target = filepath.Join("/", target) + stat.ImmediateTarget = target + } + return stat, statErr + } + + // Nothing found! + return nil, copy.ErrENOENT +} diff --git a/libpod/container_stat_freebsd.go b/libpod/container_stat_freebsd.go new file mode 100644 index 000000000..d1e0db348 --- /dev/null +++ b/libpod/container_stat_freebsd.go @@ -0,0 +1,13 @@ +package libpod + +import ( + "github.com/containers/buildah/copier" +) + +// On FreeBSD, jails use the global mount namespace, filtered to only +// the mounts the jail should see. This means that we can use +// statOnHost whether the container is running or not. +// container is running +func (c *Container) statInContainer(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { + return c.statOnHost(mountPoint, containerPath) +} diff --git a/libpod/container_stat_linux.go b/libpod/container_stat_linux.go index dc3a524f5..5e5ef3c1a 100644 --- a/libpod/container_stat_linux.go +++ b/libpod/container_stat_linux.go @@ -1,18 +1,8 @@ -//go:build linux -// +build linux - package libpod import ( - "errors" - "fmt" - "os" - "path/filepath" - "strings" - "github.com/containers/buildah/copier" "github.com/containers/podman/v4/libpod/define" - "github.com/containers/podman/v4/pkg/copy" ) // statInsideMount stats the specified path *inside* the container's mount and PID @@ -34,150 +24,15 @@ func (c *Container) statInsideMount(containerPath string) (*copier.StatForItem, return statInfo, resolvedRoot, resolvedPath, err } -// statOnHost stats the specified path *on the host*. It returns the file info -// along with the resolved root and the resolved path. Both paths are absolute -// to the host's root. Note that the paths may resolved outside the -// container's mount point (e.g., to a volume or bind mount). -func (c *Container) statOnHost(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { - // Now resolve the container's path. It may hit a volume, it may hit a - // bind mount, it may be relative. - resolvedRoot, resolvedPath, err := c.resolvePath(mountPoint, containerPath) - if err != nil { - return nil, "", "", err - } - - statInfo, err := secureStat(resolvedRoot, resolvedPath) - return statInfo, resolvedRoot, resolvedPath, err -} - -func (c *Container) stat(containerMountPoint string, containerPath string) (*define.FileInfo, string, string, error) { - var ( - resolvedRoot string - resolvedPath string - absContainerPath string - statInfo *copier.StatForItem - statErr error - ) - - // Make sure that "/" copies the *contents* of the mount point and not - // the directory. - if containerPath == "/" { - containerPath = "/." - } - - // Wildcards are not allowed. - // TODO: it's now technically possible wildcards. - // We may consider enabling support in the future. - if strings.Contains(containerPath, "*") { - return nil, "", "", copy.ErrENOENT - } - +// Calls either statOnHost or statInsideMount depending on whether the +// container is running +func (c *Container) statInContainer(mountPoint string, containerPath string) (*copier.StatForItem, string, string, error) { if c.state.State == define.ContainerStateRunning { // If the container is running, we need to join it's mount namespace // and stat there. - statInfo, resolvedRoot, resolvedPath, statErr = c.statInsideMount(containerPath) - } else { - // If the container is NOT running, we need to resolve the path - // on the host. - statInfo, resolvedRoot, resolvedPath, statErr = c.statOnHost(containerMountPoint, containerPath) - } - - if statErr != nil { - if statInfo == nil { - return nil, "", "", statErr - } - // Not all errors from secureStat map to ErrNotExist, so we - // have to look into the error string. Turning it into an - // ENOENT let's the API handlers return the correct status code - // which is crucial for the remote client. - if os.IsNotExist(statErr) || strings.Contains(statErr.Error(), "o such file or directory") { - statErr = copy.ErrENOENT - } - } - - switch { - case statInfo.IsSymlink: - // Symlinks are already evaluated and always relative to the - // container's mount point. - absContainerPath = statInfo.ImmediateTarget - case strings.HasPrefix(resolvedPath, containerMountPoint): - // If the path is on the container's mount point, strip it off. - absContainerPath = strings.TrimPrefix(resolvedPath, containerMountPoint) - absContainerPath = filepath.Join("/", absContainerPath) - default: - // No symlink and not on the container's mount point, so let's - // move it back to the original input. It must have evaluated - // to a volume or bind mount but we cannot return host paths. - absContainerPath = containerPath + return c.statInsideMount(containerPath) } - - // Preserve the base path as specified by the user. The `filepath` - // packages likes to remove trailing slashes and dots that are crucial - // to the copy logic. - absContainerPath = copy.PreserveBasePath(containerPath, absContainerPath) - resolvedPath = copy.PreserveBasePath(containerPath, resolvedPath) - - info := &define.FileInfo{ - IsDir: statInfo.IsDir, - Name: filepath.Base(absContainerPath), - Size: statInfo.Size, - Mode: statInfo.Mode, - ModTime: statInfo.ModTime, - LinkTarget: absContainerPath, - } - - return info, resolvedRoot, resolvedPath, statErr -} - -// secureStat extracts file info for path in a chroot'ed environment in root. -func secureStat(root string, path string) (*copier.StatForItem, error) { - var glob string - var err error - - // If root and path are equal, then dir must be empty and the glob must - // be ".". - if filepath.Clean(root) == filepath.Clean(path) { - glob = "." - } else { - glob, err = filepath.Rel(root, path) - if err != nil { - return nil, err - } - } - - globStats, err := copier.Stat(root, "", copier.StatOptions{}, []string{glob}) - if err != nil { - return nil, err - } - - if len(globStats) != 1 { - return nil, fmt.Errorf("internal error: secureStat: expected 1 item but got %d", len(globStats)) - } - if len(globStats) != 1 { - return nil, fmt.Errorf("internal error: secureStat: expected 1 result but got %d", len(globStats[0].Results)) - } - - // NOTE: the key in the map differ from `glob` when hitting symlink. - // Hence, we just take the first (and only) key/value pair. - for _, stat := range globStats[0].Results { - var statErr error - if stat.Error != "" { - statErr = errors.New(stat.Error) - } - // If necessary evaluate the symlink - if stat.IsSymlink { - target, err := copier.Eval(root, path, copier.EvalOptions{}) - if err != nil { - return nil, fmt.Errorf("evaluating symlink in container: %w", err) - } - // Need to make sure the symlink is relative to the root! - target = strings.TrimPrefix(target, root) - target = filepath.Join("/", target) - stat.ImmediateTarget = target - } - return stat, statErr - } - - // Nothing found! - return nil, copy.ErrENOENT + // If the container is NOT running, we need to resolve the path + // on the host. + return c.statOnHost(mountPoint, containerPath) } diff --git a/libpod/container_stat_unsupported.go b/libpod/container_stat_unsupported.go index 2f1acd44d..e88b88bb1 100644 --- a/libpod/container_stat_unsupported.go +++ b/libpod/container_stat_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux -// +build !linux +//go:build !linux && !freebsd +// +build !linux,!freebsd package libpod diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go index d749a0d4d..bb0f461e3 100644 --- a/libpod/events/logfile.go +++ b/libpod/events/logfile.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -204,11 +203,11 @@ func truncate(filePath string) error { size := origFinfo.Size() threshold := size / 2 - tmp, err := ioutil.TempFile(path.Dir(filePath), "") + tmp, err := os.CreateTemp(path.Dir(filePath), "") if err != nil { // Retry in /tmp in case creating a tmp file in the same // directory has failed. - tmp, err = ioutil.TempFile("", "") + tmp, err = os.CreateTemp("", "") if err != nil { return err } diff --git a/libpod/events/logfile_test.go b/libpod/events/logfile_test.go index 302533c12..50141168e 100644 --- a/libpod/events/logfile_test.go +++ b/libpod/events/logfile_test.go @@ -1,7 +1,6 @@ package events import ( - "io/ioutil" "os" "testing" @@ -29,7 +28,7 @@ func TestRotateLog(t *testing.T) { } for _, test := range tests { - tmp, err := ioutil.TempFile("", "log-rotation-") + tmp, err := os.CreateTemp("", "log-rotation-") require.NoError(t, err) defer os.Remove(tmp.Name()) defer tmp.Close() @@ -84,7 +83,7 @@ func TestTruncationOutput(t *testing.T) { 10 ` // Create dummy file - tmp, err := ioutil.TempFile("", "log-rotation") + tmp, err := os.CreateTemp("", "log-rotation") require.NoError(t, err) defer os.Remove(tmp.Name()) defer tmp.Close() @@ -94,11 +93,11 @@ func TestTruncationOutput(t *testing.T) { require.NoError(t, err) // Truncate the file - beforeTruncation, err := ioutil.ReadFile(tmp.Name()) + beforeTruncation, err := os.ReadFile(tmp.Name()) require.NoError(t, err) err = truncate(tmp.Name()) require.NoError(t, err) - afterTruncation, err := ioutil.ReadFile(tmp.Name()) + afterTruncation, err := os.ReadFile(tmp.Name()) require.NoError(t, err) // Test if rotation was successful @@ -116,9 +115,9 @@ func TestRenameLog(t *testing.T) { 5 ` // Create two dummy files - source, err := ioutil.TempFile("", "removing") + source, err := os.CreateTemp("", "removing") require.NoError(t, err) - target, err := ioutil.TempFile("", "renaming") + target, err := os.CreateTemp("", "renaming") require.NoError(t, err) // Write to source dummy file @@ -126,11 +125,11 @@ func TestRenameLog(t *testing.T) { require.NoError(t, err) // Rename the files - beforeRename, err := ioutil.ReadFile(source.Name()) + beforeRename, err := os.ReadFile(source.Name()) require.NoError(t, err) err = renameLog(source.Name(), target.Name()) require.NoError(t, err) - afterRename, err := ioutil.ReadFile(target.Name()) + afterRename, err := os.ReadFile(target.Name()) require.NoError(t, err) // Test if renaming was successful diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go index e835af9f0..a589f2787 100644 --- a/libpod/healthcheck.go +++ b/libpod/healthcheck.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -208,7 +207,7 @@ func (c *Container) updateHealthStatus(status string) error { if err != nil { return fmt.Errorf("unable to marshall healthchecks for writing status: %w", err) } - return ioutil.WriteFile(c.healthCheckLogPath(), newResults, 0700) + return os.WriteFile(c.healthCheckLogPath(), newResults, 0700) } // UpdateHealthCheckLog parses the health check results and writes the log @@ -242,7 +241,7 @@ func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPerio if err != nil { return fmt.Errorf("unable to marshall healthchecks for writing: %w", err) } - return ioutil.WriteFile(c.healthCheckLogPath(), newResults, 0700) + return os.WriteFile(c.healthCheckLogPath(), newResults, 0700) } // HealthCheckLogPath returns the path for where the health check log is @@ -259,7 +258,7 @@ func (c *Container) getHealthCheckLog() (define.HealthCheckResults, error) { if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) { return healthCheck, nil } - b, err := ioutil.ReadFile(c.healthCheckLogPath()) + b, err := os.ReadFile(c.healthCheckLogPath()) if err != nil { return healthCheck, fmt.Errorf("failed to read health check log file: %w", err) } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index e27ec8e9d..6ea56ade5 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -8,7 +8,6 @@ import ( "crypto/sha256" "errors" "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -303,7 +302,7 @@ func (r *RootlessNetNS) Cleanup(runtime *Runtime) error { if err != nil { logrus.Error(err) } - b, err := ioutil.ReadFile(r.getPath(rootlessNetNsSilrp4netnsPidFile)) + b, err := os.ReadFile(r.getPath(rootlessNetNsSilrp4netnsPidFile)) if err == nil { var i int i, err = strconv.Atoi(string(b)) @@ -445,7 +444,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) { // create pid file for the slirp4netns process // this is need to kill the process in the cleanup pid := strconv.Itoa(cmd.Process.Pid) - err = ioutil.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700) + err = os.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700) if err != nil { return nil, fmt.Errorf("unable to write rootless-netns slirp4netns pid file: %w", err) } diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go index 7b8eb94df..dce335c0a 100644 --- a/libpod/networking_machine.go +++ b/libpod/networking_machine.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "strconv" @@ -109,7 +108,7 @@ func makeMachineRequest(ctx context.Context, client *http.Client, url string, bu } func annotateGvproxyResponseError(r io.Reader) error { - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err == nil && len(b) > 0 { return fmt.Errorf("something went wrong with the request: %q", string(b)) } diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go index d4ec9082b..4026b6b48 100644 --- a/libpod/networking_slirp4netns.go +++ b/libpod/networking_slirp4netns.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "os/exec" @@ -324,7 +323,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { // correct value assigned so DAD is disabled for it // Also make sure to change this value back to the original after slirp4netns // is ready in case users rely on this sysctl. - orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl) + orgValue, err := os.ReadFile(ipv6ConfDefaultAcceptDadSysctl) if err != nil { netnsReadyWg.Done() // on ipv6 disabled systems the sysctl does not exists @@ -334,7 +333,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { } return err } - err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644) + err = os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644) netnsReadyWg.Done() if err != nil { return err @@ -342,7 +341,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error { // wait until slirp4nets is ready before resetting this value slirpReadyWg.Wait() - return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644) + return os.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644) }) if err != nil { logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err) @@ -486,7 +485,7 @@ func waitForSync(syncR *os.File, cmd *exec.Cmd, logFile io.ReadSeeker, timeout t if _, err := logFile.Seek(0, 0); err != nil { logrus.Errorf("Could not seek log file: %q", err) } - logContent, err := ioutil.ReadAll(logFile) + logContent, err := io.ReadAll(logFile) if err != nil { return fmt.Errorf("%s failed: %w", prog, err) } @@ -730,7 +729,7 @@ func (c *Container) reloadRootlessRLKPortMapping() error { if err != nil { return fmt.Errorf("port reloading failed: %w", err) } - b, err := ioutil.ReadAll(conn) + b, err := io.ReadAll(conn) if err != nil { return fmt.Errorf("port reloading failed: %w", err) } diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go index 53dddd064..cbdbad02d 100644 --- a/libpod/oci_conmon_common.go +++ b/libpod/oci_conmon_common.go @@ -10,7 +10,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "os" @@ -232,7 +231,7 @@ func (r *ConmonOCIRuntime) UpdateContainerStatus(ctr *Container) error { } if err := cmd.Start(); err != nil { - out, err2 := ioutil.ReadAll(errPipe) + out, err2 := io.ReadAll(errPipe) if err2 != nil { return fmt.Errorf("getting container %s state: %w", ctr.ID(), err) } @@ -254,7 +253,7 @@ func (r *ConmonOCIRuntime) UpdateContainerStatus(ctr *Container) error { if err := errPipe.Close(); err != nil { return err } - out, err := ioutil.ReadAll(outPipe) + out, err := io.ReadAll(outPipe) if err != nil { return fmt.Errorf("reading stdout: %s: %w", ctr.ID(), err) } @@ -335,7 +334,7 @@ func generateResourceFile(res *spec.LinuxResources) (string, []string, error) { return "", flags, nil } - f, err := ioutil.TempFile("", "podman") + f, err := os.CreateTemp("", "podman") if err != nil { return "", nil, err } @@ -1398,7 +1397,7 @@ func newPipe() (*os.File, *os.File, error) { func readConmonPidFile(pidFile string) (int, error) { // Let's try reading the Conmon pid at the same time. if pidFile != "" { - contents, err := ioutil.ReadFile(pidFile) + contents, err := os.ReadFile(pidFile) if err != nil { return -1, err } @@ -1447,7 +1446,7 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int, case ss := <-ch: if ss.err != nil { if ociLog != "" { - ociLogData, err := ioutil.ReadFile(ociLog) + ociLogData, err := os.ReadFile(ociLog) if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { @@ -1460,7 +1459,7 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int, logrus.Debugf("Received: %d", ss.si.Data) if ss.si.Data < 0 { if ociLog != "" { - ociLogData, err := ioutil.ReadFile(ociLog) + ociLogData, err := os.ReadFile(ociLog) if err == nil { var ociErr ociError if err := json.Unmarshal(ociLogData, &ociErr); err == nil { diff --git a/libpod/oci_conmon_exec_common.go b/libpod/oci_conmon_exec_common.go index e5080942b..24113bd8d 100644 --- a/libpod/oci_conmon_exec_common.go +++ b/libpod/oci_conmon_exec_common.go @@ -3,7 +3,6 @@ package libpod import ( "errors" "fmt" - "io/ioutil" "net/http" "os" "os/exec" @@ -665,7 +664,7 @@ func attachExecHTTP(c *Container, sessionID string, r *http.Request, w http.Resp // prepareProcessExec returns the path of the process.json used in runc exec -p // caller is responsible to close the returned *os.File if needed. func (c *Container) prepareProcessExec(options *ExecOptions, env []string, sessionID string) (*os.File, error) { - f, err := ioutil.TempFile(c.execBundlePath(sessionID), "exec-process-") + f, err := os.CreateTemp(c.execBundlePath(sessionID), "exec-process-") if err != nil { return nil, err } @@ -764,7 +763,7 @@ func (c *Container) prepareProcessExec(options *ExecOptions, env []string, sessi return nil, err } - if err := ioutil.WriteFile(f.Name(), processJSON, 0644); err != nil { + if err := os.WriteFile(f.Name(), processJSON, 0644); err != nil { return nil, err } return f, nil diff --git a/libpod/plugin/volume_api.go b/libpod/plugin/volume_api.go index 522895798..c595937ae 100644 --- a/libpod/plugin/volume_api.go +++ b/libpod/plugin/volume_api.go @@ -5,7 +5,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "io" "net" "net/http" "os" @@ -95,7 +95,7 @@ func validatePlugin(newPlugin *VolumePlugin) error { } // Read and decode the body so we can tell if this is a volume plugin. - respBytes, err := ioutil.ReadAll(resp.Body) + respBytes, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("reading activation response body from plugin %s: %w", newPlugin.Name, err) } @@ -252,7 +252,7 @@ func (p *VolumePlugin) handleErrorResponse(resp *http.Response, endpoint, volNam // Let's interpret anything other than 200 as an error. // If there isn't an error, don't even bother decoding the response. if resp.StatusCode != 200 { - errResp, err := ioutil.ReadAll(resp.Body) + errResp, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -307,7 +307,7 @@ func (p *VolumePlugin) ListVolumes() ([]*volume.Volume, error) { return nil, err } - volumeRespBytes, err := ioutil.ReadAll(resp.Body) + volumeRespBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -342,7 +342,7 @@ func (p *VolumePlugin) GetVolume(req *volume.GetRequest) (*volume.Volume, error) return nil, err } - getRespBytes, err := ioutil.ReadAll(resp.Body) + getRespBytes, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -398,7 +398,7 @@ func (p *VolumePlugin) GetVolumePath(req *volume.PathRequest) (string, error) { return "", err } - pathRespBytes, err := ioutil.ReadAll(resp.Body) + pathRespBytes, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } @@ -435,7 +435,7 @@ func (p *VolumePlugin) MountVolume(req *volume.MountRequest) (string, error) { return "", err } - mountRespBytes, err := ioutil.ReadAll(resp.Body) + mountRespBytes, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("reading response body from volume plugin %s: %w", p.Name, err) } diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go index dacbd752f..87b77c3eb 100644 --- a/libpod/runtime_img.go +++ b/libpod/runtime_img.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" buildahDefine "github.com/containers/buildah/define" @@ -105,7 +104,7 @@ func (r *Runtime) Build(ctx context.Context, options buildahDefine.BuildOptions, // DownloadFromFile reads all of the content from the reader and temporarily // saves in it $TMPDIR/importxyz, which is deleted after the image is imported func DownloadFromFile(reader *os.File) (string, error) { - outFile, err := ioutil.TempFile(util.Tmpdir(), "import") + outFile, err := os.CreateTemp(util.Tmpdir(), "import") if err != nil { return "", fmt.Errorf("creating file: %w", err) } diff --git a/libpod/runtime_migrate.go b/libpod/runtime_migrate.go index 36901d4d0..df1a1f1cb 100644 --- a/libpod/runtime_migrate.go +++ b/libpod/runtime_migrate.go @@ -5,7 +5,6 @@ package libpod import ( "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -23,7 +22,7 @@ func (r *Runtime) stopPauseProcess() error { if err != nil { return fmt.Errorf("could not get pause process pid file path: %w", err) } - data, err := ioutil.ReadFile(pausePidPath) + data, err := os.ReadFile(pausePidPath) if err != nil { if os.IsNotExist(err) { return nil diff --git a/libpod/state_test.go b/libpod/state_test.go index 3c1fe8f63..7664f7c00 100644 --- a/libpod/state_test.go +++ b/libpod/state_test.go @@ -1,7 +1,6 @@ package libpod import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -35,7 +34,7 @@ var ( // Get an empty BoltDB state for use in tests func getEmptyBoltState() (_ State, _ string, _ lock.Manager, retErr error) { - tmpDir, err := ioutil.TempDir("", tmpDirPrefix) + tmpDir, err := os.MkdirTemp("", tmpDirPrefix) if err != nil { return nil, "", nil, err } diff --git a/pkg/api/handlers/compat/containers_export.go b/pkg/api/handlers/compat/containers_export.go index 66e1dcca5..03e547411 100644 --- a/pkg/api/handlers/compat/containers_export.go +++ b/pkg/api/handlers/compat/containers_export.go @@ -2,7 +2,6 @@ package compat import ( "fmt" - "io/ioutil" "net/http" "os" @@ -19,7 +18,7 @@ func ExportContainer(w http.ResponseWriter, r *http.Request) { utils.ContainerNotFound(w, name, err) return } - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go index 0493c6ffb..cce482441 100644 --- a/pkg/api/handlers/compat/images.go +++ b/pkg/api/handlers/compat/images.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -49,7 +48,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { // 500 server runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -193,7 +192,7 @@ func CreateImageFromSrc(w http.ResponseWriter, r *http.Request) { // fromSrc – Source to import. The value may be a URL from which the image can be retrieved or - to read the image from the request body. This parameter may only be used when importing an image. source := query.FromSrc if source == "-" { - f, err := ioutil.TempFile("", "api_load.tar") + f, err := os.CreateTemp("", "api_load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to create tempfile: %w", err)) return @@ -480,7 +479,7 @@ func LoadImages(w http.ResponseWriter, r *http.Request) { // First write the body to a temporary file that we can later attempt // to load. - f, err := ioutil.TempFile("", "api_load.tar") + f, err := os.CreateTemp("", "api_load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to create tempfile: %w", err)) return @@ -547,7 +546,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { images[i] = possiblyNormalizedName } - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go index 4035b4315..287011798 100644 --- a/pkg/api/handlers/compat/images_build.go +++ b/pkg/api/handlers/compat/images_build.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -182,7 +181,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { dockerFileSet := false if utils.IsLibpodRequest(r) && query.Remote != "" { // The context directory could be a URL. Try to handle that. - anchorDir, err := ioutil.TempDir(parse.GetTempDir(), "libpod_builder") + anchorDir, err := os.MkdirTemp(parse.GetTempDir(), "libpod_builder") if err != nil { utils.InternalServerError(w, err) } @@ -730,7 +729,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) { if logrus.IsLevelEnabled(logrus.DebugLevel) { if v, found := os.LookupEnv("PODMAN_RETAIN_BUILD_ARTIFACT"); found { if keep, _ := strconv.ParseBool(v); keep { - t, _ := ioutil.TempFile("", "build_*_server") + t, _ := os.CreateTemp("", "build_*_server") defer t.Close() body = io.MultiWriter(t, w) } @@ -852,7 +851,7 @@ func parseLibPodIsolation(isolation string) (buildah.Isolation, error) { func extractTarFile(r *http.Request) (string, error) { // build a home for the request body - anchorDir, err := ioutil.TempDir("", "libpod_builder") + anchorDir, err := os.MkdirTemp("", "libpod_builder") if err != nil { return "", err } diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go index a1173de0b..e1655a3bc 100644 --- a/pkg/api/handlers/compat/images_push.go +++ b/pkg/api/handlers/compat/images_push.go @@ -4,8 +4,9 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" + "os" "strings" "github.com/containers/image/v5/types" @@ -26,7 +27,7 @@ func PushImage(w http.ResponseWriter, r *http.Request) { decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder) runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - digestFile, err := ioutil.TempFile("", "digest.txt") + digestFile, err := os.CreateTemp("", "digest.txt") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -186,7 +187,7 @@ loop: // break out of for/select infinite loop break loop } - digestBytes, err := ioutil.ReadAll(digestFile) + digestBytes, err := io.ReadAll(digestFile) if err != nil { report.Error = &jsonmessage.JSONError{ Message: err.Error(), diff --git a/pkg/api/handlers/compat/secrets.go b/pkg/api/handlers/compat/secrets.go index 13b3c4e24..847f05f27 100644 --- a/pkg/api/handlers/compat/secrets.go +++ b/pkg/api/handlers/compat/secrets.go @@ -111,14 +111,11 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("Decode(): %w", err)) return } - if len(createParams.Labels) > 0 { - utils.Error(w, http.StatusBadRequest, fmt.Errorf("labels not supported: %w", errors.New("bad parameter"))) - return - } decoded, _ := base64.StdEncoding.DecodeString(createParams.Data) reader := bytes.NewReader(decoded) opts.Driver = createParams.Driver.Name + opts.Labels = createParams.Labels ic := abi.ContainerEngine{Libpod: runtime} report, err := ic.SecretCreate(r.Context(), createParams.Name, reader, opts) diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go index a76e3d988..854740b17 100644 --- a/pkg/api/handlers/libpod/containers.go +++ b/pkg/api/handlers/libpod/containers.go @@ -4,7 +4,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -248,7 +247,7 @@ func Checkpoint(w http.ResponseWriter, r *http.Request) { } if query.Export { - f, err := ioutil.TempFile("", "checkpoint") + f, err := os.CreateTemp("", "checkpoint") if err != nil { utils.InternalServerError(w, err) return @@ -329,7 +328,7 @@ func Restore(w http.ResponseWriter, r *http.Request) { var names []string if query.Import { - t, err := ioutil.TempFile("", "restore") + t, err := os.CreateTemp("", "restore") if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index 82c1971cd..412532954 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -182,7 +181,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { switch query.Format { case define.OCIArchive, define.V2s2Archive: - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -193,7 +192,7 @@ func ExportImage(w http.ResponseWriter, r *http.Request) { return } case define.OCIManifestDir, define.V2s2ManifestDir: - tmpdir, err := ioutil.TempDir("", "save") + tmpdir, err := os.MkdirTemp("", "save") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempdir: %w", err)) return @@ -279,7 +278,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { switch query.Format { case define.V2s2Archive, define.OCIArchive: - tmpfile, err := ioutil.TempFile("", "api.tar") + tmpfile, err := os.CreateTemp("", "api.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -290,7 +289,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { return } case define.OCIManifestDir, define.V2s2ManifestDir: - tmpdir, err := ioutil.TempDir("", "save") + tmpdir, err := os.MkdirTemp("", "save") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tmpdir: %w", err)) return @@ -329,7 +328,7 @@ func ExportImages(w http.ResponseWriter, r *http.Request) { func ImagesLoad(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime) - tmpfile, err := ioutil.TempFile("", "libpod-images-load.tar") + tmpfile, err := os.CreateTemp("", "libpod-images-load.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return @@ -378,7 +377,7 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) { // Check if we need to load the image from a URL or from the request's body. source := query.URL if len(query.URL) == 0 { - tmpfile, err := ioutil.TempFile("", "libpod-images-import.tar") + tmpfile, err := os.CreateTemp("", "libpod-images-import.tar") if err != nil { utils.Error(w, http.StatusInternalServerError, fmt.Errorf("unable to create tempfile: %w", err)) return diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go index d5af72a61..c96e4936b 100644 --- a/pkg/api/handlers/libpod/manifests.go +++ b/pkg/api/handlers/libpod/manifests.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "strconv" @@ -83,7 +83,7 @@ func ManifestCreate(w http.ResponseWriter, r *http.Request) { status = http.StatusCreated } - buffer, err := ioutil.ReadAll(r.Body) + buffer, err := io.ReadAll(r.Body) if err != nil { utils.InternalServerError(w, err) return diff --git a/pkg/api/handlers/libpod/secrets.go b/pkg/api/handlers/libpod/secrets.go index 6eba65f2b..c24ac8563 100644 --- a/pkg/api/handlers/libpod/secrets.go +++ b/pkg/api/handlers/libpod/secrets.go @@ -22,6 +22,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { Name string `schema:"name"` Driver string `schema:"driver"` DriverOpts map[string]string `schema:"driveropts"` + Labels map[string]string `schema:"labels"` }{ // override any golang type defaults } @@ -33,6 +34,7 @@ func CreateSecret(w http.ResponseWriter, r *http.Request) { opts.Driver = query.Driver opts.DriverOpts = query.DriverOpts + opts.Labels = query.Labels ic := abi.ContainerEngine{Libpod: runtime} report, err := ic.SecretCreate(r.Context(), query.Name, r.Body, opts) diff --git a/pkg/api/server/handler_logging.go b/pkg/api/server/handler_logging.go index 699fab7a5..38ee8321c 100644 --- a/pkg/api/server/handler_logging.go +++ b/pkg/api/server/handler_logging.go @@ -2,7 +2,6 @@ package server import ( "io" - "io/ioutil" "net/http" "time" @@ -41,7 +40,7 @@ func loggingHandler() mux.MiddlewareFunc { "API": "request", "X-Reference-Id": r.Header.Get("X-Reference-Id"), }) - r.Body = ioutil.NopCloser( + r.Body = io.NopCloser( io.TeeReader(r.Body, annotated.WriterLevel(logrus.TraceLevel))) w = responseWriter{ResponseWriter: w} diff --git a/pkg/api/server/handler_rid.go b/pkg/api/server/handler_rid.go index ee278071a..3e404cc31 100644 --- a/pkg/api/server/handler_rid.go +++ b/pkg/api/server/handler_rid.go @@ -2,7 +2,7 @@ package server import ( "fmt" - "io/ioutil" + "io" "net/http" "github.com/containers/podman/v4/pkg/api/types" @@ -17,7 +17,7 @@ import ( func referenceIDHandler() mux.MiddlewareFunc { return func(h http.Handler) http.Handler { // Only log Apache access_log-like entries at Info level or below - out := ioutil.Discard + out := io.Discard if logrus.IsLevelEnabled(logrus.InfoLevel) { out = logrus.StandardLogger().Out } diff --git a/pkg/api/server/register_secrets.go b/pkg/api/server/register_secrets.go index 8918ad238..a60145958 100644 --- a/pkg/api/server/register_secrets.go +++ b/pkg/api/server/register_secrets.go @@ -25,6 +25,14 @@ func (s *APIServer) registerSecretHandlers(r *mux.Router) error { // type: string // description: Secret driver // default: "file" + // - in: query + // name: driveropts + // type: string + // description: Secret driver options + // - in: query + // name: labels + // type: string + // description: Labels on the secret // - in: body // name: request // description: Secret diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index 270cd4207..52a632b33 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io/ioutil" "net/http" "os" "strings" @@ -233,7 +232,7 @@ func encodeMultiAuthConfigs(authConfigs map[string]types.DockerAuthConfig) (stri // TMPDIR will be used. func authConfigsToAuthFile(authConfigs map[string]types.DockerAuthConfig) (string, error) { // Initialize an empty temporary JSON file. - tmpFile, err := ioutil.TempFile("", "auth.json.") + tmpFile, err := os.CreateTemp("", "auth.json.") if err != nil { return "", err } diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index f25cbf2cc..90a81ac9a 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -3,7 +3,6 @@ package auth import ( "encoding/base64" "encoding/json" - "io/ioutil" "net/http" "os" "testing" @@ -37,10 +36,10 @@ func systemContextForAuthFile(t *testing.T, fileContents string) (*types.SystemC return nil, func() {} } - f, err := ioutil.TempFile("", "auth.json") + f, err := os.CreateTemp("", "auth.json") require.NoError(t, err) path := f.Name() - err = ioutil.WriteFile(path, []byte(fileContents), 0700) + err = os.WriteFile(path, []byte(fileContents), 0700) require.NoError(t, err) return &types.SystemContext{AuthFilePath: path}, func() { os.Remove(path) } } @@ -347,7 +346,7 @@ func TestAuthConfigsToAuthFile(t *testing.T) { assert.Empty(t, filePath) } else { assert.NoError(t, err) - content, err := ioutil.ReadFile(filePath) + content, err := os.ReadFile(filePath) require.NoError(t, err) assert.Contains(t, string(content), tc.expectedContains) os.Remove(filePath) diff --git a/pkg/bindings/errors.go b/pkg/bindings/errors.go index 29f087c22..d9dfa95a6 100644 --- a/pkg/bindings/errors.go +++ b/pkg/bindings/errors.go @@ -4,7 +4,7 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" + "io" "github.com/containers/podman/v4/pkg/errorhandling" ) @@ -29,7 +29,7 @@ func (h APIResponse) Process(unmarshalInto interface{}) error { // ProcessWithError drains the response body, and processes the HTTP status code // Note: Closing the response.Body is left to the caller func (h APIResponse) ProcessWithError(unmarshalInto interface{}, unmarshalErrorInto interface{}) error { - data, err := ioutil.ReadAll(h.Response.Body) + data, err := io.ReadAll(h.Response.Body) if err != nil { return fmt.Errorf("unable to process API response: %w", err) } diff --git a/pkg/bindings/generator/generator.go b/pkg/bindings/generator/generator.go index 06be52451..78244b502 100644 --- a/pkg/bindings/generator/generator.go +++ b/pkg/bindings/generator/generator.go @@ -12,7 +12,6 @@ import ( "go/ast" "go/parser" "go/token" - "io/ioutil" "os" "os/exec" "strings" @@ -72,7 +71,7 @@ func main() { ) srcFile := os.Getenv("GOFILE") inputStructName := os.Args[1] - b, err := ioutil.ReadFile(srcFile) + b, err := os.ReadFile(srcFile) if err != nil { panic(err) } diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go index ef875c9eb..260d977a8 100644 --- a/pkg/bindings/images/build.go +++ b/pkg/bindings/images/build.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "net/http" "net/url" "os" @@ -395,11 +394,11 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO dontexcludes := []string{"!Dockerfile", "!Containerfile", "!.dockerignore", "!.containerignore"} for _, c := range containerFiles { if c == "/dev/stdin" { - content, err := ioutil.ReadAll(os.Stdin) + content, err := io.ReadAll(os.Stdin) if err != nil { return nil, err } - tmpFile, err := ioutil.TempFile("", "build") + tmpFile, err := os.CreateTemp("", "build") if err != nil { return nil, err } @@ -465,7 +464,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if arr[0] == "src" { // read specified secret into a tmp file // move tmp file to tar and change secret source to relative tmp file - tmpSecretFile, err := ioutil.TempFile(options.ContextDirectory, "podman-build-secret") + tmpSecretFile, err := os.CreateTemp(options.ContextDirectory, "podman-build-secret") if err != nil { return nil, err } @@ -531,7 +530,7 @@ func Build(ctx context.Context, containerFiles []string, options entities.BuildO if logrus.IsLevelEnabled(logrus.DebugLevel) { if v, found := os.LookupEnv("PODMAN_RETAIN_BUILD_ARTIFACT"); found { if keep, _ := strconv.ParseBool(v); keep { - t, _ := ioutil.TempFile("", "build_*_client") + t, _ := os.CreateTemp("", "build_*_client") defer t.Close() body = io.TeeReader(response.Body, t) } @@ -737,10 +736,10 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) { } func parseDockerignore(root string) ([]string, error) { - ignore, err := ioutil.ReadFile(filepath.Join(root, ".containerignore")) + ignore, err := os.ReadFile(filepath.Join(root, ".containerignore")) if err != nil { var dockerIgnoreErr error - ignore, dockerIgnoreErr = ioutil.ReadFile(filepath.Join(root, ".dockerignore")) + ignore, dockerIgnoreErr = os.ReadFile(filepath.Join(root, ".dockerignore")) if dockerIgnoreErr != nil && !os.IsNotExist(dockerIgnoreErr) { return nil, err } diff --git a/pkg/bindings/manifests/manifests.go b/pkg/bindings/manifests/manifests.go index 752366937..d987e51d8 100644 --- a/pkg/bindings/manifests/manifests.go +++ b/pkg/bindings/manifests/manifests.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -257,7 +256,7 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp } defer response.Body.Close() - data, err := ioutil.ReadAll(response.Body) + data, err := io.ReadAll(response.Body) if err != nil { return "", fmt.Errorf("unable to process API response: %w", err) } diff --git a/pkg/bindings/secrets/types.go b/pkg/bindings/secrets/types.go index 01c3c248d..d2f449556 100644 --- a/pkg/bindings/secrets/types.go +++ b/pkg/bindings/secrets/types.go @@ -22,4 +22,5 @@ type CreateOptions struct { Name *string Driver *string DriverOpts map[string]string + Labels map[string]string } diff --git a/pkg/bindings/secrets/types_create_options.go b/pkg/bindings/secrets/types_create_options.go index 6b1666a42..c9c88e1f3 100644 --- a/pkg/bindings/secrets/types_create_options.go +++ b/pkg/bindings/secrets/types_create_options.go @@ -61,3 +61,18 @@ func (o *CreateOptions) GetDriverOpts() map[string]string { } return o.DriverOpts } + +// WithLabels set field Labels to given value +func (o *CreateOptions) WithLabels(value map[string]string) *CreateOptions { + o.Labels = value + return o +} + +// GetLabels returns value of field Labels +func (o *CreateOptions) GetLabels() map[string]string { + if o.Labels == nil { + var z map[string]string + return z + } + return o.Labels +} diff --git a/pkg/bindings/test/auth_test.go b/pkg/bindings/test/auth_test.go index c4c4b16d8..5b148a51c 100644 --- a/pkg/bindings/test/auth_test.go +++ b/pkg/bindings/test/auth_test.go @@ -1,7 +1,6 @@ package bindings_test import ( - "io/ioutil" "os" "time" @@ -76,7 +75,7 @@ var _ = Describe("Podman images", func() { imageRef := imageRep + ":" + imageTag // Create a temporary authentication file. - tmpFile, err := ioutil.TempFile("", "auth.json.") + tmpFile, err := os.CreateTemp("", "auth.json.") Expect(err).To(BeNil()) _, err = tmpFile.Write([]byte{'{', '}'}) Expect(err).To(BeNil()) diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go index 6b0175f59..f174b84f8 100644 --- a/pkg/bindings/test/common_test.go +++ b/pkg/bindings/test/common_test.go @@ -3,7 +3,6 @@ package bindings_test import ( "context" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -146,7 +145,7 @@ func newBindingTest() *bindingTest { // createTempDirinTempDir create a temp dir with prefix podman_test func createTempDirInTempDir() (string, error) { - return ioutil.TempDir("", "libpod_api") + return os.MkdirTemp("", "libpod_api") } func (b *bindingTest) startAPIService() *gexec.Session { @@ -264,7 +263,7 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { // If running localized tests, the cache dir is created and populated. if the // tests are remote, this is a no-op createCache() - path, err := ioutil.TempDir("", "libpodlock") + path, err := os.MkdirTemp("", "libpodlock") if err != nil { fmt.Println(err) os.Exit(1) diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go index e7c843143..248b9cdbf 100644 --- a/pkg/checkpoint/checkpoint_restore.go +++ b/pkg/checkpoint/checkpoint_restore.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" metadata "github.com/checkpoint-restore/checkpointctl/lib" @@ -26,7 +25,7 @@ import ( func CRImportCheckpointTar(ctx context.Context, runtime *libpod.Runtime, restoreOptions entities.RestoreOptions) ([]*libpod.Container, error) { // First get the container definition from the // tarball to a temporary directory - dir, err := ioutil.TempDir("", "checkpoint") + dir, err := os.MkdirTemp("", "checkpoint") if err != nil { return nil, err } diff --git a/pkg/checkpoint/crutils/checkpoint_restore_utils.go b/pkg/checkpoint/crutils/checkpoint_restore_utils.go index 132632322..b9db9562a 100644 --- a/pkg/checkpoint/crutils/checkpoint_restore_utils.go +++ b/pkg/checkpoint/crutils/checkpoint_restore_utils.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -237,7 +236,7 @@ func CRRuntimeSupportsPodCheckpointRestore(runtimePath string) bool { // given checkpoint archive and returns the runtime used to create // the given checkpoint archive. func CRGetRuntimeFromArchive(input string) (*string, error) { - dir, err := ioutil.TempDir("", "checkpoint") + dir, err := os.MkdirTemp("", "checkpoint") if err != nil { return nil, err } diff --git a/pkg/ctime/ctime_test.go b/pkg/ctime/ctime_test.go index abfc627da..014f15aa9 100644 --- a/pkg/ctime/ctime_test.go +++ b/pkg/ctime/ctime_test.go @@ -1,7 +1,6 @@ package ctime import ( - "io/ioutil" "os" "testing" "time" @@ -10,13 +9,13 @@ import ( func TestCreated(t *testing.T) { before := time.Now() - fileA, err := ioutil.TempFile("", "ctime-test-") + fileA, err := os.CreateTemp("", "ctime-test-") if err != nil { t.Error(err) } defer os.Remove(fileA.Name()) - fileB, err := ioutil.TempFile("", "ctime-test-") + fileB, err := os.CreateTemp("", "ctime-test-") if err != nil { t.Error(err) } diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go index cad11b0ab..b1eb3b005 100644 --- a/pkg/domain/entities/images.go +++ b/pkg/domain/entities/images.go @@ -335,7 +335,8 @@ type ImageSaveOptions struct { // Output - write image to the specified path. Output string // Quiet - suppress output when copying images - Quiet bool + Quiet bool + SignaturePolicy string } // ImageScpOptions provide options for securely copying images to and from a remote host diff --git a/pkg/domain/entities/secrets.go b/pkg/domain/entities/secrets.go index d8af937a7..5686b90e9 100644 --- a/pkg/domain/entities/secrets.go +++ b/pkg/domain/entities/secrets.go @@ -13,6 +13,7 @@ type SecretCreateReport struct { type SecretCreateOptions struct { Driver string DriverOpts map[string]string + Labels map[string]string } type SecretListRequest struct { @@ -55,6 +56,7 @@ type SecretVersion struct { type SecretSpec struct { Name string Driver SecretDriverSpec + Labels map[string]string } type SecretDriverSpec struct { @@ -70,6 +72,8 @@ type SecretCreateRequest struct { Data string // Driver represents a driver (default "file") Driver SecretDriverSpec + // Labels are labels on the secret + Labels map[string]string } // Secret create response diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go index 6934de60e..16b75829f 100644 --- a/pkg/domain/infra/abi/images.go +++ b/pkg/domain/infra/abi/images.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "io/fs" - "io/ioutil" "net/url" "os" "os/exec" @@ -340,7 +339,7 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri return err } - if err := ioutil.WriteFile(options.DigestFile, []byte(manifestDigest.String()), 0644); err != nil { + if err := os.WriteFile(options.DigestFile, []byte(manifestDigest.String()), 0644); err != nil { return err } } @@ -406,6 +405,7 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, saveOptions := &libimage.SaveOptions{} saveOptions.DirForceCompress = options.Compress saveOptions.OciAcceptUncompressedLayers = options.OciAcceptUncompressedLayers + saveOptions.SignaturePolicyPath = options.SignaturePolicy // Force signature removal to preserve backwards compat. // See https://github.com/containers/podman/pull/11669#issuecomment-925250264 @@ -910,5 +910,5 @@ func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStore if err != nil { return err } - return ioutil.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644) + return os.WriteFile(filepath.Join(signatureDir, sigFilename), newSig, 0644) } diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go index d447b4d00..847e81e69 100644 --- a/pkg/domain/infra/abi/play.go +++ b/pkg/domain/infra/abi/play.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -116,7 +115,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options validKinds := 0 // read yaml document - content, err := ioutil.ReadAll(body) + content, err := io.ReadAll(body) if err != nil { return nil, err } @@ -873,7 +872,7 @@ func (ic *ContainerEngine) playKubePVC(ctx context.Context, pvcYAML *v1.Persiste func readConfigMapFromFile(r io.Reader) (v1.ConfigMap, error) { var cm v1.ConfigMap - content, err := ioutil.ReadAll(r) + content, err := io.ReadAll(r) if err != nil { return cm, fmt.Errorf("unable to read ConfigMap YAML content: %w", err) } @@ -1005,7 +1004,7 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, _ e reports := new(entities.PlayKubeReport) // read yaml document - content, err := ioutil.ReadAll(body) + content, err := io.ReadAll(body) if err != nil { return nil, err } diff --git a/pkg/domain/infra/abi/secrets.go b/pkg/domain/infra/abi/secrets.go index 47159d65a..929858c5c 100644 --- a/pkg/domain/infra/abi/secrets.go +++ b/pkg/domain/infra/abi/secrets.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "path/filepath" "strings" @@ -14,7 +13,7 @@ import ( ) func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader io.Reader, options entities.SecretCreateOptions) (*entities.SecretCreateReport, error) { - data, _ := ioutil.ReadAll(reader) + data, _ := io.ReadAll(reader) secretsPath := ic.Libpod.GetSecretsStorageDir() manager, err := ic.Libpod.SecretsManager() if err != nil { @@ -45,6 +44,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader storeOpts := secrets.StoreOptions{ DriverOpts: options.DriverOpts, + Labels: options.Labels, } secretID, err := manager.Store(name, data, options.Driver, storeOpts) @@ -74,6 +74,9 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string return nil, nil, fmt.Errorf("inspecting secret %s: %w", nameOrID, err) } } + if secret.Labels == nil { + secret.Labels = make(map[string]string) + } report := &entities.SecretInfoReport{ ID: secret.ID, CreatedAt: secret.CreatedAt, @@ -84,6 +87,7 @@ func (ic *ContainerEngine) SecretInspect(ctx context.Context, nameOrIDs []string Name: secret.Driver, Options: secret.DriverOptions, }, + Labels: secret.Labels, }, } reports = append(reports, report) diff --git a/pkg/domain/infra/abi/terminal/sigproxy_commn.go b/pkg/domain/infra/abi/terminal/sigproxy_commn.go index 3a0132ef3..d42685508 100644 --- a/pkg/domain/infra/abi/terminal/sigproxy_commn.go +++ b/pkg/domain/infra/abi/terminal/sigproxy_commn.go @@ -15,33 +15,25 @@ import ( "github.com/sirupsen/logrus" ) -// Make sure the signal buffer is sufficiently big. -// runc is using the same value. -const signalBufferSize = 2048 - // ProxySignals ... func ProxySignals(ctr *libpod.Container) { // Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going // to the container now. shutdown.Stop() //nolint: errcheck - sigBuffer := make(chan os.Signal, signalBufferSize) + sigBuffer := make(chan os.Signal, signal.SignalBufferSize) signal.CatchAll(sigBuffer) logrus.Debugf("Enabling signal proxying") go func() { for s := range sigBuffer { - // Ignore SIGCHLD and SIGPIPE - these are mostly likely - // intended for the podman command itself. - // SIGURG was added because of golang 1.14 and its preemptive changes - // causing more signals to "show up". - // https://github.com/containers/podman/issues/5483 - if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG { + syscallSignal := s.(syscall.Signal) + if signal.IsSignalIgnoredBySigProxy(syscallSignal) { continue } - if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil { + if err := ctr.Kill(uint(syscallSignal)); err != nil { if errors.Is(err, define.ErrCtrStateInvalid) { logrus.Infof("Ceasing signal forwarding to container %s as it has stopped", ctr.ID()) } else { diff --git a/pkg/domain/infra/abi/trust.go b/pkg/domain/infra/abi/trust.go index c58ddff06..9b30920d7 100644 --- a/pkg/domain/infra/abi/trust.go +++ b/pkg/domain/infra/abi/trust.go @@ -3,7 +3,7 @@ package abi import ( "context" "fmt" - "io/ioutil" + "os" "github.com/containers/podman/v4/pkg/domain/entities" "github.com/containers/podman/v4/pkg/trust" @@ -18,7 +18,7 @@ func (ir *ImageEngine) ShowTrust(ctx context.Context, args []string, options ent if len(options.PolicyPath) > 0 { policyPath = options.PolicyPath } - report.Raw, err = ioutil.ReadFile(policyPath) + report.Raw, err = os.ReadFile(policyPath) if err != nil { return nil, err } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 0dc73081d..0b573686f 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -620,6 +620,9 @@ func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID s } func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { + if output == nil && errput == nil { + fmt.Printf("%s\n", name) + } attachErr := make(chan error) attachReady := make(chan bool) options := new(containers.AttachOptions).WithStream(true) @@ -825,6 +828,13 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta } // Attach + if opts.SigProxy { + remoteProxySignals(con.ID, func(signal string) error { + killOpts := entities.KillOptions{All: false, Latest: false, Signal: signal} + _, err := ic.ContainerKill(ctx, []string{con.ID}, killOpts) + return err + }) + } if err := startAndAttach(ic, con.ID, &opts.DetachKeys, opts.InputStream, opts.OutputStream, opts.ErrorStream); err != nil { if err == define.ErrDetach { return &report, nil diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go index cc99b1b3a..9ae1ff959 100644 --- a/pkg/domain/infra/tunnel/images.go +++ b/pkg/domain/infra/tunnel/images.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -264,7 +263,7 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrID string, tags []string, switch opts.Format { case "oci-dir", "docker-dir": - f, err = ioutil.TempFile("", "podman_save") + f, err = os.CreateTemp("", "podman_save") if err == nil { defer func() { _ = os.Remove(f.Name()) }() } diff --git a/pkg/domain/infra/tunnel/runtime.go b/pkg/domain/infra/tunnel/runtime.go index 6542ea5b7..75bd4ef5e 100644 --- a/pkg/domain/infra/tunnel/runtime.go +++ b/pkg/domain/infra/tunnel/runtime.go @@ -2,6 +2,12 @@ package tunnel import ( "context" + "os" + "syscall" + + "github.com/containers/podman/v4/libpod/define" + "github.com/containers/podman/v4/pkg/signal" + "github.com/sirupsen/logrus" ) // Image-related runtime using an ssh-tunnel to utilize Podman service @@ -18,3 +24,28 @@ type ContainerEngine struct { type SystemEngine struct { ClientCtx context.Context } + +func remoteProxySignals(ctrID string, killFunc func(string) error) { + sigBuffer := make(chan os.Signal, signal.SignalBufferSize) + signal.CatchAll(sigBuffer) + + logrus.Debugf("Enabling signal proxying") + + go func() { + for s := range sigBuffer { + syscallSignal := s.(syscall.Signal) + if signal.IsSignalIgnoredBySigProxy(syscallSignal) { + continue + } + signalName, err := signal.ParseSysSignalToName(syscallSignal) + if err != nil { + logrus.Infof("Ceasing signal %v forwarding to container %s as it has stopped: %s", s, ctrID, err) + } + if err := killFunc(signalName); err != nil { + if err.Error() == define.ErrCtrStateInvalid.Error() { + logrus.Debugf("Ceasing signal %q forwarding to container %s as it has stopped", signalName, ctrID) + } + } + } + }() +} diff --git a/pkg/domain/infra/tunnel/secrets.go b/pkg/domain/infra/tunnel/secrets.go index d26718b12..aa48cb764 100644 --- a/pkg/domain/infra/tunnel/secrets.go +++ b/pkg/domain/infra/tunnel/secrets.go @@ -14,7 +14,8 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader opts := new(secrets.CreateOptions). WithDriver(options.Driver). WithDriverOpts(options.DriverOpts). - WithName(name) + WithName(name). + WithLabels(options.Labels) created, err := secrets.Create(ic.ClientCtx, reader, opts) if err != nil { return nil, err diff --git a/pkg/domain/utils/scp.go b/pkg/domain/utils/scp.go index 44a0d94d7..19567551e 100644 --- a/pkg/domain/utils/scp.go +++ b/pkg/domain/utils/scp.go @@ -2,7 +2,6 @@ package utils import ( "fmt" - "io/ioutil" "net/url" "os" "os/exec" @@ -29,7 +28,7 @@ func ExecuteTransfer(src, dst string, parentFlags []string, quiet bool, sshMode return nil, nil, nil, nil, err } - f, err := ioutil.TempFile("", "podman") // open temp file for load/save output + f, err := os.CreateTemp("", "podman") // open temp file for load/save output if err != nil { return nil, nil, nil, nil, err } diff --git a/pkg/machine/config.go b/pkg/machine/config.go index 54aa9e1b7..8c22ae6a3 100644 --- a/pkg/machine/config.go +++ b/pkg/machine/config.go @@ -5,7 +5,6 @@ package machine import ( "errors" - "io/ioutil" "net" "net/url" "os" @@ -283,7 +282,7 @@ func (m *VMFile) Delete() error { // Read the contents of a given file and return in []bytes func (m *VMFile) Read() ([]byte, error) { - return ioutil.ReadFile(m.GetPath()) + return os.ReadFile(m.GetPath()) } // NewMachineFile is a constructor for VMFile diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go index c298d3b14..ebf59dcd7 100644 --- a/pkg/machine/e2e/init_test.go +++ b/pkg/machine/e2e/init_test.go @@ -1,7 +1,6 @@ package e2e_test import ( - "io/ioutil" "os" "strconv" "time" @@ -138,9 +137,9 @@ var _ = Describe("podman machine init", func() { }) It("machine init with volume", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) - _, err = ioutil.TempFile(tmpDir, "example") + _, err = os.CreateTemp(tmpDir, "example") Expect(err).To(BeNil()) mount := tmpDir + ":/testmountdir" defer os.RemoveAll(tmpDir) diff --git a/pkg/machine/e2e/machine_test.go b/pkg/machine/e2e/machine_test.go index 5de04b9f7..5cd89c7ab 100644 --- a/pkg/machine/e2e/machine_test.go +++ b/pkg/machine/e2e/machine_test.go @@ -3,7 +3,6 @@ package e2e_test import ( "fmt" "io" - "io/ioutil" url2 "net/url" "os" "path" @@ -77,7 +76,7 @@ var _ = SynchronizedAfterSuite(func() {}, func setup() (string, *machineTestBuilder) { // Set TMPDIR if this needs a new directory - homeDir, err := ioutil.TempDir("", "podman_test") + homeDir, err := os.MkdirTemp("", "podman_test") if err != nil { Fail(fmt.Sprintf("failed to create home directory: %q", err)) } diff --git a/pkg/machine/fcos.go b/pkg/machine/fcos.go index 246f92a19..311891c26 100644 --- a/pkg/machine/fcos.go +++ b/pkg/machine/fcos.go @@ -6,7 +6,7 @@ package machine import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" url2 "net/url" "os" @@ -175,7 +175,7 @@ func GetFCOSDownload(imageStream string) (*FcosDownloadInfo, error) { if err != nil { return nil, err } - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return nil, err } diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go index 366d10499..39ddce14c 100644 --- a/pkg/machine/ignition.go +++ b/pkg/machine/ignition.go @@ -7,7 +7,6 @@ import ( "encoding/json" "fmt" "io/fs" - "io/ioutil" "net/url" "os" "path/filepath" @@ -227,7 +226,7 @@ WantedBy=sysinit.target if err != nil { return err } - return ioutil.WriteFile(ign.WritePath, b, 0644) + return os.WriteFile(ign.WritePath, b, 0644) } func getDirs(usrName string) []Directory { @@ -559,7 +558,7 @@ func getCerts(certsDir string, isDir bool) []File { } func prepareCertFile(path string, name string) (File, error) { - b, err := ioutil.ReadFile(path) + b, err := os.ReadFile(path) if err != nil { logrus.Warnf("Unable to read cert file %v", err) return File{}, err diff --git a/pkg/machine/keys.go b/pkg/machine/keys.go index 94cbdac04..fce405695 100644 --- a/pkg/machine/keys.go +++ b/pkg/machine/keys.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -27,7 +26,7 @@ func CreateSSHKeys(writeLocation string) (string, error) { if err := generatekeys(writeLocation); err != nil { return "", err } - b, err := ioutil.ReadFile(writeLocation + ".pub") + b, err := os.ReadFile(writeLocation + ".pub") if err != nil { return "", err } @@ -45,7 +44,7 @@ func CreateSSHKeysPrefix(dir string, file string, passThru bool, skipExisting bo } else { fmt.Println("Keys already exist, reusing") } - b, err := ioutil.ReadFile(filepath.Join(dir, file) + ".pub") + b, err := os.ReadFile(filepath.Join(dir, file) + ".pub") if err != nil { return "", err } diff --git a/pkg/machine/pull.go b/pkg/machine/pull.go index 22a1b4c0a..9cba78237 100644 --- a/pkg/machine/pull.go +++ b/pkg/machine/pull.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" url2 "net/url" "os" @@ -191,7 +190,7 @@ func Decompress(localPath, uncompressedPath string) error { if err != nil { return err } - sourceFile, err := ioutil.ReadFile(localPath) + sourceFile, err := os.ReadFile(localPath) if err != nil { return err } diff --git a/pkg/machine/qemu/claim_darwin.go b/pkg/machine/qemu/claim_darwin.go index 66aed9ad8..c51d17bc9 100644 --- a/pkg/machine/qemu/claim_darwin.go +++ b/pkg/machine/qemu/claim_darwin.go @@ -2,7 +2,7 @@ package qemu import ( "fmt" - "io/ioutil" + "io" "net" "os" "os/user" @@ -43,7 +43,7 @@ func claimDockerSock() bool { return false } _ = con.SetReadDeadline(time.Now().Add(time.Second * 5)) - read, err := ioutil.ReadAll(con) + read, err := io.ReadAll(con) return err == nil && string(read) == "OK" } diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 738cd74be..fab25aa35 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -12,7 +12,6 @@ import ( "errors" "fmt" "io/fs" - "io/ioutil" "net" "net/http" "net/url" @@ -391,11 +390,11 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) { // If the user provides an ignition file, we need to // copy it into the conf dir if len(opts.IgnitionPath) > 0 { - inputIgnition, err := ioutil.ReadFile(opts.IgnitionPath) + inputIgnition, err := os.ReadFile(opts.IgnitionPath) if err != nil { return false, err } - return false, ioutil.WriteFile(v.getIgnitionFile(), inputIgnition, 0644) + return false, os.WriteFile(v.getIgnitionFile(), inputIgnition, 0644) } // Write the ignition file ign := machine.DynamicIgnition{ @@ -1109,7 +1108,7 @@ func getVMInfos() ([]*machine.ListResponse, error) { vm := new(MachineVM) if strings.HasSuffix(d.Name(), ".json") { fullPath := filepath.Join(vmConfigDir, d.Name()) - b, err := ioutil.ReadFile(fullPath) + b, err := os.ReadFile(fullPath) if err != nil { return err } @@ -1539,7 +1538,7 @@ func (v *MachineVM) writeConfig() error { if err != nil { return err } - if err := ioutil.WriteFile(v.ConfigPath.GetPath(), b, 0644); err != nil { + if err := os.WriteFile(v.ConfigPath.GetPath(), b, 0644); err != nil { return err } return nil diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go index 44b82b823..81980736d 100644 --- a/pkg/machine/wsl/machine.go +++ b/pkg/machine/wsl/machine.go @@ -10,7 +10,6 @@ import ( "fmt" "io" "io/fs" - "io/ioutil" "net/url" "os" "os/exec" @@ -423,7 +422,7 @@ func (v *MachineVM) writeConfig() error { if err != nil { return err } - if err := ioutil.WriteFile(jsonFile, b, 0644); err != nil { + if err := os.WriteFile(jsonFile, b, 0644); err != nil { return fmt.Errorf("could not write machine json config: %w", err) } @@ -1285,7 +1284,7 @@ func readWinProxyTid(v *MachineVM) (uint32, uint32, string, error) { } tidFile := filepath.Join(stateDir, winSshProxyTid) - contents, err := ioutil.ReadFile(tidFile) + contents, err := os.ReadFile(tidFile) if err != nil { return 0, 0, "", err } diff --git a/pkg/machine/wsl/util_windows.go b/pkg/machine/wsl/util_windows.go index 67d1bfc5c..5f8da10ec 100644 --- a/pkg/machine/wsl/util_windows.go +++ b/pkg/machine/wsl/util_windows.go @@ -4,7 +4,6 @@ import ( "encoding/base64" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -209,7 +208,7 @@ func reboot() error { return fmt.Errorf("could not create data directory: %w", err) } commFile := filepath.Join(dataDir, "podman-relaunch.dat") - if err := ioutil.WriteFile(commFile, []byte(encoded), 0600); err != nil { + if err := os.WriteFile(commFile, []byte(encoded), 0600); err != nil { return fmt.Errorf("could not serialize command state: %w", err) } diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c index 3588313c6..fb22ed221 100644 --- a/pkg/rootless/rootless_linux.c +++ b/pkg/rootless/rootless_linux.c @@ -235,6 +235,7 @@ can_use_shortcut () if (strcmp (argv[argc], "mount") == 0 || strcmp (argv[argc], "machine") == 0 + || strcmp (argv[argc], "context") == 0 || strcmp (argv[argc], "search") == 0 || (strcmp (argv[argc], "system") == 0 && argv[argc+1] && strcmp (argv[argc+1], "service") != 0)) { diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index f3453320f..7de50eaf1 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "os" "os/exec" gosignal "os/signal" @@ -224,7 +223,7 @@ func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) { } func copyMappings(from, to string) error { - content, err := ioutil.ReadFile(from) + content, err := os.ReadFile(from) if err != nil { return err } @@ -235,7 +234,7 @@ func copyMappings(from, to string) error { if bytes.Contains(content, []byte("4294967295")) { content = []byte("0 0 1\n1 1 4294967294\n") } - return ioutil.WriteFile(to, content, 0600) + return os.WriteFile(to, content, 0600) } func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ bool, _ int, retErr error) { @@ -343,13 +342,13 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo if !uidsMapped { logrus.Warnf("Using rootless single mapping into the namespace. This might break some images. Check /etc/subuid and /etc/subgid for adding sub*ids if not using a network user") setgroups := fmt.Sprintf("/proc/%d/setgroups", pid) - err = ioutil.WriteFile(setgroups, []byte("deny\n"), 0666) + err = os.WriteFile(setgroups, []byte("deny\n"), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write setgroups file: %w", err) } logrus.Debugf("write setgroups file exited with 0") - err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666) + err = os.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write uid_map: %w", err) } @@ -369,7 +368,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo gidsMapped = err == nil } if !gidsMapped { - err = ioutil.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getegid())), 0666) + err = os.WriteFile(gidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Getegid())), 0666) if err != nil { return false, -1, fmt.Errorf("cannot write gid_map: %w", err) } @@ -399,7 +398,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo // We have lost the race for writing the PID file, as probably another // process created a namespace and wrote the PID. // Try to join it. - data, err := ioutil.ReadFile(pausePid) + data, err := os.ReadFile(pausePid) if err == nil { var pid uint64 pid, err = strconv.ParseUint(string(data), 10, 0) @@ -469,7 +468,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st for _, path := range paths { if !needNewNamespace { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { lastErr = err continue diff --git a/pkg/signal/signal_common.go b/pkg/signal/signal_common.go index fc1ecc04d..a81d0461b 100644 --- a/pkg/signal/signal_common.go +++ b/pkg/signal/signal_common.go @@ -9,6 +9,10 @@ import ( "syscall" ) +// Make sure the signal buffer is sufficiently big. +// runc is using the same value. +const SignalBufferSize = 2048 + // ParseSignal translates a string to a valid syscall signal. // It returns an error if the signal map doesn't include the given signal. func ParseSignal(rawSignal string) (syscall.Signal, error) { @@ -56,3 +60,14 @@ func StopCatch(sigc chan os.Signal) { signal.Stop(sigc) close(sigc) } + +// ParseSysSignalToName translates syscall.Signal to its name in the operating system. +// For example, syscall.Signal(9) will return "KILL" on Linux system. +func ParseSysSignalToName(s syscall.Signal) (string, error) { + for k, v := range SignalMap { + if v == s { + return k, nil + } + } + return "", fmt.Errorf("unknown syscall signal: %s", s) +} diff --git a/pkg/signal/signal_common_test.go b/pkg/signal/signal_common_test.go index c4ae6b389..bd9b230f7 100644 --- a/pkg/signal/signal_common_test.go +++ b/pkg/signal/signal_common_test.go @@ -118,3 +118,52 @@ func TestParseSignalNameOrNumber(t *testing.T) { }) } } + +func TestParseSysSignalToName(t *testing.T) { + type args struct { + signal syscall.Signal + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "Kill should work", + args: args{ + signal: syscall.SIGKILL, + }, + want: "KILL", + wantErr: false, + }, + { + name: "Non-defined signal number should not work", + args: args{ + signal: 923, + }, + want: "", + wantErr: true, + }, + { + name: "garbage should fail", + args: args{ + signal: -1, + }, + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ParseSysSignalToName(tt.args.signal) + if (err != nil) != tt.wantErr { + t.Errorf("ParseSysSignalToName() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("ParseSysSignalToName() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/signal/signal_linux.go b/pkg/signal/signal_linux.go index 5103b6033..81e4ed758 100644 --- a/pkg/signal/signal_linux.go +++ b/pkg/signal/signal_linux.go @@ -89,3 +89,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_linux_mipsx.go b/pkg/signal/signal_linux_mipsx.go index cdf9ad4c5..c97eeb23d 100644 --- a/pkg/signal/signal_linux_mipsx.go +++ b/pkg/signal/signal_linux_mipsx.go @@ -90,3 +90,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_unix.go b/pkg/signal/signal_unix.go index 7919e3670..01d99d7bc 100644 --- a/pkg/signal/signal_unix.go +++ b/pkg/signal/signal_unix.go @@ -87,3 +87,11 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether sig-proxy should ignore syscall signal +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + // Ignore SIGCHLD and SIGPIPE - these are most likely intended for the podman command itself. + // SIGURG was added because of golang 1.14 and its preemptive changes causing more signals to "show up". + // https://github.com/containers/podman/issues/5483 + return s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG +} diff --git a/pkg/signal/signal_unsupported.go b/pkg/signal/signal_unsupported.go index 19ae93a61..590aaf978 100644 --- a/pkg/signal/signal_unsupported.go +++ b/pkg/signal/signal_unsupported.go @@ -87,3 +87,9 @@ var SignalMap = map[string]syscall.Signal{ "RTMAX-1": sigrtmax - 1, "RTMAX": sigrtmax, } + +// IsSignalIgnoredBySigProxy determines whether to sig-proxy should ignore syscall signal +// keep the container running or not. In unsupported OS this should not ignore any syscall signal. +func IsSignalIgnoredBySigProxy(s syscall.Signal) bool { + return false +} diff --git a/pkg/specgen/generate/config_linux_cgo.go b/pkg/specgen/generate/config_linux_cgo.go index 74ba4aeeb..6903ccb51 100644 --- a/pkg/specgen/generate/config_linux_cgo.go +++ b/pkg/specgen/generate/config_linux_cgo.go @@ -7,7 +7,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "github.com/containers/common/libimage" goSeccomp "github.com/containers/common/pkg/seccomp" @@ -47,7 +47,7 @@ func getSeccompConfig(s *specgen.SpecGenerator, configSpec *spec.Spec, img *libi if s.SeccompProfilePath != "" { logrus.Debugf("Loading seccomp profile from %q", s.SeccompProfilePath) - seccompProfile, err := ioutil.ReadFile(s.SeccompProfilePath) + seccompProfile, err := os.ReadFile(s.SeccompProfilePath) if err != nil { return nil, fmt.Errorf("opening seccomp profile failed: %w", err) } diff --git a/pkg/specgen/generate/pause_image.go b/pkg/specgen/generate/pause_image.go index ddf35f230..1b502927f 100644 --- a/pkg/specgen/generate/pause_image.go +++ b/pkg/specgen/generate/pause_image.go @@ -3,7 +3,6 @@ package generate import ( "context" "fmt" - "io/ioutil" "os" buildahDefine "github.com/containers/buildah/define" @@ -62,7 +61,7 @@ func buildPauseImage(rt *libpod.Runtime, rtConfig *config.Config) (string, error COPY %s /catatonit ENTRYPOINT ["/catatonit", "-P"]`, catatonitPath) - tmpF, err := ioutil.TempFile("", "pause.containerfile") + tmpF, err := os.CreateTemp("", "pause.containerfile") if err != nil { return "", err } diff --git a/pkg/specgen/generate/validate.go b/pkg/specgen/generate/validate.go index e9ebdfce3..10997a202 100644 --- a/pkg/specgen/generate/validate.go +++ b/pkg/specgen/generate/validate.go @@ -3,7 +3,6 @@ package generate import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" @@ -180,7 +179,7 @@ func verifyContainerResourcesCgroupV2(s *specgen.SpecGenerator) ([]string, error // If running under the root cgroup try to create or reuse a "probe" cgroup to read memory values own = "podman_probe" _ = os.MkdirAll(filepath.Join("/sys/fs/cgroup", own), 0o755) - _ = ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644) + _ = os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+memory"), 0o644) } memoryMax := filepath.Join("/sys/fs/cgroup", own, "memory.max") diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go index b14e2a032..d61e57ce2 100644 --- a/pkg/specgenutil/util.go +++ b/pkg/specgenutil/util.go @@ -3,7 +3,6 @@ package specgenutil import ( "errors" "fmt" - "io/ioutil" "net" "os" "strconv" @@ -18,7 +17,7 @@ import ( // ReadPodIDFile reads the specified file and returns its content (i.e., first // line). func ReadPodIDFile(path string) (string, error) { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("reading pod ID file: %w", err) } diff --git a/pkg/systemd/generate/containers.go b/pkg/systemd/generate/containers.go index 8510cfd42..71e9065ea 100644 --- a/pkg/systemd/generate/containers.go +++ b/pkg/systemd/generate/containers.go @@ -78,7 +78,7 @@ Requires={{{{- range $index, $value := .Requires }}}}{{{{ if $index}}}} {{{{end} {{{{- end}}}} [Service] -Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i{{{{- end}}}} +Environment={{{{.EnvVariable}}}}=%n{{{{- if (eq .IdentifySpecifier true) }}}}-%i {{{{- end}}}} {{{{- if .ExtraEnvs}}}} Environment={{{{- range $index, $value := .ExtraEnvs -}}}}{{{{if $index}}}} {{{{end}}}}{{{{ $value }}}}{{{{end}}}} {{{{- end}}}} @@ -254,6 +254,10 @@ func setContainerNameForTemplate(startCommand []string, info *containerInfo) ([] return startCommand, nil } +func formatOptionsString(cmd string) string { + return formatOptions(strings.Split(cmd, " ")) +} + func formatOptions(options []string) string { var formatted strings.Builder if len(options) == 0 { @@ -294,8 +298,8 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.Type = "forking" info.EnvVariable = define.EnvVariable info.ExecStart = "{{{{.Executable}}}} start {{{{.ContainerNameOrID}}}}" - info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}" - info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}" + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.ContainerNameOrID}}}}") for i, env := range info.AdditionalEnvVariables { info.AdditionalEnvVariables[i] = escapeSystemdArg(env) } @@ -312,9 +316,9 @@ func executeContainerTemplate(info *containerInfo, options entities.GenerateSyst info.NotifyAccess = "all" info.PIDFile = "" info.ContainerIDFile = "%t/%n.ctr-id" - info.ExecStartPre = "/bin/rm -f {{{{.ContainerIDFile}}}}" - info.ExecStop = "{{{{.Executable}}}} stop --ignore --cidfile={{{{.ContainerIDFile}}}}" - info.ExecStopPost = "{{{{.Executable}}}} rm -f --ignore --cidfile={{{{.ContainerIDFile}}}}" + info.ExecStartPre = formatOptionsString("/bin/rm -f {{{{.ContainerIDFile}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop --ignore --cidfile={{{{.ContainerIDFile}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} rm -f --ignore --cidfile={{{{.ContainerIDFile}}}}") // The create command must at least have three arguments: // /usr/bin/podman run $IMAGE index := 0 diff --git a/pkg/systemd/generate/containers_test.go b/pkg/systemd/generate/containers_test.go index 7f92e75b8..11e8f549e 100644 --- a/pkg/systemd/generate/containers_test.go +++ b/pkg/systemd/generate/containers_test.go @@ -57,8 +57,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=82 ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 -ExecStop=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 -ExecStopPost=/usr/bin/podman stop -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 +ExecStop=/usr/bin/podman stop \ + -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 +ExecStopPost=/usr/bin/podman stop \ + -t 22 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401 PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -83,8 +85,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -107,8 +111,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -134,8 +140,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -161,8 +169,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -188,8 +198,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -217,8 +229,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -243,8 +257,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -266,7 +282,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -276,8 +293,13 @@ ExecStart=/usr/bin/podman container run \ --replace \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -299,7 +321,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -309,8 +332,13 @@ ExecStart=/usr/bin/podman container run \ --sdnotify=container \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -332,7 +360,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -342,8 +371,13 @@ ExecStart=/usr/bin/podman container run \ --replace \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN "foo=arg \"with \" space" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -365,7 +399,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -375,8 +410,13 @@ ExecStart=/usr/bin/podman run \ -d \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -398,7 +438,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -409,8 +450,13 @@ ExecStart=/usr/bin/podman run \ -d \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -432,7 +478,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -442,8 +489,13 @@ ExecStart=/usr/bin/podman run \ --detach \ --name jadda-jadda \ --hostname hello-world awesome-image:latest command arg1 ... argN -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -465,15 +517,21 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -496,7 +554,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -505,8 +564,13 @@ ExecStart=/usr/bin/podman run \ ` + detachparam + ` awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -530,7 +594,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -541,8 +606,13 @@ ExecStart=/usr/bin/podman run \ --name test \ -p 80:80 awesome-image:latest somecmd \ --detach=false -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -564,7 +634,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman \ --events-backend none \ --runroot /root run \ @@ -573,8 +644,13 @@ ExecStart=/usr/bin/podman \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -596,15 +672,21 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman container run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -626,7 +708,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -637,8 +720,13 @@ ExecStart=/usr/bin/podman run \ --name test \ --log-driver=journald \ --log-opt=tag={{.Name}} awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -660,7 +748,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -670,8 +759,13 @@ ExecStart=/usr/bin/podman run \ --replace \ --name test awesome-image:latest sh \ -c "kill $$$$ && echo %%\\" -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -693,7 +787,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -704,8 +799,13 @@ ExecStart=/usr/bin/podman run \ --cgroups=foo \ --conmon-pidfile=foo \ --cidfile=foo alpine -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -727,7 +827,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -740,8 +841,13 @@ ExecStart=/usr/bin/podman run \ --conmon-pidfile=foo \ --cidfile=foo \ --pod-id-file /tmp/pod-foobar.pod-id-file alpine -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -764,7 +870,8 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Environment=FOO=abc "BAR=my test" USER=%%a Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -775,8 +882,13 @@ ExecStart=/usr/bin/podman run \ --env=BAR \ --env=MYENV=2 \ -e USER awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -802,8 +914,10 @@ Environment=USER=%%a Restart=on-failure TimeoutStopSec=70 ExecStart=/usr/bin/podman start foobar -ExecStop=/usr/bin/podman stop -t 10 foobar -ExecStopPost=/usr/bin/podman stop -t 10 foobar +ExecStop=/usr/bin/podman stop \ + -t 10 foobar +ExecStopPost=/usr/bin/podman stop \ + -t 10 foobar PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -826,15 +940,21 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure StartLimitBurst=42 TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -856,7 +976,8 @@ RequiresMountsFor=/var/run/containers/storage Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --cidfile=%t/%n.ctr-id \ --cgroups=no-conmon \ @@ -864,8 +985,13 @@ ExecStart=/usr/bin/podman run \ --sdnotify=conmon \ -d \ -h hostname awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all @@ -888,7 +1014,8 @@ Environment=PODMAN_SYSTEMD_UNIT=%n-%i Restart=on-failure StartLimitBurst=42 TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/%n.ctr-id +ExecStartPre=/bin/rm \ + -f %t/%n.ctr-id ExecStart=/usr/bin/podman run \ --name=container-foo-%i \ --cidfile=%t/%n.ctr-id \ @@ -896,8 +1023,13 @@ ExecStart=/usr/bin/podman run \ --rm \ --sdnotify=conmon \ -d awesome-image:latest -ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id -ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id +ExecStop=/usr/bin/podman stop \ + --ignore \ + --cidfile=%t/%n.ctr-id +ExecStopPost=/usr/bin/podman rm \ + -f \ + --ignore \ + --cidfile=%t/%n.ctr-id Type=notify NotifyAccess=all diff --git a/pkg/systemd/generate/pods.go b/pkg/systemd/generate/pods.go index 729a038a5..588bfb430 100644 --- a/pkg/systemd/generate/pods.go +++ b/pkg/systemd/generate/pods.go @@ -294,9 +294,9 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) } info.EnvVariable = define.EnvVariable - info.ExecStart = "{{{{.Executable}}}} start {{{{.InfraNameOrID}}}}" - info.ExecStop = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}" - info.ExecStopPost = "{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}" + info.ExecStart = formatOptionsString("{{{{.Executable}}}} start {{{{.InfraNameOrID}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} stop {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}} {{{{.InfraNameOrID}}}}") // Assemble the ExecStart command when creating a new pod. // @@ -371,11 +371,11 @@ func executePodTemplate(info *podInfo, options entities.GenerateSystemdOptions) startCommand = append(startCommand, podCreateArgs...) startCommand = escapeSystemdArguments(startCommand) - info.ExecStartPre1 = "/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}" - info.ExecStartPre2 = strings.Join(startCommand, " ") - info.ExecStart = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod start --pod-id-file {{{{.PodIDFile}}}}" - info.ExecStop = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}}-t {{{{.StopTimeout}}}}{{{{end}}}}" - info.ExecStopPost = "{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}" + info.ExecStartPre1 = formatOptionsString("/bin/rm -f {{{{.PIDFile}}}} {{{{.PodIDFile}}}}") + info.ExecStartPre2 = formatOptions(startCommand) + info.ExecStart = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod start --pod-id-file {{{{.PodIDFile}}}}") + info.ExecStop = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod stop --ignore --pod-id-file {{{{.PodIDFile}}}} {{{{if (ge .StopTimeout 0)}}}} -t {{{{.StopTimeout}}}}{{{{end}}}}") + info.ExecStopPost = formatOptionsString("{{{{.Executable}}}} {{{{if .RootFlags}}}}{{{{ .RootFlags}}}} {{{{end}}}}pod rm --ignore -f --pod-id-file {{{{.PodIDFile}}}}") } info.TimeoutStopSec = minTimeoutStopSec + info.StopTimeout diff --git a/pkg/systemd/generate/pods_test.go b/pkg/systemd/generate/pods_test.go index 000d73e9a..c44ab111e 100644 --- a/pkg/systemd/generate/pods_test.go +++ b/pkg/systemd/generate/pods_test.go @@ -79,8 +79,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -107,8 +109,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -136,8 +140,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -164,8 +170,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -192,8 +200,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -222,8 +232,10 @@ Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -246,11 +258,22 @@ Before= Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop foo -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop foo +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -276,8 +299,10 @@ Restart=on-failure RestartSec=15 TimeoutStopSec=102 ExecStart=/usr/bin/podman start jadda-jadda-infra -ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra -ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra +ExecStop=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra +ExecStopPost=/usr/bin/podman stop \ + -t 42 jadda-jadda-infra PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid Type=forking @@ -301,11 +326,24 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo "bar=arg with space" --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo "bar=arg with space" \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -329,11 +367,26 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman --events-backend none --runroot /root pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo "bar=arg with space" --replace -ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman --events-backend none --runroot /root pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman \ + --events-backend none \ + --runroot /root pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo "bar=arg with space" \ + --replace +ExecStart=/usr/bin/podman --events-backend none --runroot /root pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman --events-backend none --runroot /root pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman --events-backend none --runroot /root pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -357,11 +410,24 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --exit-policy=stop --name foo --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --exit-policy=stop \ + --name foo \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking @@ -385,11 +451,25 @@ Before=container-1.service container-2.service Environment=PODMAN_SYSTEMD_UNIT=%n Restart=on-failure TimeoutStopSec=70 -ExecStartPre=/bin/rm -f %t/pod-123abc.pid %t/pod-123abc.pod-id -ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-123abc.pid --pod-id-file %t/pod-123abc.pod-id --name foo --label key={{someval}} --exit-policy=continue --replace -ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-123abc.pod-id -ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-123abc.pod-id -t 10 -ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-123abc.pod-id +ExecStartPre=/bin/rm \ + -f %t/pod-123abc.pid %t/pod-123abc.pod-id +ExecStartPre=/usr/bin/podman pod create \ + --infra-conmon-pidfile %t/pod-123abc.pid \ + --pod-id-file %t/pod-123abc.pod-id \ + --name foo \ + --label key={{someval}} \ + --exit-policy=continue \ + --replace +ExecStart=/usr/bin/podman pod start \ + --pod-id-file %t/pod-123abc.pod-id +ExecStop=/usr/bin/podman pod stop \ + --ignore \ + --pod-id-file %t/pod-123abc.pod-id \ + -t 10 +ExecStopPost=/usr/bin/podman pod rm \ + --ignore \ + -f \ + --pod-id-file %t/pod-123abc.pod-id PIDFile=%t/pod-123abc.pid Type=forking diff --git a/pkg/systemd/notifyproxy/notifyproxy.go b/pkg/systemd/notifyproxy/notifyproxy.go index 1bfab9ca0..ea1522bb3 100644 --- a/pkg/systemd/notifyproxy/notifyproxy.go +++ b/pkg/systemd/notifyproxy/notifyproxy.go @@ -4,7 +4,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "strings" @@ -49,7 +48,7 @@ type NotifyProxy struct { // New creates a NotifyProxy. The specified temp directory can be left empty. func New(tmpDir string) (*NotifyProxy, error) { - tempFile, err := ioutil.TempFile(tmpDir, "-podman-notify-proxy.sock") + tempFile, err := os.CreateTemp(tmpDir, "-podman-notify-proxy.sock") if err != nil { return nil, err } diff --git a/pkg/trust/policy.go b/pkg/trust/policy.go index d746e78cf..e0c5e0689 100644 --- a/pkg/trust/policy.go +++ b/pkg/trust/policy.go @@ -7,7 +7,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -72,7 +71,7 @@ type gpgIDReader func(string) []string // createTmpFile creates a temp file under dir and writes the content into it func createTmpFile(dir, pattern string, content []byte) (string, error) { - tmpfile, err := ioutil.TempFile(dir, pattern) + tmpfile, err := os.CreateTemp(dir, pattern) if err != nil { return "", err } @@ -133,7 +132,7 @@ func parseUids(colonDelimitKeys []byte) []string { // getPolicy parses policy.json into policyContent. func getPolicy(policyPath string) (policyContent, error) { var policyContentStruct policyContent - policyContent, err := ioutil.ReadFile(policyPath) + policyContent, err := os.ReadFile(policyPath) if err != nil { return policyContentStruct, fmt.Errorf("unable to read policy file: %w", err) } @@ -207,7 +206,7 @@ func AddPolicyEntries(policyPath string, input AddPolicyEntriesInput) error { _, err = os.Stat(policyPath) if !os.IsNotExist(err) { - policyContent, err := ioutil.ReadFile(policyPath) + policyContent, err := os.ReadFile(policyPath) if err != nil { return err } @@ -244,5 +243,5 @@ func AddPolicyEntries(policyPath string, input AddPolicyEntriesInput) error { if err != nil { return fmt.Errorf("setting trust policy: %w", err) } - return ioutil.WriteFile(policyPath, data, 0644) + return os.WriteFile(policyPath, data, 0644) } diff --git a/pkg/trust/registries.go b/pkg/trust/registries.go index 86d580059..ed7bca1d6 100644 --- a/pkg/trust/registries.go +++ b/pkg/trust/registries.go @@ -2,7 +2,6 @@ package trust import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -72,7 +71,7 @@ func loadAndMergeConfig(dirPath string) (*registryConfiguration, error) { continue } configPath := filepath.Join(dirPath, configName) - configBytes, err := ioutil.ReadFile(configPath) + configBytes, err := os.ReadFile(configPath) if err != nil { return nil, err } diff --git a/pkg/util/utils_freebsd.go b/pkg/util/utils_freebsd.go index 9b0d7c8c7..ba91308af 100644 --- a/pkg/util/utils_freebsd.go +++ b/pkg/util/utils_freebsd.go @@ -13,6 +13,6 @@ func GetContainerPidInformationDescriptors() ([]string, error) { return []string{}, errors.New("this function is not supported on freebsd") } -func AddPrivilegedDevices(g *generate.Generator) error { +func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error { return nil } diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go index 7b2d98666..07927db1c 100644 --- a/pkg/util/utils_linux.go +++ b/pkg/util/utils_linux.go @@ -70,7 +70,7 @@ func FindDeviceNodes() (map[string]string, error) { return nodes, nil } -func AddPrivilegedDevices(g *generate.Generator) error { +func AddPrivilegedDevices(g *generate.Generator, systemdMode bool) error { hostDevices, err := getDevices("/dev") if err != nil { return err @@ -104,6 +104,9 @@ func AddPrivilegedDevices(g *generate.Generator) error { } } else { for _, d := range hostDevices { + if systemdMode && strings.HasPrefix(d.Path, "/dev/tty") { + continue + } g.AddDevice(d) } // Add resources device - need to clear the existing one first. diff --git a/test/apiv2/50-secrets.at b/test/apiv2/50-secrets.at index ed0e8fb6b..acd8f3de9 100644 --- a/test/apiv2/50-secrets.at +++ b/test/apiv2/50-secrets.at @@ -7,9 +7,6 @@ t POST secrets/create Name=mysecret Data=c2VjcmV0 200\ .ID~.* \ -# secret create unsupported labels -t POST secrets/create Name=mysecret Data=c2VjcmV0 Labels='{"fail":"fail"}' 400 - # secret create name already in use t POST secrets/create Name=mysecret Data=c2VjcmV0 409 @@ -59,8 +56,15 @@ t GET libpod/secrets/json?filters='garb1age}' 500 \ t GET libpod/secrets/json?filters='{"label":["testl' 500 \ .cause="unexpected end of JSON input" +# secret with labels +t POST secrets/create Name=labeledsecret Data=c2VjcmV0 Labels='{"foo":"bar"}' 200 +t GET secrets/labeledsecret 200 \ + .Spec.Labels.foo=bar + # secret rm t DELETE secrets/mysecret 204 +t DELETE secrets/labeledsecret 204 + # secret rm non-existent secret t DELETE secrets/bogus 404 diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go index d1332665a..6773eae02 100644 --- a/test/e2e/benchmarks_test.go +++ b/test/e2e/benchmarks_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path" "strconv" @@ -108,7 +107,7 @@ var _ = Describe("Podman Benchmark Suite", func() { if f.IsDir() { continue } - raw, err := ioutil.ReadFile(path.Join(timedir, f.Name())) + raw, err := os.ReadFile(path.Join(timedir, f.Name())) if err != nil { Fail(fmt.Sprintf("Error reading timing file: %v", err)) } diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go index 424c7244e..0f6cb2a10 100644 --- a/test/e2e/build_test.go +++ b/test/e2e/build_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -219,10 +218,10 @@ var _ = Describe("Podman build", func() { } fakeFile := filepath.Join(os.TempDir(), "Containerfile") - Expect(ioutil.WriteFile(fakeFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) + Expect(os.WriteFile(fakeFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) targetFile := filepath.Join(targetPath, "Containerfile") - Expect(ioutil.WriteFile(targetFile, []byte("FROM scratch"), 0755)).To(BeNil()) + Expect(os.WriteFile(targetFile, []byte("FROM scratch"), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(fakeFile)).To(BeNil()) @@ -257,7 +256,7 @@ var _ = Describe("Podman build", func() { session := podmanTest.Podman([]string{"build", "--pull-never", "build/basicalpine", "--iidfile", targetFile}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) // Verify that id is correct inspect := podmanTest.Podman([]string{"inspect", string(id)}) @@ -311,7 +310,7 @@ var _ = Describe("Podman build", func() { RUN printenv http_proxy`, ALPINE) dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "--http-proxy", "--file", dockerfilePath, podmanTest.TempDir}) session.Wait(120) @@ -330,7 +329,7 @@ RUN printenv http_proxy`, ALPINE) RUN exit 5`, ALPINE) dockerfilePath := filepath.Join(podmanTest.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "error-test", "--file", dockerfilePath, podmanTest.TempDir}) session.Wait(120) @@ -388,7 +387,7 @@ RUN exit 5`, ALPINE) err = os.Mkdir(targetSubPath, 0755) Expect(err).To(BeNil()) dummyFile := filepath.Join(targetSubPath, "dummy") - err = ioutil.WriteFile(dummyFile, []byte("dummy"), 0644) + err = os.WriteFile(dummyFile, []byte("dummy"), 0644) Expect(err).To(BeNil()) containerfile := fmt.Sprintf(`FROM %s @@ -396,7 +395,7 @@ ADD . /test RUN find /test`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -437,7 +436,7 @@ RUN find /test`, ALPINE) containerfile := fmt.Sprintf("FROM %s", ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -476,7 +475,7 @@ ADD . /testfilter/ RUN find /testfilter/`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) targetSubPath := filepath.Join(targetPath, "subdir") @@ -484,15 +483,15 @@ RUN find /testfilter/`, ALPINE) Expect(err).To(BeNil()) dummyFile1 := filepath.Join(targetPath, "dummy1") - err = ioutil.WriteFile(dummyFile1, []byte("dummy1"), 0644) + err = os.WriteFile(dummyFile1, []byte("dummy1"), 0644) Expect(err).To(BeNil()) dummyFile2 := filepath.Join(targetPath, "dummy2") - err = ioutil.WriteFile(dummyFile2, []byte("dummy2"), 0644) + err = os.WriteFile(dummyFile2, []byte("dummy2"), 0644) Expect(err).To(BeNil()) dummyFile3 := filepath.Join(targetSubPath, "dummy3") - err = ioutil.WriteFile(dummyFile3, []byte("dummy3"), 0644) + err = os.WriteFile(dummyFile3, []byte("dummy3"), 0644) Expect(err).To(BeNil()) defer func() { @@ -509,7 +508,7 @@ subdir**` // test .dockerignore By("Test .dockererignore") - err = ioutil.WriteFile(dockerignoreFile, []byte(dockerignoreContent), 0644) + err = os.WriteFile(dockerignoreFile, []byte(dockerignoreContent), 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "test", "."}) @@ -540,18 +539,18 @@ subdir**` contents.WriteString("RUN find /testfilter/ -print\n") containerfile := filepath.Join(tempdir, "Containerfile") - Expect(ioutil.WriteFile(containerfile, contents.Bytes(), 0644)).ToNot(HaveOccurred()) + Expect(os.WriteFile(containerfile, contents.Bytes(), 0644)).ToNot(HaveOccurred()) contextDir, err := CreateTempDirInTempDir() Expect(err).ToNot(HaveOccurred()) defer os.RemoveAll(contextDir) - Expect(ioutil.WriteFile(filepath.Join(contextDir, "expected"), contents.Bytes(), 0644)). + Expect(os.WriteFile(filepath.Join(contextDir, "expected"), contents.Bytes(), 0644)). ToNot(HaveOccurred()) subdirPath := filepath.Join(contextDir, "subdir") Expect(os.MkdirAll(subdirPath, 0755)).ToNot(HaveOccurred()) - Expect(ioutil.WriteFile(filepath.Join(subdirPath, "extra"), contents.Bytes(), 0644)). + Expect(os.WriteFile(filepath.Join(subdirPath, "extra"), contents.Bytes(), 0644)). ToNot(HaveOccurred()) randomFile := filepath.Join(subdirPath, "randomFile") dd := exec.Command("dd", "if=/dev/urandom", "of="+randomFile, "bs=1G", "count=1") @@ -567,7 +566,7 @@ subdir**` }() By("Test .containerignore filtering subdirectory") - err = ioutil.WriteFile(filepath.Join(contextDir, ".containerignore"), []byte(`subdir/`), 0644) + err = os.WriteFile(filepath.Join(contextDir, ".containerignore"), []byte(`subdir/`), 0644) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{"build", "-f", containerfile, contextDir}) @@ -597,7 +596,7 @@ subdir**` err = os.Mkdir(targetSubPath, 0755) Expect(err).To(BeNil()) dummyFile := filepath.Join(targetSubPath, "dummy") - err = ioutil.WriteFile(dummyFile, []byte("dummy"), 0644) + err = os.WriteFile(dummyFile, []byte("dummy"), 0644) Expect(err).To(BeNil()) emptyDir := filepath.Join(targetSubPath, "emptyDir") @@ -612,7 +611,7 @@ RUN find /test RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) containerfilePath := filepath.Join(targetSubPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { @@ -641,7 +640,7 @@ RUN [[ -L /test/dummy-symlink ]] && echo SYMLNKOK || echo SYMLNKERR`, ALPINE) RUN cat /etc/hosts RUN grep CapEff /proc/self/status` - Expect(ioutil.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(containerFile)).To(BeNil()) @@ -668,7 +667,7 @@ RUN grep CapEff /proc/self/status` Expect(err).To(BeNil()) containerFile := filepath.Join(targetPath, "Containerfile") - Expect(ioutil.WriteFile(containerFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(fmt.Sprintf("FROM %s", ALPINE)), 0755)).To(BeNil()) defer func() { Expect(os.RemoveAll(containerFile)).To(BeNil()) @@ -712,7 +711,7 @@ RUN grep CapEff /proc/self/status` RUN echo hello`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--timestamp", "0", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -730,7 +729,7 @@ RUN echo hello`, ALPINE) containerFile := filepath.Join(targetPath, "Containerfile") content := `FROM scratch` - Expect(ioutil.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) + Expect(os.WriteFile(containerFile, []byte(content), 0755)).To(BeNil()) session := podmanTest.Podman([]string{"build", "--log-rusage", "--pull-never", targetPath}) session.WaitWithDefaultTimeout() @@ -743,7 +742,7 @@ RUN echo hello`, ALPINE) It("podman build --arch --os flag", func() { containerfile := `FROM scratch` containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--arch", "foo", "--os", "bar", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -762,7 +761,7 @@ RUN echo hello`, ALPINE) It("podman build --os windows flag", func() { containerfile := `FROM scratch` containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--os", "windows", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -785,7 +784,7 @@ RUN echo hello`, ALPINE) containerfile := fmt.Sprintf(`FROM %s RUN ls /dev/fuse`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -801,7 +800,7 @@ RUN ls /dev/fuse`, ALPINE) containerfile := fmt.Sprintf(`FROM %s RUN ls /dev/test1`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "--pull-never", "-t", "test", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -822,7 +821,7 @@ RUN ls /dev/test1`, ALPINE) Expect(err).To(BeNil()) err = os.Mkdir(buildRoot, 0755) Expect(err).To(BeNil()) - err = ioutil.WriteFile(containerFilePath, []byte(containerFile), 0755) + err = os.WriteFile(containerFilePath, []byte(containerFile), 0755) Expect(err).To(BeNil()) build := podmanTest.Podman([]string{"build", "-f", containerFilePath, buildRoot}) build.WaitWithDefaultTimeout() diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index 452a378c2..14814628d 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -287,7 +286,7 @@ var _ = Describe("Podman commit", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) check := podmanTest.Podman([]string{"inspect", "foobar.com/test1-image:latest"}) check.WaitWithDefaultTimeout() data := check.InspectImageJSON() @@ -297,7 +296,7 @@ var _ = Describe("Podman commit", func() { It("podman commit should not commit secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -322,7 +321,7 @@ var _ = Describe("Podman commit", func() { It("podman commit should not commit env secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 690e2f22c..67a889b25 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "math/rand" "net" "net/url" @@ -144,7 +143,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { } f.Close() } - path, err := ioutil.TempDir("", "libpodlock") + path, err := os.MkdirTemp("", "libpodlock") if err != nil { fmt.Println(err) os.Exit(1) @@ -875,7 +874,7 @@ func writeConf(conf []byte, confPath string) { fmt.Println(err) } } - if err := ioutil.WriteFile(confPath, conf, 0o777); err != nil { + if err := os.WriteFile(confPath, conf, 0o777); err != nil { fmt.Println(err) } } @@ -967,7 +966,7 @@ func (s *PodmanSessionIntegration) jq(jqCommand string) (string, error) { func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers string, label string) string { dockerfilePath := filepath.Join(p.TempDir, "Dockerfile") - err := ioutil.WriteFile(dockerfilePath, []byte(dockerfile), 0755) + err := os.WriteFile(dockerfilePath, []byte(dockerfile), 0755) Expect(err).To(BeNil()) cmd := []string{"build", "--pull-never", "--layers=" + layers, "--file", dockerfilePath} if label != "" { diff --git a/test/e2e/container_create_volume_test.go b/test/e2e/container_create_volume_test.go index 3c54691aa..6d6173d0f 100644 --- a/test/e2e/container_create_volume_test.go +++ b/test/e2e/container_create_volume_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -15,7 +14,7 @@ import ( func buildDataVolumeImage(pTest *PodmanTestIntegration, image, data, dest string) { // Create a dummy file for data volume dummyFile := filepath.Join(pTest.TempDir, data) - err := ioutil.WriteFile(dummyFile, []byte(data), 0644) + err := os.WriteFile(dummyFile, []byte(data), 0644) Expect(err).To(BeNil()) // Create a data volume container image but no CMD binary in it @@ -29,7 +28,7 @@ VOLUME %s/`, data, dest, dest) func createContainersConfFile(pTest *PodmanTestIntegration) { configPath := filepath.Join(pTest.TempDir, "containers.conf") containersConf := []byte("[containers]\nprepare_volume_on_create = true\n") - err := ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err := os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).To(BeNil()) // Set custom containers.conf file diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index 41e78ce0e..211f6b572 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -208,7 +207,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { tempdir, err = CreateTempDirInTempDir() Expect(err).ToNot(HaveOccurred()) - err := ioutil.WriteFile(conffile, []byte(fmt.Sprintf("[containers]\nvolumes=[\"%s:%s:Z\",]\n", tempdir, tempdir)), 0755) + err := os.WriteFile(conffile, []byte(fmt.Sprintf("[containers]\nvolumes=[\"%s:%s:Z\",]\n", tempdir, tempdir)), 0755) Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conffile) @@ -406,7 +405,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { profile := filepath.Join(podmanTest.TempDir, "seccomp.json") containersConf := []byte(fmt.Sprintf("[containers]\nseccomp_profile=\"%s\"", profile)) - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -430,7 +429,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) containersConf := []byte("[engine]\nimage_copy_tmp_dir=\"/foobar\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -443,7 +442,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { Expect(session.OutputToString()).To(Equal("/foobar")) containersConf = []byte(fmt.Sprintf("[engine]\nimage_copy_tmp_dir=%q", storagePath)) - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { podmanTest.RestartRemoteService() @@ -455,7 +454,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { Expect(session.Out.Contents()).To(ContainSubstring(storagePath)) containersConf = []byte("[engine]\nimage_copy_tmp_dir=\"storage1\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if !IsRemote() { @@ -485,7 +484,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) containersConf := []byte("[engine]\ninfra_image=\"" + infra1 + "\"") - err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + err = os.WriteFile(configPath, containersConf, os.ModePerm) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -520,7 +519,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { os.Setenv("CONTAINERS_CONF", configPath) defer os.Remove(configPath) - err := ioutil.WriteFile(configPath, []byte("[engine]\nremote=true"), os.ModePerm) + err := os.WriteFile(configPath, []byte("[engine]\nremote=true"), os.ModePerm) Expect(err).ToNot(HaveOccurred()) // podmanTest.Podman() cannot be used as it was initialized remote==false @@ -540,7 +539,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { } conffile := filepath.Join(podmanTest.TempDir, "container.conf") - err := ioutil.WriteFile(conffile, []byte("[containers]\ncgroups=\"disabled\"\n"), 0755) + err := os.WriteFile(conffile, []byte("[containers]\ncgroups=\"disabled\"\n"), 0755) Expect(err).ToNot(HaveOccurred()) result := podmanTest.Podman([]string{"create", ALPINE, "true"}) @@ -572,7 +571,7 @@ var _ = Describe("Verify podman containers.conf usage", func() { It("podman containers.conf runtime", func() { SkipIfRemote("--runtime option is not available for remote commands") conffile := filepath.Join(podmanTest.TempDir, "container.conf") - err := ioutil.WriteFile(conffile, []byte("[engine]\nruntime=\"testruntime\"\n"), 0755) + err := os.WriteFile(conffile, []byte("[engine]\nruntime=\"testruntime\"\n"), 0755) Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conffile) diff --git a/test/e2e/cp_test.go b/test/e2e/cp_test.go index 8a65b85d3..214903a16 100644 --- a/test/e2e/cp_test.go +++ b/test/e2e/cp_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/exec" "os/user" @@ -43,13 +42,13 @@ var _ = Describe("Podman cp", func() { // Copy a file to the container, then back to the host and make sure // that the contents match. It("podman cp file", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp file test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) // Create a container. NOTE that container mustn't be running for copying. @@ -72,7 +71,7 @@ var _ = Describe("Podman cp", func() { // Copy FROM the container. - destFile, err := ioutil.TempFile("", "") + destFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer destFile.Close() defer os.Remove(destFile.Name()) @@ -86,7 +85,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) // Now make sure the content matches. - roundtripContent, err := ioutil.ReadFile(destFile.Name()) + roundtripContent, err := os.ReadFile(destFile.Name()) Expect(err).To(BeNil()) Expect(roundtripContent).To(Equal(originalContent)) }) @@ -94,13 +93,13 @@ var _ = Describe("Podman cp", func() { // Copy a file to the container, then back to the host in --pid=host It("podman cp --pid=host file", func() { SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp file test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) // Create a container. NOTE that container mustn't be running for copying. @@ -120,7 +119,7 @@ var _ = Describe("Podman cp", func() { // Copy FROM the container. - destFile, err := ioutil.TempFile("", "") + destFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer destFile.Close() defer os.Remove(destFile.Name()) @@ -130,7 +129,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) // Now make sure the content matches. - roundtripContent, err := ioutil.ReadFile(destFile.Name()) + roundtripContent, err := os.ReadFile(destFile.Name()) Expect(err).To(BeNil()) Expect(roundtripContent).To(Equal(originalContent)) }) @@ -139,13 +138,13 @@ var _ = Describe("Podman cp", func() { // make sure that the link and the resolved path are accessible and // give the right content. It("podman cp symlink", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp symlink test") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top"}) @@ -178,13 +177,13 @@ var _ = Describe("Podman cp", func() { // the path to the volume's mount point on the host, and 3) copy the // data to the volume and not the container. It("podman cp volume", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) originalContent := []byte("podman cp volume") - err = ioutil.WriteFile(srcFile.Name(), originalContent, 0644) + err = os.WriteFile(srcFile.Name(), originalContent, 0644) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"volume", "create", "data"}) session.WaitWithDefaultTimeout() @@ -205,7 +204,7 @@ var _ = Describe("Podman cp", func() { Expect(session).Should(Exit(0)) volumeMountPoint := session.OutputToString() - copiedContent, err := ioutil.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) + copiedContent, err := os.ReadFile(filepath.Join(volumeMountPoint, "file.txt")) Expect(err).To(BeNil()) Expect(copiedContent).To(Equal(originalContent)) }) @@ -214,7 +213,7 @@ var _ = Describe("Podman cp", func() { // it to the host and back to the container and make sure that we can // access it, and (roughly) the right users own it. It("podman cp from ctr chown ", func() { - srcFile, err := ioutil.TempFile("", "") + srcFile, err := os.CreateTemp("", "") Expect(err).To(BeNil()) defer srcFile.Close() defer os.Remove(srcFile.Name()) @@ -265,7 +264,7 @@ var _ = Describe("Podman cp", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"cp", container + ":/", tmpDir}) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index d5920dc3e..9a18dea18 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -242,7 +241,7 @@ var _ = Describe("Podman create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(125)) - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index f4ee688b7..6bd13f7da 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -545,7 +544,7 @@ RUN useradd -u 1000 auser`, fedoraMinimal) It("podman exec with env var secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index cd2378bdf..08eaa4dcf 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/user" "path/filepath" @@ -278,7 +277,7 @@ var _ = Describe("Podman generate kube", func() { if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -752,7 +751,7 @@ var _ = Describe("Podman generate kube", func() { kube.WaitWithDefaultTimeout() Expect(kube).Should(Exit(0)) - b, err := ioutil.ReadFile(outputFile) + b, err := os.ReadFile(outputFile) Expect(err).ShouldNot(HaveOccurred()) pod := new(v1.Pod) err = yaml.Unmarshal(b, pod) @@ -1045,7 +1044,7 @@ ENTRYPOINT ["sleep"]` targetPath, err := CreateTempDirInTempDir() Expect(err).To(BeNil()) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) image := "generatekube:test" @@ -1135,7 +1134,7 @@ USER test1` targetPath, err := CreateTempDirInTempDir() Expect(err).To(BeNil()) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) image := "generatekube:test" diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 347440faf..01c0aefab 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "strings" @@ -108,7 +107,7 @@ var _ = Describe("Podman generate systemd", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=1294")) - Expect(session.OutputToString()).To(ContainSubstring(" stop -t 1234 ")) + Expect(session.OutputToString()).To(ContainSubstring("-t 1234")) }) It("podman generate systemd", func() { @@ -149,14 +148,15 @@ var _ = Describe("Podman generate systemd", func() { Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) Expect(session.OutputToString()).ToNot(ContainSubstring("TimeoutStartSec=")) - Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) + Expect(session.OutputToString()).To(ContainSubstring("podman stop")) + Expect(session.OutputToString()).To(ContainSubstring("-t 5")) session = podmanTest.Podman([]string{"generate", "systemd", "--stop-timeout", "5", "--start-timeout", "123", "nginx"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStartSec=123")) Expect(session.OutputToString()).To(ContainSubstring("TimeoutStopSec=65")) - Expect(session.OutputToString()).To(ContainSubstring("podman stop -t 5")) + Expect(session.OutputToString()).To(ContainSubstring("-t 5")) }) It("podman generate systemd with user-defined dependencies", func() { @@ -228,7 +228,8 @@ var _ = Describe("Podman generate systemd", func() { Expect(output).To(ContainSubstring(" start foo-1")) Expect(output).To(ContainSubstring("-infra")) // infra container Expect(output).To(ContainSubstring("# container-foo-2.service")) - Expect(output).To(ContainSubstring(" stop -t 42 foo-2")) + Expect(output).To(ContainSubstring("podman stop")) + Expect(output).To(ContainSubstring("-t 42 foo-2")) Expect(output).To(ContainSubstring("BindsTo=pod-foo.service")) Expect(output).To(ContainSubstring("PIDFile=")) Expect(output).To(ContainSubstring("/userdata/conmon.pid")) @@ -539,7 +540,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd pod with containers --new", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -564,10 +565,21 @@ var _ = Describe("Podman generate systemd", func() { Expect(session.OutputToString()).To(ContainSubstring("# pod-foo.service")) Expect(session.OutputToString()).To(ContainSubstring("Wants=container-foo-1.service container-foo-2.service")) Expect(session.OutputToString()).To(ContainSubstring("BindsTo=pod-foo.service")) - Expect(session.OutputToString()).To(ContainSubstring("pod create --infra-conmon-pidfile %t/pod-foo.pid --pod-id-file %t/pod-foo.pod-id --exit-policy=stop --name foo")) - Expect(session.OutputToString()).To(ContainSubstring("ExecStartPre=/bin/rm -f %t/pod-foo.pid %t/pod-foo.pod-id")) - Expect(session.OutputToString()).To(ContainSubstring("pod stop --ignore --pod-id-file %t/pod-foo.pod-id -t 10")) - Expect(session.OutputToString()).To(ContainSubstring("pod rm --ignore -f --pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("pod create")) + Expect(session.OutputToString()).To(ContainSubstring("--infra-conmon-pidfile %t/pod-foo.pid")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("--exit-policy=stop")) + Expect(session.OutputToString()).To(ContainSubstring("--name foo")) + Expect(session.OutputToString()).To(ContainSubstring("ExecStartPre=/bin/rm")) + Expect(session.OutputToString()).To(ContainSubstring("-f %t/pod-foo.pid %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("pod stop")) + Expect(session.OutputToString()).To(ContainSubstring("--ignore")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) + Expect(session.OutputToString()).To(ContainSubstring("-t 10")) + Expect(session.OutputToString()).To(ContainSubstring("pod rm")) + Expect(session.OutputToString()).To(ContainSubstring("--ignore")) + Expect(session.OutputToString()).To(ContainSubstring("-f")) + Expect(session.OutputToString()).To(ContainSubstring("--pod-id-file %t/pod-foo.pod-id")) }) It("podman generate systemd --format json", func() { diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 969f83b19..a84fd6538 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "time" @@ -303,7 +302,7 @@ var _ = Describe("Podman healthcheck run", func() { containerfile := fmt.Sprintf(`FROM %s HEALTHCHECK CMD ls -l / 2>&1`, ALPINE) containerfilePath := filepath.Join(targetPath, "Containerfile") - err = ioutil.WriteFile(containerfilePath, []byte(containerfile), 0644) + err = os.WriteFile(containerfilePath, []byte(containerfile), 0644) Expect(err).To(BeNil()) defer func() { Expect(os.Chdir(cwd)).To(BeNil()) diff --git a/test/e2e/image_scp_test.go b/test/e2e/image_scp_test.go index 2c275d974..3ee2b74b5 100644 --- a/test/e2e/image_scp_test.go +++ b/test/e2e/image_scp_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" @@ -25,7 +24,7 @@ var _ = Describe("podman image scp", func() { BeforeEach(func() { ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") - conf, err := ioutil.TempFile("", "containersconf") + conf, err := os.CreateTemp("", "containersconf") Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conf.Name()) diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go index 9d31deb55..ab4f607a0 100644 --- a/test/e2e/info_test.go +++ b/test/e2e/info_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "os/user" @@ -104,7 +103,7 @@ var _ = Describe("Podman Info", func() { driver := `"overlay"` storageOpt := `"/usr/bin/fuse-overlayfs"` storageConf := []byte(fmt.Sprintf("[storage]\ndriver=%s\nrootless_storage_path=%s\n[storage.options]\nmount_program=%s", driver, rootlessStoragePath, storageOpt)) - err = ioutil.WriteFile(configPath, storageConf, os.ModePerm) + err = os.WriteFile(configPath, storageConf, os.ModePerm) Expect(err).To(BeNil()) u, err := user.Current() diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go index 9b33e2f0d..30c82c45d 100644 --- a/test/e2e/kill_test.go +++ b/test/e2e/kill_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -150,7 +149,7 @@ var _ = Describe("Podman kill", func() { }) It("podman kill --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" defer os.RemoveAll(tmpDir) @@ -170,12 +169,12 @@ var _ = Describe("Podman kill", func() { }) It("podman kill multiple --cidfile", func() { - tmpDir1, err := ioutil.TempDir("", "") + tmpDir1, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir1 + "cid" defer os.RemoveAll(tmpDir1) - tmpDir2, err := ioutil.TempDir("", "") + tmpDir2, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile2 := tmpDir2 + "cid" defer os.RemoveAll(tmpDir2) diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go index 86be17eb3..499373e65 100644 --- a/test/e2e/libpod_suite_remote_test.go +++ b/test/e2e/libpod_suite_remote_test.go @@ -6,7 +6,6 @@ package integration import ( "errors" "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -58,7 +57,7 @@ func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() { func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) { outfile := filepath.Join(p.TempDir, "registries.conf") os.Setenv("CONTAINERS_REGISTRIES_CONF", outfile) - err := ioutil.WriteFile(outfile, b, 0644) + err := os.WriteFile(outfile, b, 0644) Expect(err).ToNot(HaveOccurred()) } diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index ecb7a2278..b797fbb89 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -48,7 +47,7 @@ func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() { func (p *PodmanTestIntegration) setRegistriesConfigEnv(b []byte) { outfile := filepath.Join(p.TempDir, "registries.conf") os.Setenv("CONTAINERS_REGISTRIES_CONF", outfile) - err := ioutil.WriteFile(outfile, b, 0644) + err := os.WriteFile(outfile, b, 0644) Expect(err).ToNot(HaveOccurred()) } diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go index 60c53e27e..5951c1a3e 100644 --- a/test/e2e/login_logout_test.go +++ b/test/e2e/login_logout_test.go @@ -3,7 +3,6 @@ package integration import ( "encoding/json" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" @@ -101,7 +100,7 @@ var _ = Describe("Podman login and logout", func() { }) readAuthInfo := func(filePath string) map[string]interface{} { - authBytes, err := ioutil.ReadFile(filePath) + authBytes, err := os.ReadFile(filePath) Expect(err).To(BeNil()) var authInfo map[string]interface{} @@ -137,12 +136,12 @@ var _ = Describe("Podman login and logout", func() { }) It("podman login and logout without registry parameter", func() { - registriesConf, err := ioutil.TempFile("", "TestLoginWithoutParameter") + registriesConf, err := os.CreateTemp("", "TestLoginWithoutParameter") Expect(err).To(BeNil()) defer registriesConf.Close() defer os.Remove(registriesConf.Name()) - err = ioutil.WriteFile(registriesConf.Name(), registriesConfWithSearch, os.ModePerm) + err = os.WriteFile(registriesConf.Name(), registriesConfWithSearch, os.ModePerm) Expect(err).To(BeNil()) // Environment is per-process, so this looks very unsafe; actually it seems fine because tests are not @@ -448,7 +447,7 @@ var _ = Describe("Podman login and logout", func() { It("podman login and logout with repository push with invalid auth.json credentials", func() { authFile := filepath.Join(podmanTest.TempDir, "auth.json") // only `server` contains the correct login data - err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + err := os.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { "%s/podmantest": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } }}`, server, server)), 0644) @@ -494,7 +493,7 @@ var _ = Describe("Podman login and logout", func() { Expect(session).Should(Exit(0)) // only `server + /podmantest` and `server` have the correct login data - err := ioutil.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { + err := os.WriteFile(authFile, []byte(fmt.Sprintf(`{"auths": { "%s/podmantest/test-alpine": { "auth": "cG9kbWFudGVzdDp3cm9uZw==" }, "%s/podmantest": { "auth": "cG9kbWFudGVzdDp0ZXN0" }, "%s": { "auth": "cG9kbWFudGVzdDp0ZXN0" } diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index e38499257..b0a5e7d03 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "path/filepath" "strings" @@ -338,7 +337,7 @@ var _ = Describe("Podman manifest", func() { for _, f := range blobs { blobPath := filepath.Join(blobsDir, f.Name()) - sourceFile, err := ioutil.ReadFile(blobPath) + sourceFile, err := os.ReadFile(blobPath) Expect(err).To(BeNil()) compressionType := archive.DetectCompression(sourceFile) diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 363df2624..6500fc0e0 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -31,7 +30,7 @@ var _ = Describe("Podman pause", func() { } if CGROUPSV2 { - b, err := ioutil.ReadFile("/proc/self/cgroup") + b, err := os.ReadFile("/proc/self/cgroup") if err != nil { Skip("cannot read self cgroup") } @@ -336,7 +335,7 @@ var _ = Describe("Podman pause", func() { }) It("podman pause --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -365,7 +364,7 @@ var _ = Describe("Podman pause", func() { }) It("podman pause multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 26460c937..67c88953a 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "net" "net/url" "os" @@ -767,7 +766,7 @@ func generateMultiDocKubeYaml(kubeObjects []string, pathname string) error { func createSecret(podmanTest *PodmanTestIntegration, name string, value []byte) { //nolint:unparam secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, value, 0755) + err := os.WriteFile(secretFilePath, value, 0755) Expect(err).To(BeNil()) secret := podmanTest.Podman([]string{"secret", "create", name, secretFilePath}) @@ -1442,7 +1441,7 @@ var _ = Describe("Podman play kube", func() { conffile := filepath.Join(podmanTest.TempDir, "container.conf") infraImage := "k8s.gcr.io/pause:3.2" - err := ioutil.WriteFile(conffile, []byte(fmt.Sprintf("[engine]\ninfra_image=\"%s\"\n", infraImage)), 0644) + err := os.WriteFile(conffile, []byte(fmt.Sprintf("[engine]\ninfra_image=\"%s\"\n", infraImage)), 0644) Expect(err).To(BeNil()) os.Setenv("CONTAINERS_CONF", conffile) @@ -2370,7 +2369,7 @@ spec: tempdir, err = CreateTempDirInTempDir() Expect(err).To(BeNil()) - err := ioutil.WriteFile(conffile, []byte(testyaml), 0755) + err := os.WriteFile(conffile, []byte(testyaml), 0755) Expect(err).To(BeNil()) kube := podmanTest.Podman([]string{"play", "kube", conffile}) @@ -3800,7 +3799,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -3808,7 +3807,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q Skip("cannot find mappings for the current user") } - initialUsernsConfig, err := ioutil.ReadFile("/proc/self/uid_map") + initialUsernsConfig, err := os.ReadFile("/proc/self/uid_map") Expect(err).To(BeNil()) if os.Geteuid() != 0 { unshare := podmanTest.Podman([]string{"unshare", "cat", "/proc/self/uid_map"}) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index 24d9d6854..d694efe5f 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/user" "path/filepath" @@ -332,7 +331,7 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - id, _ := ioutil.ReadFile(targetFile) + id, _ := os.ReadFile(targetFile) check := podmanTest.Podman([]string{"pod", "inspect", "abc"}) check.WaitWithDefaultTimeout() data := check.InspectPodToJSON() @@ -707,7 +706,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -742,7 +741,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -778,7 +777,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -815,7 +814,7 @@ ENTRYPOINT ["sleep","99999"] name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/pod_rm_test.go b/test/e2e/pod_rm_test.go index 364ef54d5..d9f319798 100644 --- a/test/e2e/pod_rm_test.go +++ b/test/e2e/pod_rm_test.go @@ -3,7 +3,6 @@ package integration import ( "fmt" "io/fs" - "io/ioutil" "os" "path/filepath" "strings" @@ -235,7 +234,7 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod start/remove single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -264,7 +263,7 @@ var _ = Describe("Podman pod rm", func() { }) It("podman pod start/remove multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/pod_start_test.go b/test/e2e/pod_start_test.go index 084a48636..a89613732 100644 --- a/test/e2e/pod_start_test.go +++ b/test/e2e/pod_start_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -175,7 +174,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod start single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -199,7 +198,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod start multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) @@ -231,7 +230,7 @@ var _ = Describe("Podman pod start", func() { }) It("podman pod create --infra-conmon-pod create + start", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -248,7 +247,7 @@ var _ = Describe("Podman pod start", func() { Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) // infra readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/pod_stop_test.go b/test/e2e/pod_stop_test.go index 2fe0aa486..b8a9fabc7 100644 --- a/test/e2e/pod_stop_test.go +++ b/test/e2e/pod_stop_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -181,7 +180,7 @@ var _ = Describe("Podman pod stop", func() { }) It("podman pod start/stop single pod via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "podID" defer os.RemoveAll(tmpDir) @@ -210,7 +209,7 @@ var _ = Describe("Podman pod stop", func() { }) It("podman pod start/stop multiple pods via --pod-id-file", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) defer os.RemoveAll(tmpDir) diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index a73b7c87b..5af47678f 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "path/filepath" @@ -84,7 +83,7 @@ var _ = Describe("Podman push", func() { for _, f := range blobs { blobPath := filepath.Join(blobsDir, f.Name()) - sourceFile, err := ioutil.ReadFile(blobPath) + sourceFile, err := os.ReadFile(blobPath) Expect(err).To(BeNil()) compressionType := archive.DetectCompression(sourceFile) diff --git a/test/e2e/restart_test.go b/test/e2e/restart_test.go index 9df884292..87d20a2e6 100644 --- a/test/e2e/restart_test.go +++ b/test/e2e/restart_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "time" @@ -251,7 +250,7 @@ var _ = Describe("Podman restart", func() { }) It("podman restart --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -274,7 +273,7 @@ var _ = Describe("Podman restart", func() { }) It("podman restart multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go index e76451824..e931c4419 100644 --- a/test/e2e/rm_test.go +++ b/test/e2e/rm_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -145,7 +144,7 @@ var _ = Describe("Podman rm", func() { }) It("podman rm --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -166,7 +165,7 @@ var _ = Describe("Podman rm", func() { }) It("podman rm multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go index 18d011e6d..f486054c3 100644 --- a/test/e2e/run_apparmor_test.go +++ b/test/e2e/run_apparmor_test.go @@ -5,7 +5,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -104,7 +103,7 @@ profile aa-test-profile flags=(attach_disconnected,mediate_deleted) { } ` aaFile := filepath.Join(os.TempDir(), "aaFile") - Expect(ioutil.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil()) + Expect(os.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil()) parse := SystemExec("apparmor_parser", []string{"-Kr", aaFile}) Expect(parse).Should(Exit(0)) diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index 24cae43b1..ba3ca922e 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -86,12 +85,12 @@ var _ = Describe("Podman run with --cgroup-parent", func() { containerCgroup := strings.TrimRight(strings.ReplaceAll(exec.OutputToString(), "0::", ""), "\n") // Move the container process to a sub cgroup - content, err := ioutil.ReadFile(filepath.Join(cgroupRoot, containerCgroup, "cgroup.procs")) + content, err := os.ReadFile(filepath.Join(cgroupRoot, containerCgroup, "cgroup.procs")) Expect(err).To(BeNil()) oldSubCgroupPath := filepath.Join(cgroupRoot, containerCgroup, "old-container") err = os.MkdirAll(oldSubCgroupPath, 0755) Expect(err).To(BeNil()) - err = ioutil.WriteFile(filepath.Join(oldSubCgroupPath, "cgroup.procs"), content, 0644) + err = os.WriteFile(filepath.Join(oldSubCgroupPath, "cgroup.procs"), content, 0644) Expect(err).To(BeNil()) newCgroup := fmt.Sprintf("%s/new-container", containerCgroup) diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go index 19bb735ff..bdac998cf 100644 --- a/test/e2e/run_cpu_test.go +++ b/test/e2e/run_cpu_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" . "github.com/containers/podman/v4/test/utils" @@ -26,7 +25,7 @@ var _ = Describe("Podman run cpu", func() { } if CGROUPSV2 { - if err := ioutil.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0644); err != nil { + if err := os.WriteFile("/sys/fs/cgroup/cgroup.subtree_control", []byte("+cpuset"), 0644); err != nil { Skip("cpuset controller not available on the current kernel") } } diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 3fbdd4339..fb02cb410 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -638,7 +637,7 @@ USER bin`, BB) Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Equal("111")) - currentOOMScoreAdj, err := ioutil.ReadFile("/proc/self/oom_score_adj") + currentOOMScoreAdj, err := os.ReadFile("/proc/self/oom_score_adj") Expect(err).To(BeNil()) session = podmanTest.Podman([]string{"run", "--rm", fedoraMinimal, "cat", "/proc/self/oom_score_adj"}) session.WaitWithDefaultTimeout() @@ -845,7 +844,7 @@ USER bin`, BB) "stage" : [ "prestart" ] } `, hookScriptPath) - err = ioutil.WriteFile(hookJSONPath, []byte(hookJSON), 0644) + err = os.WriteFile(hookJSONPath, []byte(hookJSON), 0644) Expect(err).ToNot(HaveOccurred()) random := stringid.GenerateRandomID() @@ -853,14 +852,14 @@ USER bin`, BB) hookScript := fmt.Sprintf(`#!/bin/sh echo -n %s >%s `, random, targetFile) - err = ioutil.WriteFile(hookScriptPath, []byte(hookScript), 0755) + err = os.WriteFile(hookScriptPath, []byte(hookScript), 0755) Expect(err).ToNot(HaveOccurred()) session := podmanTest.Podman([]string{"--hooks-dir", hooksDir, "run", ALPINE, "ls"}) session.Wait(10) Expect(session).Should(Exit(0)) - b, err := ioutil.ReadFile(targetFile) + b, err := os.ReadFile(targetFile) Expect(err).ToNot(HaveOccurred()) Expect(string(b)).To(Equal(random)) }) @@ -877,19 +876,19 @@ echo -n %s >%s mountsFile := filepath.Join(containersDir, "mounts.conf") mountString := secretsDir + ":/run/secrets" - err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755) + err = os.WriteFile(mountsFile, []byte(mountString), 0755) Expect(err).To(BeNil()) secretsFile := filepath.Join(secretsDir, "test.txt") secretsString := "Testing secrets mount. I am mounted!" - err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755) + err = os.WriteFile(secretsFile, []byte(secretsString), 0755) Expect(err).To(BeNil()) targetDir := tempdir + "/symlink/target" err = os.MkdirAll(targetDir, 0755) Expect(err).To(BeNil()) keyFile := filepath.Join(targetDir, "key.pem") - err = ioutil.WriteFile(keyFile, []byte(mountString), 0755) + err = os.WriteFile(keyFile, []byte(mountString), 0755) Expect(err).To(BeNil()) execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")}) Expect(execSession).Should(Exit(0)) @@ -908,7 +907,7 @@ echo -n %s >%s It("podman run with FIPS mode secrets", func() { SkipIfRootless("rootless can not manipulate system-fips file") fipsFile := "/etc/system-fips" - err = ioutil.WriteFile(fipsFile, []byte{}, 0755) + err = os.WriteFile(fipsFile, []byte{}, 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"}) @@ -1070,7 +1069,7 @@ USER mail`, BB) filename := "test.txt" volFile := filepath.Join(vol, filename) data := "Testing --volumes-from!!!" - err = ioutil.WriteFile(volFile, []byte(data), 0755) + err = os.WriteFile(volFile, []byte(data), 0755) Expect(err).To(BeNil()) mountpoint := "/myvol/" @@ -1102,7 +1101,7 @@ USER mail`, BB) filename := "test.txt" volFile := filepath.Join(vol, filename) data := "Testing --volumes-from!!!" - err = ioutil.WriteFile(volFile, []byte(data), 0755) + err = os.WriteFile(volFile, []byte(data), 0755) Expect(err).To(BeNil()) mountpoint := "/myvol/" @@ -1469,7 +1468,7 @@ USER mail`, BB) return strings.TrimSuffix(i, "\n") } - curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") + curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup") Expect(err).ShouldNot(HaveOccurred()) curCgroups := trim(string(curCgroupsBytes)) fmt.Printf("Output:\n%s\n", curCgroups) @@ -1492,7 +1491,7 @@ USER mail`, BB) Skip("Test only works on crun") } - curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") + curCgroupsBytes, err := os.ReadFile("/proc/self/cgroup") Expect(err).To(BeNil()) var curCgroups string = string(curCgroupsBytes) fmt.Printf("Output:\n%s\n", curCgroups) @@ -1509,7 +1508,7 @@ USER mail`, BB) pid := inspectOut[0].State.Pid Expect(pid).To(Not(Equal(0))) - ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) + ctrCgroupsBytes, err := os.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) Expect(err).To(BeNil()) var ctrCgroups string = string(ctrCgroupsBytes) fmt.Printf("Output\n:%s\n", ctrCgroups) @@ -1740,7 +1739,7 @@ WORKDIR /madethis`, BB) It("podman run --secret", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1762,7 +1761,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1784,7 +1783,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount with target", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath}) @@ -1806,7 +1805,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=mount with target at /tmp", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath}) @@ -1828,7 +1827,7 @@ WORKDIR /madethis`, BB) It("podman run --secret source=mysecret,type=env", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1844,7 +1843,7 @@ WORKDIR /madethis`, BB) It("podman run --secret target option", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1860,7 +1859,7 @@ WORKDIR /madethis`, BB) It("podman run --secret mount with uid, gid, mode options", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1887,7 +1886,7 @@ WORKDIR /madethis`, BB) It("podman run --secret with --user", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1903,7 +1902,7 @@ WORKDIR /madethis`, BB) It("podman run invalid secret option", func() { secretsString := "somesecretdata" secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) + err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) @@ -1968,7 +1967,7 @@ WORKDIR /madethis`, BB) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go index 016f67bf6..c485f1522 100644 --- a/test/e2e/run_userns_test.go +++ b/test/e2e/run_userns_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/user" "strings" @@ -55,7 +54,7 @@ var _ = Describe("Podman UserNS support", func() { if name == "root" { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -181,7 +180,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -213,7 +212,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -251,7 +250,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -280,7 +279,7 @@ var _ = Describe("Podman UserNS support", func() { name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index aa8f49176..d65be97a4 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "os/exec" "os/user" @@ -768,7 +767,7 @@ VOLUME /test/`, ALPINE) name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } @@ -815,7 +814,7 @@ VOLUME /test/`, ALPINE) name = "containers" } - content, err := ioutil.ReadFile("/etc/subuid") + content, err := os.ReadFile("/etc/subuid") if err != nil { Skip("cannot read /etc/subuid") } diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index afb723a63..db353c036 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -1,7 +1,6 @@ package integration import ( - "io/ioutil" "os" "os/exec" "path/filepath" @@ -46,6 +45,15 @@ var _ = Describe("Podman save", func() { Expect(save).Should(Exit(0)) }) + It("podman save signature-policy flag", func() { + SkipIfRemote("--signature-policy N/A for remote") + outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") + + save := podmanTest.Podman([]string{"save", "--signature-policy", "/etc/containers/policy.json", "-o", outfile, ALPINE}) + save.WaitWithDefaultTimeout() + Expect(save).Should(Exit(0)) + }) + It("podman save oci flag", func() { outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") @@ -185,7 +193,7 @@ default-docker: sigstore: file:///var/lib/containers/sigstore sigstore-staging: file:///var/lib/containers/sigstore ` - Expect(ioutil.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) + Expect(os.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index f8b1bc836..77cb72056 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "os" "strconv" "text/template" @@ -288,7 +287,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry4.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { podmanTest.RestartRemoteService() @@ -332,7 +331,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry5.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) search := podmanTest.Podman([]string{"search", image, "--tls-verify=true"}) @@ -372,7 +371,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileBadTmpl.Execute(&buffer, ep) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry6.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { @@ -428,7 +427,7 @@ registries = ['{{.Host}}:{{.Port}}']` err = registryFileTwoTmpl.Execute(&buffer, ep3) Expect(err).ToNot(HaveOccurred()) podmanTest.setRegistriesConfigEnv(buffer.Bytes()) - err = ioutil.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("%s/registry8.conf", tempdir), buffer.Bytes(), 0644) Expect(err).ToNot(HaveOccurred()) if IsRemote() { diff --git a/test/e2e/secret_test.go b/test/e2e/secret_test.go index 902f422bd..286815e67 100644 --- a/test/e2e/secret_test.go +++ b/test/e2e/secret_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -37,7 +36,7 @@ var _ = Describe("Podman secret", func() { It("podman secret create", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "-d", "file", "--driver-opts", "opt1=val", "a", secretFilePath}) @@ -57,7 +56,7 @@ var _ = Describe("Podman secret", func() { It("podman secret create bad name should fail", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "?!", secretFilePath}) @@ -67,7 +66,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -83,7 +82,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect with --format", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -99,7 +98,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect multiple secrets", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -120,7 +119,7 @@ var _ = Describe("Podman secret", func() { It("podman secret inspect bogus", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) inspect := podmanTest.Podman([]string{"secret", "inspect", "bogus"}) @@ -131,7 +130,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -147,7 +146,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls --quiet", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) secretName := "a" @@ -177,7 +176,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls with filters", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) secret1 := "Secret1" @@ -231,7 +230,7 @@ var _ = Describe("Podman secret", func() { It("podman secret ls with Go template", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -247,7 +246,7 @@ var _ = Describe("Podman secret", func() { It("podman secret rm", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -268,7 +267,7 @@ var _ = Describe("Podman secret", func() { It("podman secret rm --all", func() { secretFilePath := filepath.Join(podmanTest.TempDir, "secret") - err := ioutil.WriteFile(secretFilePath, []byte("mysecret"), 0755) + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"secret", "create", "a", secretFilePath}) @@ -310,4 +309,41 @@ var _ = Describe("Podman secret", func() { Expect(inspect.OutputToString()).To(Equal(secrID)) }) + It("podman secret with labels", func() { + secretFilePath := filepath.Join(podmanTest.TempDir, "secret") + err := os.WriteFile(secretFilePath, []byte("mysecret"), 0755) + Expect(err).To(BeNil()) + + session := podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "a", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID := session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect := podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar")) + + session = podmanTest.Podman([]string{"secret", "create", "--label", "foo=bar", "--label", "a:b", "b", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID = session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(ContainSubstring("foo:bar")) + Expect(inspect.OutputToString()).To(ContainSubstring("a:b")) + + session = podmanTest.Podman([]string{"secret", "create", "c", secretFilePath}) + session.WaitWithDefaultTimeout() + secrID = session.OutputToString() + Expect(session).Should(Exit(0)) + + inspect = podmanTest.Podman([]string{"secret", "inspect", "--format", "{{.Spec.Labels}}", secrID}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).Should(Exit(0)) + Expect(inspect.OutputToString()).To(Equal("map[]")) + + }) }) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index f3e8cc015..db6f87ac0 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -204,7 +203,7 @@ var _ = Describe("Podman start", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) readFirstLine := func(path string) string { - content, err := ioutil.ReadFile(path) + content, err := os.ReadFile(path) Expect(err).To(BeNil()) return strings.Split(string(content), "\n")[0] } diff --git a/test/e2e/stop_test.go b/test/e2e/stop_test.go index 23abb6d92..6f7a67139 100644 --- a/test/e2e/stop_test.go +++ b/test/e2e/stop_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "strings" @@ -276,7 +275,7 @@ var _ = Describe("Podman stop", func() { It("podman stop --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile := tmpDir + "cid" @@ -300,7 +299,7 @@ var _ = Describe("Podman stop", func() { It("podman stop multiple --cidfile", func() { - tmpDir, err := ioutil.TempDir("", "") + tmpDir, err := os.MkdirTemp("", "") Expect(err).To(BeNil()) tmpFile1 := tmpDir + "cid-1" tmpFile2 := tmpDir + "cid-2" diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go index baa31424b..31cbfe349 100644 --- a/test/e2e/system_connection_test.go +++ b/test/e2e/system_connection_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "net/url" "os" "os/exec" @@ -27,7 +26,7 @@ var _ = Describe("podman system connection", func() { BeforeEach(func() { ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") - conf, err := ioutil.TempFile("", "containersconf") + conf, err := os.CreateTemp("", "containersconf") Expect(err).ToNot(HaveOccurred()) os.Setenv("CONTAINERS_CONF", conf.Name()) diff --git a/test/e2e/system_service_test.go b/test/e2e/system_service_test.go index 398290426..adb3cade6 100644 --- a/test/e2e/system_service_test.go +++ b/test/e2e/system_service_test.go @@ -1,7 +1,7 @@ package integration import ( - "io/ioutil" + "io" "net" "net/http" "net/url" @@ -89,7 +89,7 @@ var _ = Describe("podman system service", func() { defer resp.Body.Close() Expect(resp).To(HaveHTTPStatus(http.StatusOK)) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) Expect(err).ShouldNot(HaveOccurred()) Expect(body).ShouldNot(BeEmpty()) diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index 7b3552cc2..7b79a724d 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -2,7 +2,6 @@ package integration import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -51,7 +50,7 @@ WantedBy=default.target SkipIfRootless("rootless can not write to /etc") SkipIfContainerized("test does not have systemd as pid 1") - sysFile := ioutil.WriteFile("/etc/systemd/system/redis.service", []byte(systemdUnitFile), 0644) + sysFile := os.WriteFile("/etc/systemd/system/redis.service", []byte(systemdUnitFile), 0644) Expect(sysFile).To(BeNil()) defer func() { stop := SystemExec("bash", []string{"-c", "systemctl stop redis"}) @@ -137,7 +136,7 @@ RUN mkdir -p /usr/lib/systemd/; touch /usr/lib/systemd/systemd CMD /usr/lib/systemd/systemd`, ALPINE) containerfilePath := filepath.Join(podmanTest.TempDir, "Containerfile") - err := ioutil.WriteFile(containerfilePath, []byte(containerfile), 0755) + err := os.WriteFile(containerfilePath, []byte(containerfile), 0755) Expect(err).To(BeNil()) session := podmanTest.Podman([]string{"build", "-t", "systemd", "--file", containerfilePath, podmanTest.TempDir}) session.WaitWithDefaultTimeout() @@ -167,7 +166,7 @@ CMD /usr/lib/systemd/systemd`, ALPINE) Expect(session).Should(Exit(0)) pidFile := strings.TrimSuffix(session.OutputToString(), "\n") - _, err := ioutil.ReadFile(pidFile) + _, err := os.ReadFile(pidFile) Expect(err).To(BeNil()) }) diff --git a/test/e2e/trust_test.go b/test/e2e/trust_test.go index eee802e43..78b4f1b23 100644 --- a/test/e2e/trust_test.go +++ b/test/e2e/trust_test.go @@ -2,7 +2,6 @@ package integration import ( "encoding/json" - "io/ioutil" "os" "path/filepath" @@ -57,7 +56,7 @@ var _ = Describe("Podman trust", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) var teststruct map[string][]map[string]string - policyContent, err := ioutil.ReadFile(policyJSON) + policyContent, err := os.ReadFile(policyJSON) if err != nil { os.Exit(1) } @@ -111,7 +110,7 @@ var _ = Describe("Podman trust", func() { session := podmanTest.Podman([]string{"image", "trust", "show", "--policypath", filepath.Join(INTEGRATION_ROOT, "test/policy.json"), "--raw"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - contents, err := ioutil.ReadFile(filepath.Join(INTEGRATION_ROOT, "test/policy.json")) + contents, err := os.ReadFile(filepath.Join(INTEGRATION_ROOT, "test/policy.json")) Expect(err).ShouldNot(HaveOccurred()) Expect(session.OutputToString()).To(BeValidJSON()) Expect(string(session.Out.Contents())).To(Equal(string(contents) + "\n")) diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index 378edc013..ba6bde4df 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -56,14 +56,17 @@ function setup() { @test "podman --context emits reasonable output" { + if ! is_remote; then + skip "only applicable on podman-remote" + fi # All we care about here is that the command passes run_podman --context=default version # This one must fail run_podman 125 --context=swarm version is "$output" \ - "Error: podman does not support swarm, the only --context value allowed is \"default\"" \ - "--context=default or fail" + "Error: failed to resolve active destination: \"swarm\" service destination not found" \ + "--context=swarm should fail" } @test "podman can pull an image" { diff --git a/test/system/030-run.bats b/test/system/030-run.bats index b1ce91d14..65a1150a3 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -3,7 +3,6 @@ load helpers @test "podman run - basic tests" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" rand=$(random_string 30) err_no_such_cmd="Error:.*/no/such/command.*[Nn]o such file or directory" @@ -892,4 +891,32 @@ $IMAGE--c_ok" \ run_podman container rm -f -t 0 c_ok c_fail_no_rm } +@test "podman run --attach stdin prints container ID" { + ctr_name="container-$(random_string 5)" + run_podman run --name $ctr_name --attach stdin $IMAGE echo hello + run_output=$output + run_podman inspect --format "{{.Id}}" $ctr_name + ctr_id=$output + is "$run_output" "$ctr_id" "Did not find container ID in the output" + run_podman rm $ctr_name +} + +@test "podman run --privileged as root with systemd will not mount /dev/tty" { + skip_if_rootless "this test only makes sense as root" + + ctr_name="container-$(random_string 5)" + run_podman run --rm -d --privileged --systemd=always --name "$ctr_name" "$IMAGE" /home/podman/pause + + TTYs=$(ls /dev/tty*|sed '/^\/dev\/tty$/d') + + if [[ $TTYs = "" ]]; then + die "Did not find any /dev/ttyN devices on local host" + else + run_podman exec "$ctr_name" ls /dev/ + assert "$(grep tty <<<$output)" = "tty" "There must be no /dev/ttyN devices in the container" + fi + + run_podman stop "$ctr_name" +} + # vim: filetype=sh diff --git a/test/system/032-sig-proxy.bats b/test/system/032-sig-proxy.bats new file mode 100644 index 000000000..686df0e1b --- /dev/null +++ b/test/system/032-sig-proxy.bats @@ -0,0 +1,43 @@ +#!/usr/bin/env bats + +load helpers + +@test "podman sigkill" { + $PODMAN run -i --name foo $IMAGE sh -c 'trap "echo BYE;exit 0" INT;echo READY;while :;do sleep 0.1;done' & + local kidpid=$! + + # Wait for container to appear + local timeout=5 + while :;do + sleep 0.5 + run_podman '?' container exists foo + if [[ $status -eq 0 ]]; then + break + fi + timeout=$((timeout - 1)) + if [[ $timeout -eq 0 ]]; then + die "Timed out waiting for container to start" + fi + done + + wait_for_ready foo + + # Signal, and wait for container to exit + kill -INT $kidpid + local timeout=5 + while :;do + sleep 0.5 + run_podman logs foo + if [[ "$output" =~ BYE ]]; then + break + fi + timeout=$((timeout - 1)) + if [[ $timeout -eq 0 ]]; then + die "Timed out waiting for BYE from container" + fi + done + + run_podman rm -f -t0 foo +} + +# vim: filetype=sh diff --git a/test/system/075-exec.bats b/test/system/075-exec.bats index 7dd43c2c3..0a6048b7e 100644 --- a/test/system/075-exec.bats +++ b/test/system/075-exec.bats @@ -6,8 +6,6 @@ load helpers @test "podman exec - basic test" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" - rand_filename=$(random_string 20) rand_content=$(random_string 50) diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index 6c3ef7f3f..c4724d605 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -142,7 +142,6 @@ READY=1" "sdnotify sent MAINPID and READY" # These tests can fail in dev. environment because of SELinux. # quick fix: chcon -t container_runtime_exec_t ./bin/podman @test "sdnotify : container" { - skip_if_aarch64 "FIXME: #15277 sdnotify doesn't work on aarch64" # Sigh... we need to pull a humongous image because it has systemd-notify. # (IMPORTANT: fedora:32 and above silently removed systemd-notify; this # caused CI to hang. That's why we explicitly require fedora:31) @@ -248,8 +247,6 @@ READY=1" "sdnotify sent MAINPID and READY" } @test "sdnotify : play kube - with policies" { - skip_if_aarch64 "FIXME: #15277 sdnotify doesn't work on aarch64" - # Sigh... we need to pull a humongous image because it has systemd-notify. # (IMPORTANT: fedora:32 and above silently removed systemd-notify; this # caused CI to hang. That's why we explicitly require fedora:31) diff --git a/test/system/272-system-connection.bats b/test/system/272-system-connection.bats index e937a7273..402e69736 100644 --- a/test/system/272-system-connection.bats +++ b/test/system/272-system-connection.bats @@ -56,8 +56,22 @@ function _run_podman_remote() { c1="c1_$(random_string 15)" c2="c2_$(random_string 15)" - run_podman system connection add $c1 tcp://localhost:12345 - run_podman system connection add --default $c2 tcp://localhost:54321 + run_podman system connection add $c1 tcp://localhost:12345 + run_podman context create --docker "host=tcp://localhost:54321" $c2 + run_podman system connection ls + is "$output" \ + ".*$c1[ ]\+tcp://localhost:12345[ ]\+true +$c2[ ]\+tcp://localhost:54321[ ]\+false" \ + "system connection ls" + run_podman system connection ls -q + is "$(echo $(sort <<<$output))" \ + "$c1 $c2" \ + "system connection ls -q should show two names" + run_podman context ls -q + is "$(echo $(sort <<<$output))" \ + "$c1 $c2" \ + "context ls -q should show two names" + run_podman context use $c2 run_podman system connection ls is "$output" \ ".*$c1[ ]\+tcp://localhost:12345[ ]\+false @@ -66,11 +80,11 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true" \ # Remove default connection; the remaining one should still not be default run_podman system connection rm $c2 - run_podman system connection ls + run_podman context ls is "$output" ".*$c1[ ]\+tcp://localhost:12345[ ]\+false" \ "system connection ls (after removing default connection)" - run_podman system connection rm $c1 + run_podman context rm $c1 } # Test tcp socket; requires starting a local server diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index cc86f282a..52c428884 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -39,12 +39,10 @@ function check_label() { } @test "podman selinux: container with label=disable" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" check_label "--security-opt label=disable" "spc_t" } @test "podman selinux: privileged container" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" check_label "--privileged --userns=host" "spc_t" } @@ -65,7 +63,6 @@ function check_label() { } @test "podman selinux: pid=host" { - skip_if_aarch64 "FIXME: #15074 - fails on aarch64" # FIXME this test fails when run rootless with runc: # Error: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: readonly path /proc/asound: operation not permitted: OCI permission denied if is_rootless; then diff --git a/test/testvol/main.go b/test/testvol/main.go index ab26e2df0..cbbf7e4b0 100644 --- a/test/testvol/main.go +++ b/test/testvol/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "sync" @@ -78,7 +77,7 @@ func startServer(socketPath string) error { logrus.Debugf("Starting server...") if config.path == "" { - path, err := ioutil.TempDir("", "test_volume_plugin") + path, err := os.MkdirTemp("", "test_volume_plugin") if err != nil { return fmt.Errorf("getting directory for plugin: %w", err) } diff --git a/test/utils/common_function_test.go b/test/utils/common_function_test.go index 7092e40a1..724b2deb2 100644 --- a/test/utils/common_function_test.go +++ b/test/utils/common_function_test.go @@ -3,7 +3,7 @@ package utils_test import ( "encoding/json" "fmt" - "io/ioutil" + "io" "os" "reflect" "strings" @@ -113,7 +113,7 @@ var _ = Describe("Common functions test", func() { Expect(err).To(BeNil(), "Can not find the JSON file after we write it.") defer read.Close() - bytes, err := ioutil.ReadAll(read) + bytes, err := io.ReadAll(read) Expect(err).ToNot(HaveOccurred()) err = json.Unmarshal(bytes, compareData) Expect(err).ToNot(HaveOccurred()) diff --git a/test/utils/utils.go b/test/utils/utils.go index 19b287ae1..19b67dfa7 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -4,7 +4,6 @@ import ( "bufio" "encoding/json" "fmt" - "io/ioutil" "math/rand" "os" "os/exec" @@ -100,7 +99,7 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string } if timeDir := os.Getenv(EnvTimeDir); timeDir != "" { - timeFile, err := ioutil.TempFile(timeDir, ".time") + timeFile, err := os.CreateTemp(timeDir, ".time") if err != nil { Fail(fmt.Sprintf("Error creating time file: %v", err)) } @@ -374,7 +373,7 @@ func (s *PodmanSession) WaitWithTimeout(timeout int) { // CreateTempDirInTempDir create a temp dir with prefix podman_test func CreateTempDirInTempDir() (string, error) { - return ioutil.TempDir("", "podman_test") + return os.MkdirTemp("", "podman_test") } // SystemExec is used to exec a system command to check its exit code or output @@ -497,7 +496,7 @@ func WriteJSONFile(data []byte, filePath string) error { if err != nil { return err } - return ioutil.WriteFile(filePath, formatJSON, 0644) + return os.WriteFile(filePath, formatJSON, 0644) } // Containerized check the podman command run inside container @@ -506,7 +505,7 @@ func Containerized() bool { if container != "" { return true } - b, err := ioutil.ReadFile(ProcessOneCgroupPath) + b, err := os.ReadFile(ProcessOneCgroupPath) if err != nil { // shrug, if we cannot read that file, return false return false diff --git a/utils/utils.go b/utils/utils.go index 4d41ce5f8..5fb3695ce 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "fmt" "io" - "io/ioutil" "os" "os/exec" "strconv" @@ -114,7 +113,7 @@ var ( // RunsOnSystemd returns whether the system is using systemd func RunsOnSystemd() bool { runsOnSystemdOnce.Do(func() { - initCommand, err := ioutil.ReadFile("/proc/1/comm") + initCommand, err := os.ReadFile("/proc/1/comm") // On errors, default to systemd runsOnSystemd = err != nil || strings.TrimRight(string(initCommand), "\n") == "systemd" }) @@ -122,7 +121,7 @@ func RunsOnSystemd() bool { } func moveProcessPIDFileToScope(pidPath, slice, scope string) error { - data, err := ioutil.ReadFile(pidPath) + data, err := os.ReadFile(pidPath) if err != nil { // do not raise an error if the file doesn't exist if os.IsNotExist(err) { diff --git a/utils/utils_supported.go b/utils/utils_supported.go index d7d47b2bc..8844d46fd 100644 --- a/utils/utils_supported.go +++ b/utils/utils_supported.go @@ -8,7 +8,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -181,7 +180,7 @@ func moveUnderCgroup(cgroup, subtree string, processes []uint32) error { } } } else { - processesData, err := ioutil.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) + processesData, err := os.ReadFile(filepath.Join(cgroupRoot, parts[2], "cgroup.procs")) if err != nil { return err } |