mirror of
https://github.com/containers/podman.git
synced 2025-05-22 01:27:07 +08:00
Merge pull request #9754 from mheon/add_dep
Add --requires flag to podman run/create
This commit is contained in:
@ -576,6 +576,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) {
|
|||||||
`If a container with the same name exists, replace it`,
|
`If a container with the same name exists, replace it`,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
requiresFlagName := "requires"
|
||||||
|
createFlags.StringSliceVar(
|
||||||
|
&cf.Requires,
|
||||||
|
requiresFlagName, []string{},
|
||||||
|
"Add one or more requirement containers that must be started before this container will start",
|
||||||
|
)
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc(requiresFlagName, AutocompleteContainers)
|
||||||
|
|
||||||
restartFlagName := "restart"
|
restartFlagName := "restart"
|
||||||
createFlags.StringVar(
|
createFlags.StringVar(
|
||||||
&cf.Restart,
|
&cf.Restart,
|
||||||
|
@ -93,6 +93,7 @@ type ContainerCLIOpts struct {
|
|||||||
ReadOnlyTmpFS bool
|
ReadOnlyTmpFS bool
|
||||||
Restart string
|
Restart string
|
||||||
Replace bool
|
Replace bool
|
||||||
|
Requires []string
|
||||||
Rm bool
|
Rm bool
|
||||||
RootFS bool
|
RootFS bool
|
||||||
Secrets []string
|
Secrets []string
|
||||||
|
@ -486,6 +486,8 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
|
|||||||
s.ReadOnlyFilesystem = c.ReadOnly
|
s.ReadOnlyFilesystem = c.ReadOnly
|
||||||
s.ConmonPidFile = c.ConmonPIDFile
|
s.ConmonPidFile = c.ConmonPIDFile
|
||||||
|
|
||||||
|
s.DependencyContainers = c.Requires
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// outside of specgen and oci though
|
// outside of specgen and oci though
|
||||||
// defaults to true, check spec/storage
|
// defaults to true, check spec/storage
|
||||||
|
@ -781,6 +781,12 @@ If container is running in --read-only mode, then mount a read-write tmpfs on /r
|
|||||||
|
|
||||||
If another container with the same name already exists, replace and remove it. The default is **false**.
|
If another container with the same name already exists, replace and remove it. The default is **false**.
|
||||||
|
|
||||||
|
#### **\-\-requires**=**container**
|
||||||
|
|
||||||
|
Specify one or more requirements.
|
||||||
|
A requirement is a dependency container that will be started before this container.
|
||||||
|
Containers can be specified by name or ID, with multiple containers being separated by commas.
|
||||||
|
|
||||||
#### **\-\-restart**=*policy*
|
#### **\-\-restart**=*policy*
|
||||||
|
|
||||||
Restart policy to follow when containers exit.
|
Restart policy to follow when containers exit.
|
||||||
@ -1250,6 +1256,25 @@ $ podman create --tz=Asia/Shanghai alpine date
|
|||||||
$ podman create --tz=US/Eastern alpine date
|
$ podman create --tz=US/Eastern alpine date
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Adding dependency containers
|
||||||
|
|
||||||
|
Podman will make sure the first container, container1, is running before the second container (container2) is started.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ podman create --name container1 -t -i fedora bash
|
||||||
|
$ podman create --name container2 --requires container1 -t -i fedora bash
|
||||||
|
$ podman start --attach container2
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple containers can be required.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ podman create --name container1 -t -i fedora bash
|
||||||
|
$ podman create --name container2 -t -i fedora bash
|
||||||
|
$ podman create --name container3 --requires container1,container2 -t -i fedora bash
|
||||||
|
$ podman start --attach container3
|
||||||
|
```
|
||||||
|
|
||||||
### Rootless Containers
|
### Rootless Containers
|
||||||
|
|
||||||
Podman runs as a non root user on most systems. This feature requires that a new enough version of shadow-utils
|
Podman runs as a non root user on most systems. This feature requires that a new enough version of shadow-utils
|
||||||
@ -1297,7 +1322,7 @@ b
|
|||||||
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
|
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**podman**(1), **podman-secret**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-kill**(1), **podman-stop**(1),
|
**podman**(1), **podman-secret**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-start*(1), **podman-kill**(1), **podman-stop**(1),
|
||||||
**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
|
**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
|
||||||
|
|
||||||
## HISTORY
|
## HISTORY
|
||||||
|
@ -825,6 +825,12 @@ If container is running in **\-\-read-only** mode, then mount a read-write tmpfs
|
|||||||
|
|
||||||
If another container with the same name already exists, replace and remove it. The default is **false**.
|
If another container with the same name already exists, replace and remove it. The default is **false**.
|
||||||
|
|
||||||
|
#### **\-\-requires**=**container**
|
||||||
|
|
||||||
|
Specify one or more requirements.
|
||||||
|
A requirement is a dependency container that will be started before this container.
|
||||||
|
Containers can be specified by name or ID, with multiple containers being separated by commas.
|
||||||
|
|
||||||
#### **\-\-restart**=*policy*
|
#### **\-\-restart**=*policy*
|
||||||
|
|
||||||
Restart policy to follow when containers exit.
|
Restart policy to follow when containers exit.
|
||||||
@ -1612,6 +1618,24 @@ $ podman run --tz=Asia/Shanghai alpine date
|
|||||||
$ podman run --tz=US/Eastern alpine date
|
$ podman run --tz=US/Eastern alpine date
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Adding dependency containers
|
||||||
|
|
||||||
|
The first container, container1, is not started initially, but must be running before container2 will start.
|
||||||
|
The `podman run` command will start the container automatically before starting container2.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ podman create --name container1 -t -i fedora bash
|
||||||
|
$ podman run --name container2 --requires container1 -t -i fedora bash
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple containers can be required.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ podman create --name container1 -t -i fedora bash
|
||||||
|
$ podman create --name container2 -t -i fedora bash
|
||||||
|
$ podman run --name container3 --requires container1,container2 -t -i fedora bash
|
||||||
|
```
|
||||||
|
|
||||||
### Rootless Containers
|
### Rootless Containers
|
||||||
|
|
||||||
Podman runs as a non root user on most systems. This feature requires that a new enough version of **shadow-utils**
|
Podman runs as a non root user on most systems. This feature requires that a new enough version of **shadow-utils**
|
||||||
@ -1657,7 +1681,7 @@ b
|
|||||||
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
|
NOTE: Use the environment variable `TMPDIR` to change the temporary storage location of downloaded container images. Podman defaults to use `/var/tmp`.
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**podman**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-kill**(1), **podman-stop**(1),
|
**podman**(1), **podman-save**(1), **podman-ps**(1), **podman-attach**(1), **podman-pod-create**(1), **podman-port**(1), **podman-start**(1), **podman-kill**(1), **podman-stop**(1),
|
||||||
**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
|
**podman-generate-systemd**(1) **podman-rm**(1), **subgid**(5), **subuid**(5), **containers.conf**(5), **systemd.unit**(5), **setsebool**(8), **slirp4netns**(1), **fuse-overlayfs**(1), **proc**(5)**.
|
||||||
|
|
||||||
## HISTORY
|
## HISTORY
|
||||||
|
@ -919,7 +919,7 @@ func (s *BoltState) removeContainer(ctr *Container, pod *Pod, tx *bolt.Tx) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(deps) != 0 {
|
if len(deps) != 0 {
|
||||||
return errors.Wrapf(define.ErrCtrExists, "container %s is a dependency of the following containers: %s", ctr.ID(), strings.Join(deps, ", "))
|
return errors.Wrapf(define.ErrDepExists, "container %s is a dependency of the following containers: %s", ctr.ID(), strings.Join(deps, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ctrBucket.DeleteBucket(ctrID); err != nil {
|
if err := ctrBucket.DeleteBucket(ctrID); err != nil {
|
||||||
|
@ -31,6 +31,10 @@ var (
|
|||||||
// not exist.
|
// not exist.
|
||||||
ErrNoSuchExecSession = errors.New("no such exec session")
|
ErrNoSuchExecSession = errors.New("no such exec session")
|
||||||
|
|
||||||
|
// ErrDepExists indicates that the current object has dependencies and
|
||||||
|
// cannot be removed before them.
|
||||||
|
ErrDepExists = errors.New("dependency exists")
|
||||||
|
|
||||||
// ErrNoAliases indicates that the container does not have any network
|
// ErrNoAliases indicates that the container does not have any network
|
||||||
// aliases.
|
// aliases.
|
||||||
ErrNoAliases = errors.New("no aliases for container")
|
ErrNoAliases = errors.New("no aliases for container")
|
||||||
|
@ -391,7 +391,7 @@ func (s *InMemoryState) RemoveContainer(ctr *Container) error {
|
|||||||
deps, ok := s.ctrDepends[ctr.ID()]
|
deps, ok := s.ctrDepends[ctr.ID()]
|
||||||
if ok && len(deps) != 0 {
|
if ok && len(deps) != 0 {
|
||||||
depsStr := strings.Join(deps, ", ")
|
depsStr := strings.Join(deps, ", ")
|
||||||
return errors.Wrapf(define.ErrCtrExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
|
return errors.Wrapf(define.ErrDepExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we don't have active exec sessions
|
// Ensure we don't have active exec sessions
|
||||||
@ -1497,7 +1497,7 @@ func (s *InMemoryState) RemoveContainerFromPod(pod *Pod, ctr *Container) error {
|
|||||||
deps, ok := s.ctrDepends[ctr.ID()]
|
deps, ok := s.ctrDepends[ctr.ID()]
|
||||||
if ok && len(deps) != 0 {
|
if ok && len(deps) != 0 {
|
||||||
depsStr := strings.Join(deps, ", ")
|
depsStr := strings.Join(deps, ", ")
|
||||||
return errors.Wrapf(define.ErrCtrExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
|
return errors.Wrapf(define.ErrDepExists, "the following containers depend on container %s: %s", ctr.ID(), depsStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure we don't have active exec sessions
|
// Ensure we don't have active exec sessions
|
||||||
|
@ -42,7 +42,7 @@ func StartContainer(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.WriteResponse(w, http.StatusNotModified, nil)
|
utils.WriteResponse(w, http.StatusNotModified, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := con.Start(r.Context(), len(con.PodID()) > 0); err != nil {
|
if err := con.Start(r.Context(), true); err != nil {
|
||||||
utils.InternalServerError(w, err)
|
utils.InternalServerError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,7 @@ type RestartOptions struct {
|
|||||||
// StartOptions are optional options for starting containers
|
// StartOptions are optional options for starting containers
|
||||||
type StartOptions struct {
|
type StartOptions struct {
|
||||||
DetachKeys *string
|
DetachKeys *string
|
||||||
|
Recursive *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:generate go run ../generator/generator.go StatsOptions
|
//go:generate go run ../generator/generator.go StatsOptions
|
||||||
|
@ -35,3 +35,19 @@ func (o *StartOptions) GetDetachKeys() string {
|
|||||||
}
|
}
|
||||||
return *o.DetachKeys
|
return *o.DetachKeys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithRecursive
|
||||||
|
func (o *StartOptions) WithRecursive(value bool) *StartOptions {
|
||||||
|
v := &value
|
||||||
|
o.Recursive = v
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRecursive
|
||||||
|
func (o *StartOptions) GetRecursive() bool {
|
||||||
|
var recursive bool
|
||||||
|
if o.Recursive == nil {
|
||||||
|
return recursive
|
||||||
|
}
|
||||||
|
return *o.Recursive
|
||||||
|
}
|
||||||
|
@ -585,7 +585,7 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrID string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the container is in a pod, also set to recursively start dependencies
|
// If the container is in a pod, also set to recursively start dependencies
|
||||||
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, false, ctr.PodID() != "")
|
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, false)
|
||||||
if err != nil && errors.Cause(err) != define.ErrDetach {
|
if err != nil && errors.Cause(err) != define.ErrDetach {
|
||||||
return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
|
return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
|
||||||
}
|
}
|
||||||
@ -708,7 +708,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
|
|||||||
ctrRunning := ctrState == define.ContainerStateRunning
|
ctrRunning := ctrState == define.ContainerStateRunning
|
||||||
|
|
||||||
if options.Attach {
|
if options.Attach {
|
||||||
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, !ctrRunning, ctr.PodID() != "")
|
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, !ctrRunning)
|
||||||
if errors.Cause(err) == define.ErrDetach {
|
if errors.Cause(err) == define.ErrDetach {
|
||||||
// User manually detached
|
// User manually detached
|
||||||
// Exit cleanly immediately
|
// Exit cleanly immediately
|
||||||
@ -784,7 +784,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
|
|||||||
RawInput: rawInput,
|
RawInput: rawInput,
|
||||||
ExitCode: 125,
|
ExitCode: 125,
|
||||||
}
|
}
|
||||||
if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
|
if err := ctr.Start(ctx, true); err != nil {
|
||||||
// if lastError != nil {
|
// if lastError != nil {
|
||||||
// fmt.Fprintln(os.Stderr, lastError)
|
// fmt.Fprintln(os.Stderr, lastError)
|
||||||
// }
|
// }
|
||||||
@ -845,10 +845,6 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var joinPod bool
|
|
||||||
if len(ctr.PodID()) > 0 {
|
|
||||||
joinPod = true
|
|
||||||
}
|
|
||||||
report := entities.ContainerRunReport{Id: ctr.ID()}
|
report := entities.ContainerRunReport{Id: ctr.ID()}
|
||||||
|
|
||||||
if logrus.GetLevel() == logrus.DebugLevel {
|
if logrus.GetLevel() == logrus.DebugLevel {
|
||||||
@ -859,7 +855,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
}
|
}
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
// if the container was created as part of a pod, also start its dependencies, if any.
|
// if the container was created as part of a pod, also start its dependencies, if any.
|
||||||
if err := ctr.Start(ctx, joinPod); err != nil {
|
if err := ctr.Start(ctx, true); err != nil {
|
||||||
// This means the command did not exist
|
// This means the command did not exist
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(err)
|
||||||
return &report, err
|
return &report, err
|
||||||
@ -869,7 +865,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the container was created as part of a pod, also start its dependencies, if any.
|
// if the container was created as part of a pod, also start its dependencies, if any.
|
||||||
if err := terminal.StartAttachCtr(ctx, ctr, opts.OutputStream, opts.ErrorStream, opts.InputStream, opts.DetachKeys, opts.SigProxy, true, joinPod); err != nil {
|
if err := terminal.StartAttachCtr(ctx, ctr, opts.OutputStream, opts.ErrorStream, opts.InputStream, opts.DetachKeys, opts.SigProxy, true); err != nil {
|
||||||
// We've manually detached from the container
|
// We've manually detached from the container
|
||||||
// Do not perform cleanup, or wait for container exit code
|
// Do not perform cleanup, or wait for container exit code
|
||||||
// Just exit immediately
|
// Just exit immediately
|
||||||
|
@ -39,7 +39,7 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
|
|||||||
// StartAttachCtr starts and (if required) attaches to a container
|
// StartAttachCtr starts and (if required) attaches to a container
|
||||||
// if you change the signature of this function from os.File to io.Writer, it will trigger a downstream
|
// if you change the signature of this function from os.File to io.Writer, it will trigger a downstream
|
||||||
// error. we may need to just lint disable this one.
|
// error. we may need to just lint disable this one.
|
||||||
func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error { //nolint-interfacer
|
func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool) error { //nolint-interfacer
|
||||||
resize := make(chan define.TerminalSize)
|
resize := make(chan define.TerminalSize)
|
||||||
|
|
||||||
haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
|
haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
|
||||||
@ -88,7 +88,7 @@ func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr,
|
|||||||
return ctr.Attach(streams, detachKeys, resize)
|
return ctr.Attach(streams, detachKeys, resize)
|
||||||
}
|
}
|
||||||
|
|
||||||
attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive)
|
attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -629,7 +629,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
|
|||||||
|
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
// Detach and return early
|
// Detach and return early
|
||||||
err := containers.Start(ic.ClientCtx, con.ID, nil)
|
err := containers.Start(ic.ClientCtx, con.ID, new(containers.StartOptions).WithRecursive(true))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
report.ExitCode = define.ExitCode(err)
|
report.ExitCode = define.ExitCode(err)
|
||||||
}
|
}
|
||||||
|
@ -364,6 +364,17 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
|
|||||||
if len(s.Secrets) != 0 {
|
if len(s.Secrets) != 0 {
|
||||||
options = append(options, libpod.WithSecrets(s.Secrets))
|
options = append(options, libpod.WithSecrets(s.Secrets))
|
||||||
}
|
}
|
||||||
|
if len(s.DependencyContainers) > 0 {
|
||||||
|
deps := make([]*libpod.Container, 0, len(s.DependencyContainers))
|
||||||
|
for _, ctr := range s.DependencyContainers {
|
||||||
|
depCtr, err := rt.LookupContainer(ctr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "%q is not a valid container, cannot be used as a dependency", ctr)
|
||||||
|
}
|
||||||
|
deps = append(deps, depCtr)
|
||||||
|
}
|
||||||
|
options = append(options, libpod.WithDependencyCtrs(deps))
|
||||||
|
}
|
||||||
return options, nil
|
return options, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,10 +160,17 @@ type ContainerBasicConfig struct {
|
|||||||
// to 0, 1, 2) that will be passed to the executed process. The total FDs
|
// to 0, 1, 2) that will be passed to the executed process. The total FDs
|
||||||
// passed will be 3 + PreserveFDs.
|
// passed will be 3 + PreserveFDs.
|
||||||
// set tags as `json:"-"` for not supported remote
|
// set tags as `json:"-"` for not supported remote
|
||||||
|
// Optional.
|
||||||
PreserveFDs uint `json:"-"`
|
PreserveFDs uint `json:"-"`
|
||||||
// Timezone is the timezone inside the container.
|
// Timezone is the timezone inside the container.
|
||||||
// Local means it has the same timezone as the host machine
|
// Local means it has the same timezone as the host machine
|
||||||
|
// Optional.
|
||||||
Timezone string `json:"timezone,omitempty"`
|
Timezone string `json:"timezone,omitempty"`
|
||||||
|
// DependencyContainers is an array of containers this container
|
||||||
|
// depends on. Dependency containers must be started before this
|
||||||
|
// container. Dependencies can be specified by name or full/partial ID.
|
||||||
|
// Optional.
|
||||||
|
DependencyContainers []string `json:"dependencyContainers,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStorageConfig contains information on the storage configuration of a
|
// ContainerStorageConfig contains information on the storage configuration of a
|
||||||
|
@ -1588,4 +1588,29 @@ WORKDIR /madethis`, BB)
|
|||||||
Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
|
Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman run --requires", func() {
|
||||||
|
depName := "ctr1"
|
||||||
|
depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"})
|
||||||
|
depContainer.WaitWithDefaultTimeout()
|
||||||
|
Expect(depContainer.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
mainName := "ctr2"
|
||||||
|
mainContainer := podmanTest.Podman([]string{"run", "--name", mainName, "--requires", depName, "-d", ALPINE, "top"})
|
||||||
|
mainContainer.WaitWithDefaultTimeout()
|
||||||
|
Expect(mainContainer.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
stop := podmanTest.Podman([]string{"stop", "--all"})
|
||||||
|
stop.WaitWithDefaultTimeout()
|
||||||
|
Expect(stop.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
start := podmanTest.Podman([]string{"start", mainName})
|
||||||
|
start.WaitWithDefaultTimeout()
|
||||||
|
Expect(start.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
running := podmanTest.Podman([]string{"ps", "-q"})
|
||||||
|
running.WaitWithDefaultTimeout()
|
||||||
|
Expect(running.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(running.OutputToStringArray())).To(Equal(2))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user