summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go52
-rw-r--r--cmd/podman/images/list.go6
-rw-r--r--docs/source/markdown/podman-container-clone.1.md27
-rw-r--r--docs/source/markdown/podman-create.1.md6
-rw-r--r--docs/source/markdown/podman-images.1.md4
-rw-r--r--docs/source/markdown/podman-run.1.md6
-rw-r--r--libpod/container_config.go2
-rw-r--r--libpod/container_internal_linux.go19
-rw-r--r--libpod/container_log_linux.go3
-rw-r--r--libpod/options.go13
-rw-r--r--pkg/api/handlers/compat/images.go5
-rw-r--r--pkg/api/server/register_images.go5
-rw-r--r--pkg/bindings/images/types.go2
-rw-r--r--pkg/bindings/images/types_list_options.go15
-rw-r--r--pkg/domain/entities/images.go1
-rw-r--r--pkg/domain/entities/pods.go2
-rw-r--r--pkg/domain/infra/abi/images_list.go16
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/specgen/generate/container_create.go37
-rw-r--r--pkg/specgen/specgen.go2
-rw-r--r--pkg/specgenutil/specgen.go5
-rw-r--r--test/e2e/container_clone_test.go14
-rw-r--r--test/e2e/run_passwd_test.go12
-rw-r--r--test/system/010-images.bats11
-rw-r--r--test/system/015-help.bats15
-rw-r--r--test/system/030-run.bats24
-rw-r--r--test/system/035-logs.bats28
27 files changed, 221 insertions, 113 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 8a3f02036..62c9f4c9a 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -312,30 +312,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(logOptFlagName, AutocompleteLogOpt)
- memoryReservationFlagName := "memory-reservation"
- createFlags.StringVar(
- &cf.MemoryReservation,
- memoryReservationFlagName, "",
- "Memory soft limit "+sizeWithUnitFormat,
- )
- _ = cmd.RegisterFlagCompletionFunc(memoryReservationFlagName, completion.AutocompleteNone)
-
- memorySwapFlagName := "memory-swap"
- createFlags.StringVar(
- &cf.MemorySwap,
- memorySwapFlagName, "",
- "Swap limit equal to memory plus swap: '-1' to enable unlimited swap",
- )
- _ = cmd.RegisterFlagCompletionFunc(memorySwapFlagName, completion.AutocompleteNone)
-
- memorySwappinessFlagName := "memory-swappiness"
- createFlags.Int64Var(
- &cf.MemorySwappiness,
- memorySwappinessFlagName, -1,
- "Tune container memory swappiness (0 to 100, or -1 for system default)",
- )
- _ = cmd.RegisterFlagCompletionFunc(memorySwappinessFlagName, completion.AutocompleteNone)
-
createFlags.BoolVar(
&cf.NoHealthCheck,
"no-healthcheck", false,
@@ -630,6 +606,10 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(chrootDirsFlagName, completion.AutocompleteDefault)
+ passwdEntryName := "passwd-entry"
+ createFlags.StringVar(&cf.PasswdEntry, passwdEntryName, "", "Entry to write to /etc/passwd")
+ _ = cmd.RegisterFlagCompletionFunc(passwdEntryName, completion.AutocompleteNone)
+
if registry.IsRemote() {
_ = createFlags.MarkHidden("env-host")
_ = createFlags.MarkHidden("http-proxy")
@@ -891,6 +871,30 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
"Memory limit "+sizeWithUnitFormat,
)
_ = cmd.RegisterFlagCompletionFunc(memoryFlagName, completion.AutocompleteNone)
+
+ memoryReservationFlagName := "memory-reservation"
+ createFlags.StringVar(
+ &cf.MemoryReservation,
+ memoryReservationFlagName, "",
+ "Memory soft limit "+sizeWithUnitFormat,
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memoryReservationFlagName, completion.AutocompleteNone)
+
+ memorySwapFlagName := "memory-swap"
+ createFlags.StringVar(
+ &cf.MemorySwap,
+ memorySwapFlagName, "",
+ "Swap limit equal to memory plus swap: '-1' to enable unlimited swap",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memorySwapFlagName, completion.AutocompleteNone)
+
+ memorySwappinessFlagName := "memory-swappiness"
+ createFlags.Int64Var(
+ &cf.MemorySwappiness,
+ memorySwappinessFlagName, -1,
+ "Tune container memory swappiness (0 to 100, or -1 for system default)",
+ )
+ _ = cmd.RegisterFlagCompletionFunc(memorySwappinessFlagName, completion.AutocompleteNone)
}
//anyone can use these
cpusFlagName := "cpus"
diff --git a/cmd/podman/images/list.go b/cmd/podman/images/list.go
index 10a2a4f87..9bddf1cff 100644
--- a/cmd/podman/images/list.go
+++ b/cmd/podman/images/list.go
@@ -87,7 +87,6 @@ func imageListFlagSet(cmd *cobra.Command) {
flags := cmd.Flags()
flags.BoolVarP(&listOptions.All, "all", "a", false, "Show all images (default hides intermediate images)")
- flags.BoolVarP(&listOptions.Size, "size", "", true, "Compute the size of each image")
filterFlagName := "filter"
flags.StringSliceVarP(&listOptions.Filter, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])")
@@ -321,10 +320,7 @@ func lsFormatFromFlags(flags listFlagType) string {
row = append(row, "{{.Digest}}")
}
- row = append(row, "{{.ID}}", "{{.Created}}")
- if listOptions.Size {
- row = append(row, "{{.Size}}")
- }
+ row = append(row, "{{.ID}}", "{{.Created}}", "{{.Size}}")
if flags.history {
row = append(row, "{{if .History}}{{.History}}{{else}}<none>{{end}}")
diff --git a/docs/source/markdown/podman-container-clone.1.md b/docs/source/markdown/podman-container-clone.1.md
index 6c23abe81..7d5e1c262 100644
--- a/docs/source/markdown/podman-container-clone.1.md
+++ b/docs/source/markdown/podman-container-clone.1.md
@@ -137,6 +137,33 @@ system's page size (the value would be very large, that's millions of trillions)
If no memory limits are specified, the original container's will be used.
+#### **--memory-reservation**=*limit*
+
+Memory soft limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes))
+
+After setting memory reservation, when the system detects memory contention
+or low memory, containers are forced to restrict their consumption to their
+reservation. So you should always set the value below **--memory**, otherwise the
+hard limit will take precedence. By default, memory reservation will be the same
+as memory limit from the container being cloned.
+
+#### **--memory-swap**=*limit*
+
+A limit value equal to memory plus swap. Must be used with the **-m**
+(**--memory**) flag. The swap `LIMIT` should always be larger than **-m**
+(**--memory**) value. By default, the swap `LIMIT` will be set to double
+the value of --memory if specified. Otherwise, the container being cloned will be used to derive the swap value.
+
+The format of `LIMIT` is `<number>[<unit>]`. Unit can be `b` (bytes),
+`k` (kilobytes), `m` (megabytes), or `g` (gigabytes). If you don't specify a
+unit, `b` is used. Set LIMIT to `-1` to enable unlimited swap.
+
+#### **--memory-swappiness**=*number*
+
+Tune a container's memory swappiness behavior. Accepts an integer between 0 and 100.
+
+This flag is not supported on cgroups V2 systems.
+
#### **--name**
Set a custom name for the cloned container. The default if not specified is of the syntax: **<ORIGINAL_NAME>-clone**
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index c4d27e321..9af7174fc 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -755,6 +755,12 @@ Tune the host's OOM preferences for containers (accepts -1000 to 1000)
#### **--os**=*OS*
Override the OS, defaults to hosts, of the image to be pulled. For example, `windows`.
+#### **--passwd-entry**=*ENTRY*
+
+Customize the entry that is written to the `/etc/passwd` file within the container when `--passwd` is used.
+
+The variables $USERNAME, $UID, $GID, $NAME, $HOME are automatically replaced with their value at runtime.
+
#### **--personality**=*persona*
Personality sets the execution domain via Linux personality(2).
diff --git a/docs/source/markdown/podman-images.1.md b/docs/source/markdown/podman-images.1.md
index bdd187348..e28df840d 100644
--- a/docs/source/markdown/podman-images.1.md
+++ b/docs/source/markdown/podman-images.1.md
@@ -100,10 +100,6 @@ Omit the table headings from the listing of images.
Lists only the image IDs.
-#### **--size**
-
-Compute and display the size of each image. The default is true. Computing the size of images can be costly. If listing images is critical to performance, consider turning off size-computation via `--size=false`.
-
#### **--sort**=*sort*=*created*
Sort by created, id, repository, size or tag (default: created)
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index e4ccd0368..ecb24ba6d 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -787,6 +787,12 @@ Override the OS, defaults to hosts, of the image to be pulled. For example, `win
Allow Podman to add entries to /etc/passwd and /etc/group when used in conjunction with the --user option.
This is used to override the Podman provided user setup in favor of entrypoint configurations such as libnss-extrausers.
+#### **--passwd-entry**=*ENTRY*
+
+Customize the entry that is written to the `/etc/passwd` file within the container when `--passwd` is used.
+
+The variables $USERNAME, $UID, $GID, $NAME, $HOME are automatically replaced with their value at runtime.
+
#### **--personality**=*persona*
Personality sets the execution domain via Linux personality(2).
diff --git a/libpod/container_config.go b/libpod/container_config.go
index ea644764c..8500c6db9 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -404,6 +404,8 @@ type ContainerMiscConfig struct {
// InitContainerType specifies if the container is an initcontainer
// and if so, what type: always or once are possible non-nil entries
InitContainerType string `json:"init_container_type,omitempty"`
+ // PasswdEntry specifies arbitrary data to append to a file.
+ PasswdEntry string `json:"passwd_entry,omitempty"`
}
// InfraInherit contains the compatible options inheritable from the infra container
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 11ca169ca..9369b746c 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -2724,6 +2724,9 @@ func (c *Container) userPasswdEntry(u *user.User) (string, error) {
if !hasHomeSet {
c.config.Spec.Process.Env = append(c.config.Spec.Process.Env, fmt.Sprintf("HOME=%s", homeDir))
}
+ if c.config.PasswdEntry != "" {
+ return c.passwdEntry(u.Username, u.Uid, u.Gid, u.Name, homeDir), nil
+ }
return fmt.Sprintf("%s:*:%s:%s:%s:%s:/bin/sh\n", u.Username, u.Uid, u.Gid, u.Name, homeDir), nil
}
@@ -2775,9 +2778,25 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, err
gid = group.Gid
}
}
+
+ if c.config.PasswdEntry != "" {
+ entry := c.passwdEntry(fmt.Sprintf("%d", uid), fmt.Sprintf("%d", uid), fmt.Sprintf("%d", gid), "container user", c.WorkingDir())
+ return entry, int(uid), gid, nil
+ }
+
return fmt.Sprintf("%d:*:%d:%d:container user:%s:/bin/sh\n", uid, uid, gid, c.WorkingDir()), int(uid), gid, nil
}
+func (c *Container) passwdEntry(username string, uid, gid, name, homeDir string) string {
+ s := c.config.PasswdEntry
+ s = strings.Replace(s, "$USERNAME", username, -1)
+ s = strings.Replace(s, "$UID", uid, -1)
+ s = strings.Replace(s, "$GID", gid, -1)
+ s = strings.Replace(s, "$NAME", name, -1)
+ s = strings.Replace(s, "$HOME", homeDir, -1)
+ return s + "\n"
+}
+
// generatePasswdAndGroup generates container-specific passwd and group files
// iff g.config.User is a number or we are configured to make a passwd entry for
// the current user or the user specified HostsUsers
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index d96647e51..deb726526 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -209,9 +209,6 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
containerCouldBeLogging = true
case events.Exited:
containerCouldBeLogging = false
- if doTail {
- doTailFunc()
- }
}
continue
}
diff --git a/libpod/options.go b/libpod/options.go
index 2e5454393..6c4b4cc42 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -2051,3 +2051,16 @@ func WithChrootDirs(dirs []string) CtrCreateOption {
return nil
}
}
+
+// WithPasswdEntry sets the entry to write to the /etc/passwd file.
+func WithPasswdEntry(passwdEntry string) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+
+ ctr.config.PasswdEntry = passwdEntry
+
+ return nil
+ }
+}
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index ea2df4a73..edefce010 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -415,9 +415,8 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
All bool
Digests bool
Filter string // Docker 1.24 compatibility
- Size bool
}{
- Size: true,
+ // This is where you can override the golang default value for one of fields
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
@@ -444,7 +443,7 @@ func GetImages(w http.ResponseWriter, r *http.Request) {
imageEngine := abi.ImageEngine{Libpod: runtime}
- listOptions := entities.ImageListOptions{All: query.All, Filter: filterList, Size: query.Size}
+ listOptions := entities.ImageListOptions{All: query.All, Filter: filterList}
summaries, err := imageEngine.List(r.Context(), listOptions)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 2ed7aa054..89f808e7d 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -840,11 +840,6 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - `id`=(`<image-id>`)
// - `since`=(`<image-name>[:<tag>]`, `<image id>` or `<image@digest>`)
// type: string
- // - name: size
- // in: query
- // description: Compute the size of each image
- // type: boolean
- // default: true
// produces:
// - application/json
// responses:
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 87ec28dc2..75cb38a0a 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -31,8 +31,6 @@ type ListOptions struct {
All *bool
// filters that can be used to get a more specific list of images
Filters map[string][]string
- // Compute the size of each image
- Size *bool
}
//go:generate go run ../generator/generator.go GetOptions
diff --git a/pkg/bindings/images/types_list_options.go b/pkg/bindings/images/types_list_options.go
index 7f479630f..f47cd9c75 100644
--- a/pkg/bindings/images/types_list_options.go
+++ b/pkg/bindings/images/types_list_options.go
@@ -46,18 +46,3 @@ func (o *ListOptions) GetFilters() map[string][]string {
}
return o.Filters
}
-
-// WithSize set field Size to given value
-func (o *ListOptions) WithSize(value bool) *ListOptions {
- o.Size = &value
- return o
-}
-
-// GetSize returns value of field Size
-func (o *ListOptions) GetSize() bool {
- if o.Size == nil {
- var z bool
- return z
- }
- return *o.Size
-}
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index 56126f46c..7081c5d25 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -251,7 +251,6 @@ type ImageSearchReport struct {
type ImageListOptions struct {
All bool `json:"all" schema:"all"`
Filter []string `json:"Filter,omitempty"`
- Size bool `json:"size" schema:"size"`
}
type ImagePruneOptions struct {
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index f1d445c4b..1e25e0872 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -272,6 +272,8 @@ type ContainerCreateOptions struct {
Net *NetOptions `json:"net,omitempty"`
CgroupConf []string
+
+ PasswdEntry string
}
func NewInfraContainerCreateOptions() ContainerCreateOptions {
diff --git a/pkg/domain/infra/abi/images_list.go b/pkg/domain/infra/abi/images_list.go
index 8825f1ac6..9a0aaaf3a 100644
--- a/pkg/domain/infra/abi/images_list.go
+++ b/pkg/domain/infra/abi/images_list.go
@@ -60,16 +60,14 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
}
e.Containers = len(ctnrs)
- if opts.Size {
- sz, err := img.Size()
- if err != nil {
- return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID())
- }
- e.Size = sz
- // This is good enough for now, but has to be
- // replaced later with correct calculation logic
- e.VirtualSize = sz
+ sz, err := img.Size()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error retrieving size of image %q: you may need to remove the image to resolve the error", img.ID())
}
+ e.Size = sz
+ // This is good enough for now, but has to be
+ // replaced later with correct calculation logic
+ e.VirtualSize = sz
parent, err := img.Parent(ctx)
if err != nil {
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 4694189e3..18e10e8dd 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -38,7 +38,7 @@ func (ir *ImageEngine) List(ctx context.Context, opts entities.ImageListOptions)
f := strings.Split(filter, "=")
filters[f[0]] = f[1:]
}
- options := new(images.ListOptions).WithAll(opts.All).WithFilters(filters).WithSize(opts.Size)
+ options := new(images.ListOptions).WithAll(opts.All).WithFilters(filters)
psImages, err := images.List(ir.ClientCtx, options)
if err != nil {
return nil, err
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 6a611e854..5667a02e8 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -8,7 +8,6 @@ import (
cdi "github.com/container-orchestrated-devices/container-device-interface/pkg/cdi"
"github.com/containers/common/libimage"
- "github.com/containers/common/pkg/cgroups"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/namespaces"
@@ -184,32 +183,19 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
if err != nil {
return nil, nil, nil, err
}
-
- switch {
- case s.ResourceLimits.CPU != nil:
- runtimeSpec.Linux.Resources.CPU = s.ResourceLimits.CPU
- case s.ResourceLimits.Memory != nil:
- runtimeSpec.Linux.Resources.Memory = s.ResourceLimits.Memory
- case s.ResourceLimits.BlockIO != nil:
- runtimeSpec.Linux.Resources.BlockIO = s.ResourceLimits.BlockIO
- case s.ResourceLimits.Devices != nil:
- runtimeSpec.Linux.Resources.Devices = s.ResourceLimits.Devices
- }
-
- cgroup2, err := cgroups.IsCgroup2UnifiedMode()
- if err != nil {
- return nil, nil, nil, err
- }
- if cgroup2 && s.ResourceLimits.Memory != nil && s.ResourceLimits.Memory.Swappiness != nil { // conf.Spec.Linux contains memory swappiness established after the spec process we need to remove that
- s.ResourceLimits.Memory.Swappiness = nil
- if runtimeSpec.Linux.Resources.Memory != nil {
- runtimeSpec.Linux.Resources.Memory.Swappiness = nil
+ if s.ResourceLimits != nil {
+ switch {
+ case s.ResourceLimits.CPU != nil:
+ runtimeSpec.Linux.Resources.CPU = s.ResourceLimits.CPU
+ case s.ResourceLimits.Memory != nil:
+ runtimeSpec.Linux.Resources.Memory = s.ResourceLimits.Memory
+ case s.ResourceLimits.BlockIO != nil:
+ runtimeSpec.Linux.Resources.BlockIO = s.ResourceLimits.BlockIO
+ case s.ResourceLimits.Devices != nil:
+ runtimeSpec.Linux.Resources.Devices = s.ResourceLimits.Devices
}
}
}
- if err != nil {
- return nil, nil, nil, err
- }
if len(s.HostDeviceList) > 0 {
options = append(options, libpod.WithHostDevice(s.HostDeviceList))
}
@@ -286,6 +272,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.Volatile {
options = append(options, libpod.WithVolatile())
}
+ if s.PasswdEntry != "" {
+ options = append(options, libpod.WithPasswdEntry(s.PasswdEntry))
+ }
useSystemd := false
switch s.Systemd {
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index dfac1d457..79e20667b 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -206,6 +206,8 @@ type ContainerBasicConfig struct {
UnsetEnvAll bool `json:"unsetenvall,omitempty"`
// Passwd is a container run option that determines if we are validating users/groups before running the container
Passwd *bool `json:"manage_password,omitempty"`
+ // PasswdEntry specifies arbitrary data to append to a file.
+ PasswdEntry string `json:"passwd_entry,omitempty"`
}
// ContainerStorageConfig contains information on the storage configuration of a
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 7d4fca846..42b66d909 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -832,6 +832,11 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if s.Passwd == nil {
s.Passwd = &t
}
+
+ if len(s.PasswdEntry) == 0 || len(c.PasswdEntry) != 0 {
+ s.PasswdEntry = c.PasswdEntry
+ }
+
return nil
}
diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go
index a327bb8ed..1d5944d1a 100644
--- a/test/e2e/container_clone_test.go
+++ b/test/e2e/container_clone_test.go
@@ -146,6 +146,20 @@ var _ = Describe("Podman container clone", func() {
cloneData = cloneInspect.InspectContainerToJSON()
Expect(createData[0].HostConfig.NanoCpus).ToNot(Equal(cloneData[0].HostConfig.NanoCpus))
Expect(cloneData[0].HostConfig.NanoCpus).To(Equal(nanoCPUs))
+
+ create = podmanTest.Podman([]string{"create", ALPINE})
+ create.WaitWithDefaultTimeout()
+ Expect(create).To(Exit(0))
+ clone = podmanTest.Podman([]string{"container", "clone", "--cpus=4", create.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ cloneInspect = podmanTest.Podman([]string{"inspect", clone.OutputToString()})
+ cloneInspect.WaitWithDefaultTimeout()
+ Expect(cloneInspect).To(Exit(0))
+ cloneData = cloneInspect.InspectContainerToJSON()
+ Expect(cloneData[0].HostConfig.MemorySwappiness).To(Equal(int64(0)))
+
})
It("podman container clone in a pod", func() {
diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go
index 4c97e665a..ce6c6ffda 100644
--- a/test/e2e/run_passwd_test.go
+++ b/test/e2e/run_passwd_test.go
@@ -137,4 +137,16 @@ USER 1000`, ALPINE)
Expect(run).Should(Exit(0))
Expect(run.OutputToString()).NotTo((ContainSubstring("1234:1234")))
})
+
+ It("podman run --passwd-entry flag", func() {
+ // Test that the line we add doesn't contain anything else than what is specified
+ run := podmanTest.Podman([]string{"run", "--user", "1234:1234", "--passwd-entry=FOO", ALPINE, "grep", "^FOO$", "/etc/passwd"})
+ run.WaitWithDefaultTimeout()
+ Expect(run).Should(Exit(0))
+
+ run = podmanTest.Podman([]string{"run", "--user", "12345:12346", "-w", "/etc", "--passwd-entry=$UID-$GID-$NAME-$HOME-$USERNAME", ALPINE, "cat", "/etc/passwd"})
+ run.WaitWithDefaultTimeout()
+ Expect(run).Should(Exit(0))
+ Expect(run.OutputToString()).To(ContainSubstring("12345-12346-container user-/etc-12345"))
+ })
})
diff --git a/test/system/010-images.bats b/test/system/010-images.bats
index 352c3aa95..257508418 100644
--- a/test/system/010-images.bats
+++ b/test/system/010-images.bats
@@ -312,15 +312,4 @@ Deleted: $pauseID"
is "$output" ""
}
-@test "podman images --size" {
- run_podman images
- is "${lines[0]}" "REPOSITORY.*TAG.*IMAGE ID.*CREATED.*SIZE"
- run_podman images --noheading --format "{{.Size}}"
- is "$output" ".* MB"
- run_podman images --size=false
- is "${lines[0]}" "REPOSITORY.*TAG.*IMAGE ID.*CREATED"
- run_podman images --noheading --format "{{.Size}}" --size=false
- is "$output" "0 B"
-}
-
# vim: filetype=sh
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index a87081687..4eeea85bf 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -68,9 +68,10 @@ function check_help() {
if [ "$cmd" != "help" ]; then
dprint "$command_string invalid-arg"
run_podman '?' "$@" $cmd invalid-arg
- is "$status" 125 "'$command_string invalid-arg' - exit status"
+ is "$status" 125 \
+ "'$usage' indicates that the command takes no arguments. I invoked it with 'invalid-arg' and expected an error status"
is "$output" "Error: .* takes no arguments" \
- "'$command_string' with extra (invalid) arguments"
+ "'$usage' indicates that the command takes no arguments. I invoked it with 'invalid-arg' and expected the following error message"
fi
found[takes_no_args]=1
fi
@@ -115,9 +116,10 @@ function check_help() {
# try to read username/password from stdin.
dprint "$command_string (without required args)"
run_podman '?' "$@" $cmd </dev/null
- is "$status" 125 "'$command_string' with no arguments - exit status"
+ is "$status" 125 \
+ "'$usage' indicates at least one required arg. I invoked it with no args and expected an error exit code"
is "$output" "Error:.* \(require\|specif\|must\|provide\|need\|choose\|accepts\)" \
- "'$command_string' without required arg"
+ "'$usage' indicates at least one required arg. I invoked it with no args and expected one of these error messages"
found[required_args]=1
fi
@@ -138,9 +140,10 @@ function check_help() {
local n_args=$(wc -w <<<"$rhs")
run_podman '?' "$@" $cmd $(seq --format='x%g' 0 $n_args)
- is "$status" 125 "'$command_string' with >$n_args arguments - exit status"
+ is "$status" 125 \
+ "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected this exit status"
is "$output" "Error:.* \(takes no arguments\|requires exactly $n_args arg\|accepts at most\|too many arguments\|accepts $n_args arg(s), received\|accepts between .* and .* arg(s), received \)" \
- "'$command_string' with >$n_args arguments"
+ "'$usage' indicates a maximum of $n_args args. I invoked it with more, and expected one of these error messages"
found[fixed_args]=1
fi
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 72e4a2bc8..aba18badb 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -821,4 +821,28 @@ EOF
run_podman run --rm $IMAGE cat /proc/self/oom_score_adj
is "$output" "$current_oom_score_adj" "different oom_score_adj in the container"
}
+
+# CVE-2022-1227 : podman top joins container mount NS and uses nsenter from image
+@test "podman top does not use nsenter from image" {
+ tmpdir=$PODMAN_TMPDIR/build-test
+ mkdir -p $tmpdir
+ tmpbuilddir=$tmpdir/build
+ mkdir -p $tmpbuilddir
+ dockerfile=$tmpbuilddir/Dockerfile
+ cat >$dockerfile <<EOF
+FROM $IMAGE
+RUN rm /usr/bin/nsenter; \
+echo -e "#!/bin/sh\nfalse" >> /usr/bin/nsenter; \
+chmod +x /usr/bin/nsenter
+EOF
+
+ test_image="cve_2022_1227_test"
+ run_podman build -t $test_image $tmpbuilddir
+ run_podman run -d --userns=keep-id $test_image top
+ ctr="$output"
+ run_podman top $ctr huser,user
+ run_podman rm -f -t0 $ctr
+ run_podman rmi $test_image
+}
+
# vim: filetype=sh
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index db50c8f8c..e38cdb383 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -30,6 +30,34 @@ load helpers
run_podman rm $cid
}
+function _log_test_tail() {
+ local driver=$1
+
+ run_podman run -d --log-driver=$driver $IMAGE sh -c "echo test1; echo test2"
+ cid="$output"
+
+ run_podman logs --tail 1 $cid
+ is "$output" "test2" "logs should only show last line"
+
+ run_podman restart $cid
+
+ run_podman logs --tail 1 $cid
+ is "$output" "test2" "logs should only show last line after restart"
+
+ run_podman rm $cid
+}
+
+@test "podman logs - tail test, k8s-file" {
+ _log_test_tail k8s-file
+}
+
+@test "podman logs - tail test, journald" {
+ # We can't use journald on RHEL as rootless: rhbz#1895105
+ skip_if_journald_unavailable
+
+ _log_test_tail journald
+}
+
function _additional_events_backend() {
local driver=$1
# Since PR#10431, 'logs -f' with journald driver is only supported with journald events backend.