mirror of
https://github.com/containers/podman.git
synced 2025-07-03 17:27:18 +08:00
Merge pull request #10041 from chenk008/add_pidfile_flag
Add flag "--pidfile" for podman create/run
This commit is contained in:
@ -817,6 +817,13 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
|
||||
)
|
||||
_ = 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")
|
||||
if registry.IsRemote() {
|
||||
_ = createFlags.MarkHidden("env-host")
|
||||
|
@ -122,6 +122,7 @@ type ContainerCLIOpts struct {
|
||||
VolumesFrom []string
|
||||
Workdir string
|
||||
SeccompPolicy string
|
||||
PidFile string
|
||||
|
||||
Net *entities.NetOptions
|
||||
|
||||
|
@ -644,6 +644,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
||||
s.Timezone = c.Timezone
|
||||
s.Umask = c.Umask
|
||||
s.Secrets = c.Secrets
|
||||
s.PidFile = c.PidFile
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -63,6 +63,11 @@ func createFlags(cmd *cobra.Command) {
|
||||
common.DefineNetFlags(cmd)
|
||||
|
||||
flags.SetNormalizeFunc(utils.AliasFlags)
|
||||
|
||||
if registry.IsRemote() {
|
||||
_ = flags.MarkHidden("conmon-pidfile")
|
||||
_ = flags.MarkHidden("pidfile")
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -76,8 +76,11 @@ func runFlags(cmd *cobra.Command) {
|
||||
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 `_`")
|
||||
_ = cmd.RegisterFlagCompletionFunc(detachKeysFlagName, common.AutocompleteDetachKeys)
|
||||
|
||||
if registry.IsRemote() {
|
||||
_ = 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*
|
||||
|
||||
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*
|
||||
|
||||
@ -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
|
||||
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
|
||||
|
||||
### Create a container using a local image
|
||||
|
@ -167,6 +167,7 @@ Write the container ID to *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.
|
||||
(This option is not available with the remote Podman client)
|
||||
|
||||
#### **\-\-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
|
||||
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
|
||||
|
||||
The exit code from **podman run** gives information about why the container
|
||||
|
@ -364,4 +364,6 @@ type ContainerMiscConfig struct {
|
||||
Timezone string `json:"timezone,omitempty"`
|
||||
// Umask is the umask inside the container.
|
||||
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,
|
||||
OCIRuntime: config.OCIRuntime,
|
||||
ConmonPidFile: config.ConmonPidFile,
|
||||
PidFile: config.PidFile,
|
||||
Name: config.Name,
|
||||
RestartCount: int32(runtimeInfo.RestartCount),
|
||||
Driver: driverData.Name,
|
||||
|
@ -627,6 +627,7 @@ type InspectContainerData struct {
|
||||
OCIConfigPath string `json:"OCIConfigPath,omitempty"`
|
||||
OCIRuntime string `json:"OCIRuntime,omitempty"`
|
||||
ConmonPidFile string `json:"ConmonPidFile"`
|
||||
PidFile string `json:"PidFile"`
|
||||
Name string `json:"Name"`
|
||||
RestartCount int32 `json:"RestartCount"`
|
||||
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 {
|
||||
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
|
||||
|
||||
// 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 = ""
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
@ -366,6 +373,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
||||
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.
|
||||
// If they don't exist they will be created using basic options.
|
||||
// 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))
|
||||
}
|
||||
if s.PidFile != "" {
|
||||
options = append(options, libpod.WithPidFile(s.PidFile))
|
||||
}
|
||||
return options, nil
|
||||
}
|
||||
|
||||
|
@ -171,6 +171,10 @@ type ContainerBasicConfig struct {
|
||||
// container. Dependencies can be specified by name or full/partial ID.
|
||||
// Optional.
|
||||
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
|
||||
|
@ -508,4 +508,14 @@ var _ = Describe("Podman inspect", func() {
|
||||
Expect(data[0].HostConfig.CapDrop[1]).To(Equal("CAP_MKNOD"))
|
||||
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(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
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
. "github.com/containers/podman/v3/test/utils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
@ -206,4 +209,25 @@ var _ = Describe("Podman start", func() {
|
||||
session.WaitWithDefaultTimeout()
|
||||
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())
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user