summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go19
-rw-r--r--cmd/podman/images/scp.go13
-rw-r--r--cmd/podman/root.go5
-rw-r--r--docs/source/markdown/podman-pod-create.1.md22
-rw-r--r--docs/source/markdown/podman.1.md5
-rw-r--r--libpod/options.go2
-rw-r--r--libpod/runtime.go7
-rw-r--r--pkg/domain/entities/engine.go1
-rw-r--r--pkg/domain/entities/events.go2
-rw-r--r--pkg/domain/entities/pods.go12
-rw-r--r--pkg/domain/infra/abi/images.go50
-rw-r--r--pkg/machine/config.go9
-rw-r--r--pkg/machine/qemu/machine.go122
-rw-r--r--pkg/specgen/podspecgen.go2
-rw-r--r--test/e2e/events_test.go2
-rw-r--r--test/e2e/pod_create_test.go39
-rw-r--r--test/system/030-run.bats15
-rw-r--r--test/system/050-stop.bats5
-rw-r--r--test/system/080-pause.bats3
-rw-r--r--test/system/090-events.bats13
-rw-r--r--test/system/200-pod.bats6
-rw-r--r--test/system/250-systemd.bats5
-rw-r--r--test/system/500-networking.bats6
23 files changed, 302 insertions, 63 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index b60169990..e95e447e1 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -563,15 +563,6 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(stopTimeoutFlagName, completion.AutocompleteNone)
- sysctlFlagName := "sysctl"
- createFlags.StringSliceVar(
- &cf.Sysctl,
- sysctlFlagName, []string{},
- "Sysctl options",
- )
- //TODO: Add function for sysctl completion.
- _ = cmd.RegisterFlagCompletionFunc(sysctlFlagName, completion.AutocompleteNone)
-
systemdFlagName := "systemd"
createFlags.StringVar(
&cf.Systemd,
@@ -712,6 +703,16 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
`If a container with the same name exists, replace it`,
)
}
+
+ sysctlFlagName := "sysctl"
+ createFlags.StringSliceVar(
+ &cf.Sysctl,
+ sysctlFlagName, []string{},
+ "Sysctl options",
+ )
+ //TODO: Add function for sysctl completion.
+ _ = cmd.RegisterFlagCompletionFunc(sysctlFlagName, completion.AutocompleteNone)
+
securityOptFlagName := "security-opt"
createFlags.StringArrayVar(
&cf.SecurityOpt,
diff --git a/cmd/podman/images/scp.go b/cmd/podman/images/scp.go
index f02a3c15e..fb20d9417 100644
--- a/cmd/podman/images/scp.go
+++ b/cmd/podman/images/scp.go
@@ -46,6 +46,7 @@ var (
var (
parentFlags []string
+ quiet bool
source entities.ImageScpOptions
dest entities.ImageScpOptions
sshInfo entities.ImageScpConnections
@@ -61,7 +62,7 @@ func init() {
func scpFlags(cmd *cobra.Command) {
flags := cmd.Flags()
- flags.BoolVarP(&source.Quiet, "quiet", "q", false, "Suppress the output")
+ flags.BoolVarP(&quiet, "quiet", "q", false, "Suppress the output")
}
func scp(cmd *cobra.Command, args []string) (finalErr error) {
@@ -139,6 +140,7 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
}
}
+ source.Quiet = quiet
source.File = f.Name() // after parsing the arguments, set the file for the save/load
dest.File = source.File
if err = os.Remove(source.File); err != nil { // remove the file and simply use its name so podman creates the file upon save. avoids umask errors
@@ -203,15 +205,6 @@ func scp(cmd *cobra.Command, args []string) (finalErr error) {
}
}
- src, err := json.MarshalIndent(source, "", " ")
- if err != nil {
- return err
- }
- dst, err := json.MarshalIndent(dest, "", " ")
- if err != nil {
- return err
- }
- fmt.Printf("SOURCE: %s\nDEST: %s\n", string(src), string(dst))
return nil
}
diff --git a/cmd/podman/root.go b/cmd/podman/root.go
index b695443c2..1de937ca5 100644
--- a/cmd/podman/root.go
+++ b/cmd/podman/root.go
@@ -114,6 +114,10 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error {
}
cfg := registry.PodmanConfig()
+ if cfg.NoOut {
+ null, _ := os.Open(os.DevNull)
+ os.Stdout = null
+ }
// Currently it is only possible to restore a container with the same runtime
// as used for checkpointing. It should be possible to make crun and runc
@@ -343,6 +347,7 @@ func rootFlags(cmd *cobra.Command, opts *entities.PodmanConfig) {
lFlags.StringVar(&opts.Identity, identityFlagName, ident, "path to SSH identity file, (CONTAINER_SSHKEY)")
_ = cmd.RegisterFlagCompletionFunc(identityFlagName, completion.AutocompleteDefault)
+ lFlags.BoolVar(&opts.NoOut, "noout", false, "do not output to stdout")
lFlags.BoolVarP(&opts.Remote, "remote", "r", registry.IsRemote(), "Access remote Podman service")
pFlags := cmd.PersistentFlags()
if registry.IsRemote() {
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index b2e16e051..c9255d37f 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -276,6 +276,28 @@ podman generates a UUID for each pod, and if a name is not assigned
to the container with **--name** then a random string name will be generated
for it. The name is useful any place you need to identify a pod.
+#### **--sysctl**=_name_=_value_
+
+Configure namespace kernel parameters for all containers in the pod.
+
+For the IPC namespace, the following sysctls are allowed:
+
+- kernel.msgmax
+- kernel.msgmnb
+- kernel.msgmni
+- kernel.sem
+- kernel.shmall
+- kernel.shmmax
+- kernel.shmmni
+- kernel.shm_rmid_forced
+- Sysctls beginning with fs.mqueue.\*
+
+Note: if the ipc namespace is not shared within the pod, these sysctls are not allowed.
+
+For the network namespace, only sysctls beginning with net.\* are allowed.
+
+Note: if the network namespace is not shared within the pod, these sysctls are not allowed.
+
#### **--userns**=*mode*
Set the user namespace mode for all the containers in a pod. It defaults to the **PODMAN_USERNS** environment variable. An empty value ("") means user namespaces are disabled.
diff --git a/docs/source/markdown/podman.1.md b/docs/source/markdown/podman.1.md
index daa8212c5..9f85ebda3 100644
--- a/docs/source/markdown/podman.1.md
+++ b/docs/source/markdown/podman.1.md
@@ -92,6 +92,11 @@ When namespace is set, created containers and pods will join the given namespace
#### **--network-cmd-path**=*path*
Path to the command binary to use for setting up a network. It is currently only used for setting up a slirp4netns network. If "" is used then the binary is looked up using the $PATH environment variable.
+#### **--noout**
+
+Redirect stdout to /dev/null. This command will prevent all stdout from the Podman command. The **--noout** option will not block stderr or stdout from containers.
+
+
#### **--remote**, **-r**
When true, access to the Podman service will be remote. Defaults to false.
Settings can be modified in the containers.conf file. If the CONTAINER_HOST
diff --git a/libpod/options.go b/libpod/options.go
index 1137d228f..5cf7609e9 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -500,8 +500,6 @@ func WithEventsLogger(logger string) RuntimeOption {
}
rt.config.Engine.EventsLogger = logger
- rt.config.Engine.EventsLogFilePath = filepath.Join(rt.config.Engine.TmpDir, "events", "events.log")
-
return nil
}
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 5a86cc993..077fce999 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -169,7 +169,6 @@ func NewRuntime(ctx context.Context, options ...RuntimeOption) (*Runtime, error)
if err != nil {
return nil, err
}
- conf.CheckCgroupsAndAdjustConfig()
return newRuntimeFromConfig(ctx, conf, options...)
}
@@ -227,6 +226,8 @@ func newRuntimeFromConfig(ctx context.Context, conf *config.Config, options ...R
return nil, err
}
+ runtime.config.CheckCgroupsAndAdjustConfig()
+
return runtime, nil
}
@@ -1078,7 +1079,9 @@ func (r *Runtime) mergeDBConfig(dbConfig *DBConfig) {
logrus.Debugf("Overriding tmp dir %q with %q from database", c.TmpDir, dbConfig.LibpodTmp)
}
c.TmpDir = dbConfig.LibpodTmp
- c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log")
+ if c.EventsLogFilePath == "" {
+ c.EventsLogFilePath = filepath.Join(dbConfig.LibpodTmp, "events", "events.log")
+ }
}
if !r.storageSet.VolumePathSet && dbConfig.VolumePath != "" {
diff --git a/pkg/domain/entities/engine.go b/pkg/domain/entities/engine.go
index a8023f7cf..055af7ff9 100644
--- a/pkg/domain/entities/engine.go
+++ b/pkg/domain/entities/engine.go
@@ -40,6 +40,7 @@ type PodmanConfig struct {
Identity string // ssh identity for connecting to server
MaxWorks int // maximum number of parallel threads
MemoryProfile string // Hidden: Should memory profile be taken
+ NoOut bool // Don't output to stdout
RegistriesConf string // allows for specifying a custom registries.conf
Remote bool // Connection to Podman API Service will use RESTful API
RuntimePath string // --runtime flag will set Engine.RuntimePath
diff --git a/pkg/domain/entities/events.go b/pkg/domain/entities/events.go
index 73a375b94..fa815d7b9 100644
--- a/pkg/domain/entities/events.go
+++ b/pkg/domain/entities/events.go
@@ -42,7 +42,7 @@ func ConvertToLibpodEvent(e Event) *libpodEvents.Event {
Image: image,
Name: name,
Status: status,
- Time: time.Unix(e.Time, e.TimeNano),
+ Time: time.Unix(0, e.TimeNano),
Type: t,
Details: libpodEvents.Details{
Attributes: details,
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index 1b5a1be51..cc9476d79 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -139,6 +139,7 @@ type PodCreateOptions struct {
Volume []string `json:"volume,omitempty"`
VolumesFrom []string `json:"volumes_from,omitempty"`
SecurityOpt []string `json:"security_opt,omitempty"`
+ Sysctl []string `json:"sysctl,omitempty"`
}
// PodLogsOptions describes the options to extract pod logs.
@@ -240,7 +241,7 @@ type ContainerCreateOptions struct {
StorageOpts []string
SubUIDName string
SubGIDName string
- Sysctl []string
+ Sysctl []string `json:"sysctl,omitempty"`
Systemd string
Timeout uint
TLSVerify commonFlag.OptionalBool
@@ -360,6 +361,15 @@ func ToPodSpecGen(s specgen.PodSpecGenerator, p *PodCreateOptions) (*specgen.Pod
}
}
s.Userns = p.Userns
+ sysctl := map[string]string{}
+ if ctl := p.Sysctl; len(ctl) > 0 {
+ sysctl, err = util.ValidateSysctls(ctl)
+ if err != nil {
+ return nil, err
+ }
+ }
+ s.Sysctl = sysctl
+
return &s, nil
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 84c83ea8e..592e0f4e3 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -745,11 +745,17 @@ func putSignature(manifestBlob []byte, mech signature.SigningMechanism, sigStore
// TransferRootless creates new podman processes using exec.Command and sudo, transferring images between the given source and destination users
func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
var cmdSave *exec.Cmd
- saveCommand := parentFlags
- saveCommand = append(saveCommand, []string{"save", "--output", source.File, source.Image}...)
+ saveCommand, loadCommand := parentFlags, parentFlags
+ saveCommand = append(saveCommand, []string{"save"}...)
+ loadCommand = append(loadCommand, []string{"load"}...)
+ if source.Quiet {
+ saveCommand = append(saveCommand, "-q")
+ loadCommand = append(loadCommand, "-q")
+ }
+
+ saveCommand = append(saveCommand, []string{"--output", source.File, source.Image}...)
- loadCommand := parentFlags
- loadCommand = append(loadCommand, []string{"load", "--input", dest.File}...)
+ loadCommand = append(loadCommand, []string{"--input", dest.File}...)
if source.User == "root" {
cmdSave = exec.Command("sudo", podman)
@@ -757,7 +763,7 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
cmdSave = exec.Command(podman)
}
cmdSave = utils.CreateSCPCommand(cmdSave, saveCommand)
- logrus.Debug("Executing save command")
+ logrus.Debugf("Executing save command: %q", cmdSave)
err := cmdSave.Run()
if err != nil {
return err
@@ -770,20 +776,22 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
cmdLoad = exec.Command(podman)
}
cmdLoad = utils.CreateSCPCommand(cmdLoad, loadCommand)
- logrus.Debug("Executing load command")
- err = cmdLoad.Run()
- if err != nil {
- return err
- }
- return nil
+ logrus.Debugf("Executing load command: %q", cmdLoad)
+ return cmdLoad.Run()
}
-// TransferRootless creates new podman processes using exec.Command and su/machinectl, transferring images between the given source and destination users
+// TransferRootful creates new podman processes using exec.Command and su/machinectl, transferring images between the given source and destination users
func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
- saveCommand := append(basicCommand, []string{"save", "--output", source.File, source.Image}...)
- loadCommand := append(basicCommand, []string{"load", "--input", dest.File}...)
+ saveCommand := append(basicCommand, "save")
+ loadCommand := append(basicCommand, "load")
+ if source.Quiet {
+ saveCommand = append(saveCommand, "-q")
+ loadCommand = append(loadCommand, "-q")
+ }
+ saveCommand = append(saveCommand, []string{"--output", source.File, source.Image}...)
+ loadCommand = append(loadCommand, []string{"--input", dest.File}...)
save := []string{strings.Join(saveCommand, " ")}
load := []string{strings.Join(loadCommand, " ")}
@@ -846,18 +854,18 @@ func lookupUser(u string) (*user.User, error) {
func execSu(execUser *user.User, command []string) error {
cmd := exec.Command("su", "-l", execUser.Username, "--command")
cmd = utils.CreateSCPCommand(cmd, command)
- logrus.Debug("Executing command su")
+ logrus.Debugf("Executing via su: %q", cmd)
return cmd.Run()
}
func execMachine(execUser *user.User, command []string, machinectl string) error {
- var cmd *exec.Cmd
+ verb := machinectl
+ args := []string{"shell", "-q", execUser.Username + "@.host"}
if execUser.Uid == "0" {
- cmd = exec.Command("sudo", machinectl, "shell", "-q", execUser.Username+"@.host")
- } else {
- cmd = exec.Command(machinectl, "shell", "-q", execUser.Username+"@.host")
+ args = append([]string{verb}, args...)
+ verb = "sudo"
}
- cmd = utils.CreateSCPCommand(cmd, command)
- logrus.Debug("Executing command machinectl")
+ cmd := utils.CreateSCPCommand(exec.Command(verb, args...), command)
+ logrus.Debugf("Executing via machinectl: %q", cmd)
return cmd.Run()
}
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 27a7c1b1f..97237f5e5 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -29,6 +29,15 @@ type InitOptions struct {
ReExec bool
}
+type QemuMachineStatus = string
+
+const (
+ // Running indicates the qemu vm is running
+ Running QemuMachineStatus = "running"
+ // Stopped indicates the vm has stopped
+ Stopped QemuMachineStatus = "stopped"
+)
+
type Provider interface {
NewMachine(opts InitOptions) (VM, error)
LoadVMByName(name string) (VM, error)
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a43d78665..560037542 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -386,8 +386,16 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
}
if len(v.Mounts) > 0 {
- for !v.isRunning() || !v.isListening() {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ for running || !v.isListening() {
time.Sleep(100 * time.Millisecond)
+ running, err = v.isRunning()
+ if err != nil {
+ return err
+ }
}
}
for _, mount := range v.Mounts {
@@ -416,8 +424,48 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return nil
}
+func (v *MachineVM) checkStatus(monitor *qmp.SocketMonitor) (machine.QemuMachineStatus, error) {
+ // this is the format returned from the monitor
+ // {"return": {"status": "running", "singlestep": false, "running": true}}
+
+ type statusDetails struct {
+ Status string `json:"status"`
+ Step bool `json:"singlestep"`
+ Running bool `json:"running"`
+ }
+ type statusResponse struct {
+ Response statusDetails `json:"return"`
+ }
+ var response statusResponse
+
+ checkCommand := struct {
+ Execute string `json:"execute"`
+ }{
+ Execute: "query-status",
+ }
+ input, err := json.Marshal(checkCommand)
+ if err != nil {
+ return "", err
+ }
+ b, err := monitor.Run(input)
+ if err != nil {
+ if errors.Cause(err) == os.ErrNotExist {
+ return machine.Stopped, nil
+ }
+ return "", err
+ }
+ if err := json.Unmarshal(b, &response); err != nil {
+ return "", err
+ }
+ if response.Response.Status == machine.Running {
+ return machine.Running, nil
+ }
+ return machine.Stopped, nil
+}
+
// Stop uses the qmp monitor to call a system_powerdown
func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
+ var disconnected bool
// check if the qmp socket is there. if not, qemu instance is gone
if _, err := os.Stat(v.QMPMonitor.Address); os.IsNotExist(err) {
// Right now it is NOT an error to stop a stopped machine
@@ -442,19 +490,22 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
return err
}
defer func() {
- if err := qmpMonitor.Disconnect(); err != nil {
- logrus.Error(err)
+ if !disconnected {
+ if err := qmpMonitor.Disconnect(); err != nil {
+ logrus.Error(err)
+ }
}
}()
+
if _, err = qmpMonitor.Run(input); err != nil {
return err
}
+
qemuSocketFile, pidFile, err := v.getSocketandPid()
if err != nil {
return err
}
if _, err := os.Stat(pidFile); os.IsNotExist(err) {
- logrus.Info(err)
return nil
}
pidString, err := ioutil.ReadFile(pidFile)
@@ -483,6 +534,24 @@ func (v *MachineVM) Stop(name string, _ machine.StopOptions) error {
return err
}
+ if err := qmpMonitor.Disconnect(); err != nil {
+ return nil
+ }
+
+ disconnected = true
+ waitInternal := 250 * time.Millisecond
+ for i := 0; i < 5; i++ {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ if !running {
+ break
+ }
+ time.Sleep(waitInternal)
+ waitInternal = waitInternal * 2
+ }
+
return nil
}
@@ -519,7 +588,11 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
)
// cannot remove a running vm
- if v.isRunning() {
+ running, err := v.isRunning()
+ if err != nil {
+ return "", nil, err
+ }
+ if running {
return "", nil, errors.Errorf("running vm %q cannot be destroyed", v.Name)
}
@@ -578,16 +651,33 @@ func (v *MachineVM) Remove(name string, opts machine.RemoveOptions) (string, fun
}, nil
}
-func (v *MachineVM) isRunning() bool {
+func (v *MachineVM) isRunning() (bool, error) {
// Check if qmp socket path exists
if _, err := os.Stat(v.QMPMonitor.Address); os.IsNotExist(err) {
- return false
+ return false, nil
}
// Check if we can dial it
- if _, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address, v.QMPMonitor.Timeout); err != nil {
- return false
+ monitor, err := qmp.NewSocketMonitor(v.QMPMonitor.Network, v.QMPMonitor.Address, v.QMPMonitor.Timeout)
+ if err != nil {
+ return false, nil
}
- return true
+ if err := monitor.Connect(); err != nil {
+ return false, err
+ }
+ defer func() {
+ if err := monitor.Disconnect(); err != nil {
+ logrus.Error(err)
+ }
+ }()
+ // If there is a monitor, lets see if we can query state
+ state, err := v.checkStatus(monitor)
+ if err != nil {
+ return false, err
+ }
+ if state == machine.Running {
+ return true, nil
+ }
+ return false, nil
}
func (v *MachineVM) isListening() bool {
@@ -603,7 +693,11 @@ func (v *MachineVM) isListening() bool {
// SSH opens an interactive SSH session to the vm specified.
// Added ssh function to VM interface: pkg/machine/config/go : line 58
func (v *MachineVM) SSH(name string, opts machine.SSHOptions) error {
- if !v.isRunning() {
+ running, err := v.isRunning()
+ if err != nil {
+ return err
+ }
+ if !running {
return errors.Errorf("vm %q is not running.", v.Name)
}
@@ -710,7 +804,11 @@ func GetVMInfos() ([]*machine.ListResponse, error) {
return err
}
listEntry.LastUp = fi.ModTime()
- if vm.isRunning() {
+ running, err := vm.isRunning()
+ if err != nil {
+ return err
+ }
+ if running {
listEntry.Running = true
}
diff --git a/pkg/specgen/podspecgen.go b/pkg/specgen/podspecgen.go
index ec4c66595..b6f2d6bf0 100644
--- a/pkg/specgen/podspecgen.go
+++ b/pkg/specgen/podspecgen.go
@@ -74,6 +74,8 @@ type PodBasicConfig struct {
Userns Namespace `json:"userns,omitempty"`
// Devices contains user specified Devices to be added to the Pod
Devices []string `json:"pod_devices,omitempty"`
+ // Sysctl sets kernel parameters for the pod
+ Sysctl map[string]string `json:"sysctl,omitempty"`
}
// PodNetworkConfig contains networking configuration for a pod.
diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go
index 39f495460..3b5b8ac6c 100644
--- a/test/e2e/events_test.go
+++ b/test/e2e/events_test.go
@@ -62,6 +62,8 @@ var _ = Describe("Podman events", func() {
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(0))
Expect(len(result.OutputToStringArray())).To(BeNumerically(">=", 1), "Number of events")
+ date := time.Now().Format("2006-01-02")
+ Expect(result.OutputToStringArray()).To(ContainElement(HavePrefix(date)), "event log has correct timestamp")
})
It("podman events with an event filter and container=cid", func() {
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index fab107af8..623377ea1 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -1029,4 +1029,43 @@ ENTRYPOINT ["sleep","99999"]
Expect(inspect[0].AppArmorProfile).To(Equal(apparmor.Profile))
})
+
+ It("podman pod create --sysctl test", func() {
+ SkipIfRootless("Network sysctls are not available root rootless")
+ podCreate := podmanTest.Podman([]string{"pod", "create", "--sysctl", "net.core.somaxconn=65535"})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+ session := podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
+
+ // if not sharing the net NS, nothing should fail, but the sysctl should not be passed
+ podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "net.core.somaxconn=65535"})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+ session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).NotTo(ContainSubstring("net.core.somaxconn = 65535"))
+
+ // one other misc option
+ podCreate = podmanTest.Podman([]string{"pod", "create", "--sysctl", "kernel.msgmax=65535"})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+ session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("kernel.msgmax = 65535"))
+
+ podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "kernel.msgmax=65535"})
+ podCreate.WaitWithDefaultTimeout()
+ Expect(podCreate).Should(Exit(0))
+ session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).NotTo(ContainSubstring("kernel.msgmax = 65535"))
+
+ })
+
})
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index feca5370b..afcda3d3c 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -509,6 +509,21 @@ json-file | f
rm -f $new_runtime
}
+@test "podman --noout run should print output" {
+ run_podman --noout run -d --name test $IMAGE echo hi
+ is "$output" "" "output should be empty"
+ run_podman wait test
+ run_podman --noout rm test
+ is "$output" "" "output should be empty"
+}
+
+@test "podman --noout create should print output" {
+ run_podman --noout create --name test $IMAGE echo hi
+ is "$output" "" "output should be empty"
+ run_podman --noout rm test
+ is "$output" "" "output should be empty"
+}
+
# Regression test for issue #8082
@test "podman run : look up correct image name" {
# Create a 2nd tag for the local image. Force to lower case, and apply it.
diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats
index e049da518..7dd8f98e8 100644
--- a/test/system/050-stop.bats
+++ b/test/system/050-stop.bats
@@ -173,4 +173,9 @@ load helpers
is "$output" ".*StopSignal SIGTERM failed to stop container stopme in 1 seconds, resorting to SIGKILL" "stopping container should print warning"
}
+@test "podman stop --noout" {
+ run_podman run --rm --name stopme -d $IMAGE top
+ run_podman --noout stop -t 0 stopme
+ is "$output" "" "output should be empty"
+}
# vim: filetype=sh
diff --git a/test/system/080-pause.bats b/test/system/080-pause.bats
index 857c8bbf4..57f390a74 100644
--- a/test/system/080-pause.bats
+++ b/test/system/080-pause.bats
@@ -21,7 +21,8 @@ load helpers
# time to write a new post-restart time value. Pause by CID, unpause
# by name, just to exercise code paths. While paused, check 'ps'
# and 'inspect', then check again after restarting.
- run_podman pause $cid
+ run_podman --noout pause $cid
+ is "$output" "" "output should be empty"
run_podman inspect --format '{{.State.Status}}' $cid
is "$output" "paused" "podman inspect .State.Status"
sleep 3
diff --git a/test/system/090-events.bats b/test/system/090-events.bats
index 5af6a3793..a0b0380a2 100644
--- a/test/system/090-events.bats
+++ b/test/system/090-events.bats
@@ -116,3 +116,16 @@ function _events_disjunctive_filters() {
@test "events with disjunctive filters - default" {
_events_disjunctive_filters ""
}
+
+@test "events with events_logfile_path in containers.conf" {
+ skip_if_remote "remote does not support --events-backend"
+ events_file=$PODMAN_TMPDIR/events.log
+ containersconf=$PODMAN_TMPDIR/containers.conf
+ cat >$containersconf <<EOF
+[engine]
+events_logfile_path="$events_file"
+EOF
+ CONTAINERS_CONF="$containersconf" run_podman --events-backend=file pull $IMAGE
+ run cat $events_file
+ is "$output" ".*\"Name\":\"$IMAGE" "test"
+}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index 6abdf9779..4a3337e57 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -57,7 +57,8 @@ function teardown() {
fi
# Clean up
- run_podman pod rm -f -t 0 $podid
+ run_podman --noout pod rm -f -t 0 $podid
+ is "$output" "" "output should be empty"
}
@@ -330,7 +331,8 @@ EOF
# Note that the internal pause image is built even when --infra-image is
# set to the K8s one.
- run_podman pod create --name $pod_name --infra-name "$infra_name" --infra-image "k8s.gcr.io/pause:3.5"
+ run_podman --noout pod create --name $pod_name --infra-name "$infra_name" --infra-image "k8s.gcr.io/pause:3.5"
+ is "$output" "" "output should be empty"
run_podman '?' pod create --infra-name "$infra_name"
if [ $status -eq 0 ]; then
die "Podman should fail when user try to create two pods with the same infra-name value"
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index c49727cc9..c47679904 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -276,4 +276,9 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
is "$output" ".*--template cannot be set" "Error message should be '--template requires --new'"
}
+@test "podman --cgroup=cgroupfs doesn't show systemd warning" {
+ DBUS_SESSION_BUS_ADDRESS= run_podman --log-level warning --cgroup-manager=cgroupfs info -f ''
+ is "$output" "" "output should be empty"
+}
+
# vim: filetype=sh
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 2b5ad44dc..5a721c965 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -332,7 +332,8 @@ load helpers
is_rootless || skip "only meaningful for rootless"
local mynetname=testnet-$(random_string 10)
- run_podman network create $mynetname
+ run_podman --noout network create $mynetname
+ is "$output" "" "output should be empty"
# Test that rootless cni adds /usr/sbin to $PATH
# iptables is located under /usr/sbin and is needed for the CNI plugins.
@@ -340,7 +341,8 @@ load helpers
PATH=/usr/local/bin:/usr/bin run_podman run --rm --network $mynetname $IMAGE ip addr
is "$output" ".*eth0.*" "Interface eth0 not found in ip addr output"
- run_podman network rm -t 0 -f $mynetname
+ run_podman --noout network rm -t 0 -f $mynetname
+ is "$output" "" "output should be empty"
}
@test "podman ipv6 in /etc/resolv.conf" {