mirror of https://github.com/containers/podman.git
Merge pull request #10041 from chenk008/add_pidfile_flag
Add flag "--pidfile" for podman create/run
This commit is contained in:
commit
a94360a3f7
|
@ -817,6 +817,13 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
|
||||||
)
|
)
|
||||||
_ = cmd.RegisterFlagCompletionFunc(cgroupConfFlagName, completion.AutocompleteNone)
|
_ = cmd.RegisterFlagCompletionFunc(cgroupConfFlagName, completion.AutocompleteNone)
|
||||||
|
|
||||||
|
pidFileFlagName := "pidfile"
|
||||||
|
createFlags.StringVar(
|
||||||
|
&cf.PidFile,
|
||||||
|
pidFileFlagName, "",
|
||||||
|
"Write the container process ID to the file")
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(pidFileFlagName, completion.AutocompleteDefault)
|
||||||
|
|
||||||
_ = createFlags.MarkHidden("signature-policy")
|
_ = createFlags.MarkHidden("signature-policy")
|
||||||
if registry.IsRemote() {
|
if registry.IsRemote() {
|
||||||
_ = createFlags.MarkHidden("env-host")
|
_ = createFlags.MarkHidden("env-host")
|
||||||
|
|
|
@ -122,6 +122,7 @@ type ContainerCLIOpts struct {
|
||||||
VolumesFrom []string
|
VolumesFrom []string
|
||||||
Workdir string
|
Workdir string
|
||||||
SeccompPolicy string
|
SeccompPolicy string
|
||||||
|
PidFile string
|
||||||
|
|
||||||
Net *entities.NetOptions
|
Net *entities.NetOptions
|
||||||
|
|
||||||
|
|
|
@ -644,6 +644,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||||
s.Timezone = c.Timezone
|
s.Timezone = c.Timezone
|
||||||
s.Umask = c.Umask
|
s.Umask = c.Umask
|
||||||
s.Secrets = c.Secrets
|
s.Secrets = c.Secrets
|
||||||
|
s.PidFile = c.PidFile
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,11 @@ func createFlags(cmd *cobra.Command) {
|
||||||
common.DefineNetFlags(cmd)
|
common.DefineNetFlags(cmd)
|
||||||
|
|
||||||
flags.SetNormalizeFunc(utils.AliasFlags)
|
flags.SetNormalizeFunc(utils.AliasFlags)
|
||||||
|
|
||||||
|
if registry.IsRemote() {
|
||||||
|
_ = flags.MarkHidden("conmon-pidfile")
|
||||||
|
_ = flags.MarkHidden("pidfile")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
@ -76,8 +76,11 @@ func runFlags(cmd *cobra.Command) {
|
||||||
detachKeysFlagName := "detach-keys"
|
detachKeysFlagName := "detach-keys"
|
||||||
flags.StringVar(&runOpts.DetachKeys, detachKeysFlagName, containerConfig.DetachKeys(), "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
|
flags.StringVar(&runOpts.DetachKeys, detachKeysFlagName, containerConfig.DetachKeys(), "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\\`, `]`, `^` or `_`")
|
||||||
_ = cmd.RegisterFlagCompletionFunc(detachKeysFlagName, common.AutocompleteDetachKeys)
|
_ = cmd.RegisterFlagCompletionFunc(detachKeysFlagName, common.AutocompleteDetachKeys)
|
||||||
|
|
||||||
if registry.IsRemote() {
|
if registry.IsRemote() {
|
||||||
_ = flags.MarkHidden("preserve-fds")
|
_ = flags.MarkHidden("preserve-fds")
|
||||||
|
_ = flags.MarkHidden("conmon-pidfile")
|
||||||
|
_ = flags.MarkHidden("pidfile")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,7 @@ Write the container ID to the file
|
||||||
#### **\-\-conmon-pidfile**=*path*
|
#### **\-\-conmon-pidfile**=*path*
|
||||||
|
|
||||||
Write the pid of the `conmon` process to a file. `conmon` runs in a separate process than Podman, so this is necessary when using systemd to restart Podman containers.
|
Write the pid of the `conmon` process to a file. `conmon` runs in a separate process than Podman, so this is necessary when using systemd to restart Podman containers.
|
||||||
|
(This option is not available with the remote Podman client)
|
||||||
|
|
||||||
#### **\-\-cpu-period**=*limit*
|
#### **\-\-cpu-period**=*limit*
|
||||||
|
|
||||||
|
@ -1224,6 +1225,17 @@ The default working directory for running binaries within a container is the roo
|
||||||
The image developer can set a different default with the WORKDIR instruction. The operator
|
The image developer can set a different default with the WORKDIR instruction. The operator
|
||||||
can override the working directory by using the **-w** option.
|
can override the working directory by using the **-w** option.
|
||||||
|
|
||||||
|
#### **\-\-pidfile**=*path*
|
||||||
|
|
||||||
|
When the pidfile location is specified, the container process' PID will be written to the pidfile. (This option is not available with the remote Podman client)
|
||||||
|
If the pidfile option is not specified, the container process' PID will be written to /run/containers/storage/${storage-driver}-containers/$CID/userdata/pidfile.
|
||||||
|
|
||||||
|
After the container is started, the location for the pidfile can be discovered with the following `podman inspect` command:
|
||||||
|
|
||||||
|
$ podman inspect --format '{{ .PidFile }}' $CID
|
||||||
|
/run/containers/storage/${storage-driver}-containers/$CID/userdata/pidfile
|
||||||
|
|
||||||
|
|
||||||
## EXAMPLES
|
## EXAMPLES
|
||||||
|
|
||||||
### Create a container using a local image
|
### Create a container using a local image
|
||||||
|
|
|
@ -167,6 +167,7 @@ Write the container ID to *file*.
|
||||||
#### **\-\-conmon-pidfile**=*file*
|
#### **\-\-conmon-pidfile**=*file*
|
||||||
|
|
||||||
Write the pid of the **conmon** process to a file. As **conmon** runs in a separate process than Podman, this is necessary when using systemd to restart Podman containers.
|
Write the pid of the **conmon** process to a file. As **conmon** runs in a separate process than Podman, this is necessary when using systemd to restart Podman containers.
|
||||||
|
(This option is not available with the remote Podman client)
|
||||||
|
|
||||||
#### **\-\-cpu-period**=*limit*
|
#### **\-\-cpu-period**=*limit*
|
||||||
|
|
||||||
|
@ -1305,6 +1306,16 @@ The default working directory for running binaries within a container is the roo
|
||||||
The image developer can set a different default with the WORKDIR instruction. The operator
|
The image developer can set a different default with the WORKDIR instruction. The operator
|
||||||
can override the working directory by using the **-w** option.
|
can override the working directory by using the **-w** option.
|
||||||
|
|
||||||
|
#### **\-\-pidfile**=*path*
|
||||||
|
|
||||||
|
When the pidfile location is specified, the container process' PID will be written to the pidfile. (This option is not available with the remote Podman client)
|
||||||
|
If the pidfile option is not specified, the container process' PID will be written to /run/containers/storage/${storage-driver}-containers/$CID/userdata/pidfile.
|
||||||
|
|
||||||
|
After the container is started, the location for the pidfile can be discovered with the following `podman inspect` command:
|
||||||
|
|
||||||
|
$ podman inspect --format '{{ .PidFile }}' $CID
|
||||||
|
/run/containers/storage/${storage-driver}-containers/$CID/userdata/pidfile
|
||||||
|
|
||||||
## Exit Status
|
## Exit Status
|
||||||
|
|
||||||
The exit code from **podman run** gives information about why the container
|
The exit code from **podman run** gives information about why the container
|
||||||
|
|
|
@ -364,4 +364,6 @@ type ContainerMiscConfig struct {
|
||||||
Timezone string `json:"timezone,omitempty"`
|
Timezone string `json:"timezone,omitempty"`
|
||||||
// Umask is the umask inside the container.
|
// Umask is the umask inside the container.
|
||||||
Umask string `json:"umask,omitempty"`
|
Umask string `json:"umask,omitempty"`
|
||||||
|
// PidFile is the file that saves the pid of the container process
|
||||||
|
PidFile string `json:"pid_file,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver
|
||||||
StaticDir: config.StaticDir,
|
StaticDir: config.StaticDir,
|
||||||
OCIRuntime: config.OCIRuntime,
|
OCIRuntime: config.OCIRuntime,
|
||||||
ConmonPidFile: config.ConmonPidFile,
|
ConmonPidFile: config.ConmonPidFile,
|
||||||
|
PidFile: config.PidFile,
|
||||||
Name: config.Name,
|
Name: config.Name,
|
||||||
RestartCount: int32(runtimeInfo.RestartCount),
|
RestartCount: int32(runtimeInfo.RestartCount),
|
||||||
Driver: driverData.Name,
|
Driver: driverData.Name,
|
||||||
|
|
|
@ -627,6 +627,7 @@ type InspectContainerData struct {
|
||||||
OCIConfigPath string `json:"OCIConfigPath,omitempty"`
|
OCIConfigPath string `json:"OCIConfigPath,omitempty"`
|
||||||
OCIRuntime string `json:"OCIRuntime,omitempty"`
|
OCIRuntime string `json:"OCIRuntime,omitempty"`
|
||||||
ConmonPidFile string `json:"ConmonPidFile"`
|
ConmonPidFile string `json:"ConmonPidFile"`
|
||||||
|
PidFile string `json:"PidFile"`
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
RestartCount int32 `json:"RestartCount"`
|
RestartCount int32 `json:"RestartCount"`
|
||||||
Driver string `json:"Driver"`
|
Driver string `json:"Driver"`
|
||||||
|
|
|
@ -1025,7 +1025,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
args := r.sharedConmonArgs(ctr, ctr.ID(), ctr.bundlePath(), filepath.Join(ctr.state.RunDir, "pidfile"), ctr.LogPath(), r.exitsDir, ociLog, ctr.LogDriver(), logTag)
|
args := r.sharedConmonArgs(ctr, ctr.ID(), ctr.bundlePath(), ctr.config.PidFile, ctr.LogPath(), r.exitsDir, ociLog, ctr.LogDriver(), logTag)
|
||||||
|
|
||||||
if ctr.config.Spec.Process.Terminal {
|
if ctr.config.Spec.Process.Terminal {
|
||||||
args = append(args, "-t")
|
args = append(args, "-t")
|
||||||
|
|
|
@ -1692,6 +1692,17 @@ func WithSecrets(secretNames []string) CtrCreateOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithPidFile adds pidFile to the container
|
||||||
|
func WithPidFile(pidFile string) CtrCreateOption {
|
||||||
|
return func(ctr *Container) error {
|
||||||
|
if ctr.valid {
|
||||||
|
return define.ErrCtrFinalized
|
||||||
|
}
|
||||||
|
ctr.config.PidFile = pidFile
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pod Creation Options
|
// Pod Creation Options
|
||||||
|
|
||||||
// WithInfraImage sets the infra image for libpod.
|
// WithInfraImage sets the infra image for libpod.
|
||||||
|
|
|
@ -69,6 +69,13 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config
|
||||||
ctr.config.ConmonPidFile = ""
|
ctr.config.ConmonPidFile = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the path to PidFile starts with the default value (RunRoot), then
|
||||||
|
// the user has not specified '--pidfile' during run or create (probably).
|
||||||
|
// In that case reset PidFile to be set to the default value later.
|
||||||
|
if strings.HasPrefix(ctr.config.PidFile, r.storageConfig.RunRoot) {
|
||||||
|
ctr.config.PidFile = ""
|
||||||
|
}
|
||||||
|
|
||||||
return r.setupContainer(ctx, ctr)
|
return r.setupContainer(ctx, ctr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,6 +373,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||||
ctr.config.ConmonPidFile = filepath.Join(ctr.state.RunDir, "conmon.pid")
|
ctr.config.ConmonPidFile = filepath.Join(ctr.state.RunDir, "conmon.pid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctr.config.PidFile == "" {
|
||||||
|
ctr.config.PidFile = filepath.Join(ctr.state.RunDir, "pidfile")
|
||||||
|
}
|
||||||
|
|
||||||
// Go through named volumes and add them.
|
// Go through named volumes and add them.
|
||||||
// If they don't exist they will be created using basic options.
|
// If they don't exist they will be created using basic options.
|
||||||
// Maintain an array of them - we need to lock them later.
|
// Maintain an array of them - we need to lock them later.
|
||||||
|
|
|
@ -375,6 +375,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
|
||||||
}
|
}
|
||||||
options = append(options, libpod.WithDependencyCtrs(deps))
|
options = append(options, libpod.WithDependencyCtrs(deps))
|
||||||
}
|
}
|
||||||
|
if s.PidFile != "" {
|
||||||
|
options = append(options, libpod.WithPidFile(s.PidFile))
|
||||||
|
}
|
||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,6 +171,10 @@ type ContainerBasicConfig struct {
|
||||||
// container. Dependencies can be specified by name or full/partial ID.
|
// container. Dependencies can be specified by name or full/partial ID.
|
||||||
// Optional.
|
// Optional.
|
||||||
DependencyContainers []string `json:"dependencyContainers,omitempty"`
|
DependencyContainers []string `json:"dependencyContainers,omitempty"`
|
||||||
|
// PidFile is the file that saves container process id.
|
||||||
|
// set tags as `json:"-"` for not supported remote
|
||||||
|
// Optional.
|
||||||
|
PidFile string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStorageConfig contains information on the storage configuration of a
|
// ContainerStorageConfig contains information on the storage configuration of a
|
||||||
|
|
|
@ -508,4 +508,14 @@ var _ = Describe("Podman inspect", func() {
|
||||||
Expect(data[0].HostConfig.CapDrop[1]).To(Equal("CAP_MKNOD"))
|
Expect(data[0].HostConfig.CapDrop[1]).To(Equal("CAP_MKNOD"))
|
||||||
Expect(data[0].HostConfig.CapDrop[2]).To(Equal("CAP_NET_RAW"))
|
Expect(data[0].HostConfig.CapDrop[2]).To(Equal("CAP_NET_RAW"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman inspect container with GO format for PidFile", func() {
|
||||||
|
SkipIfRemote("pidfile not handled by remote")
|
||||||
|
session, ec, _ := podmanTest.RunLsContainer("test1")
|
||||||
|
Expect(ec).To(Equal(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"inspect", "--format", "{{.PidFile}}", "test1"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1613,4 +1613,20 @@ WORKDIR /madethis`, BB)
|
||||||
Expect(running.ExitCode()).To(Equal(0))
|
Expect(running.ExitCode()).To(Equal(0))
|
||||||
Expect(len(running.OutputToStringArray())).To(Equal(2))
|
Expect(len(running.OutputToStringArray())).To(Equal(2))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman run with pidfile", func() {
|
||||||
|
SkipIfRemote("pidfile not handled by remote")
|
||||||
|
pidfile := tempdir + "pidfile"
|
||||||
|
session := podmanTest.Podman([]string{"run", "--pidfile", pidfile, ALPINE, "ls"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
readFirstLine := func(path string) string {
|
||||||
|
content, err := ioutil.ReadFile(path)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
return strings.Split(string(content), "\n")[0]
|
||||||
|
}
|
||||||
|
containerPID := readFirstLine(pidfile)
|
||||||
|
_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/containers/podman/v3/test/utils"
|
. "github.com/containers/podman/v3/test/utils"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
|
@ -206,4 +209,25 @@ var _ = Describe("Podman start", func() {
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(Exit(125))
|
Expect(session).Should(Exit(125))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman start container with special pidfile", func() {
|
||||||
|
SkipIfRemote("pidfile not handled by remote")
|
||||||
|
pidfile := tempdir + "pidfile"
|
||||||
|
session := podmanTest.Podman([]string{"create", "--pidfile", pidfile, ALPINE, "ls"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
cid := session.OutputToString()
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"start", cid})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
readFirstLine := func(path string) string {
|
||||||
|
content, err := ioutil.ReadFile(path)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
return strings.Split(string(content), "\n")[0]
|
||||||
|
}
|
||||||
|
containerPID := readFirstLine(pidfile)
|
||||||
|
_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue