aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@pm.me>2021-03-18 12:45:09 -0400
committerMatthew Heon <matthew.heon@pm.me>2021-04-06 14:01:31 -0400
commit6acd265306370ab5cfeaf2843bd359fe13216d92 (patch)
tree4ee6cb44d495be5791c144c26f59849729539cb9 /pkg
parentf7ad9fbd9e334b5daf9f3af9160cc8fab82255d6 (diff)
downloadpodman-6acd265306370ab5cfeaf2843bd359fe13216d92.tar.gz
podman-6acd265306370ab5cfeaf2843bd359fe13216d92.tar.bz2
podman-6acd265306370ab5cfeaf2843bd359fe13216d92.zip
Add --requires flag to podman run/create
Podman has, for a long time, had an internal concept of dependency management, used mainly to ensure that pod infra containers are started before any other container in the pod. We also have the ability to recursively start these dependencies, which we use to ensure that `podman start` on a container in a pod will not fail because the infra container is stopped. We have not, however, exposed these via the command line until now. Add a `--requires` flag to `podman run` and `podman create` to allow users to manually specify dependency containers. These containers must be running before the container will start. Also, make recursive starting with `podman start` default so we can start these containers and their dependencies easily. Fixes #9250 Signed-off-by: Matthew Heon <matthew.heon@pm.me>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/api/handlers/compat/containers_start.go2
-rw-r--r--pkg/bindings/containers/types.go1
-rw-r--r--pkg/bindings/containers/types_start_options.go16
-rw-r--r--pkg/domain/infra/abi/containers.go14
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go4
-rw-r--r--pkg/domain/infra/tunnel/containers.go2
-rw-r--r--pkg/specgen/generate/container_create.go11
-rw-r--r--pkg/specgen/specgen.go7
8 files changed, 44 insertions, 13 deletions
diff --git a/pkg/api/handlers/compat/containers_start.go b/pkg/api/handlers/compat/containers_start.go
index 391aa752d..f1ed1b2b8 100644
--- a/pkg/api/handlers/compat/containers_start.go
+++ b/pkg/api/handlers/compat/containers_start.go
@@ -42,7 +42,7 @@ func StartContainer(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusNotModified, nil)
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)
return
}
diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go
index f63e35bf1..0d22c32f8 100644
--- a/pkg/bindings/containers/types.go
+++ b/pkg/bindings/containers/types.go
@@ -154,6 +154,7 @@ type RestartOptions struct {
// StartOptions are optional options for starting containers
type StartOptions struct {
DetachKeys *string
+ Recursive *bool
}
//go:generate go run ../generator/generator.go StatsOptions
diff --git a/pkg/bindings/containers/types_start_options.go b/pkg/bindings/containers/types_start_options.go
index f8ba29623..d419c755c 100644
--- a/pkg/bindings/containers/types_start_options.go
+++ b/pkg/bindings/containers/types_start_options.go
@@ -35,3 +35,19 @@ func (o *StartOptions) GetDetachKeys() string {
}
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
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 637531ee9..3fe9ef637 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -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
- 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 {
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
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 {
// User manually detached
// Exit cleanly immediately
@@ -784,7 +784,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
RawInput: rawInput,
ExitCode: 125,
}
- if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
+ if err := ctr.Start(ctx, true); err != nil {
// if lastError != nil {
// 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()}
if logrus.GetLevel() == logrus.DebugLevel {
@@ -859,7 +855,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
}
if opts.Detach {
// 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
report.ExitCode = define.ExitCode(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 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
// Do not perform cleanup, or wait for container exit code
// Just exit immediately
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
index 7a0c2907c..ab71f8f6f 100644
--- a/pkg/domain/infra/abi/terminal/terminal_linux.go
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -39,7 +39,7 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpo
// 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
// 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)
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)
}
- attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive)
+ attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, true)
if err != nil {
return err
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index a0f65f11f..4545d266b 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -629,7 +629,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
if opts.Detach {
// 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 {
report.ExitCode = define.ExitCode(err)
}
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 1d724ffb0..ef9975021 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -364,6 +364,17 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if len(s.Secrets) != 0 {
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
}
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index c10dc5ef5..28111f96d 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -160,10 +160,17 @@ type ContainerBasicConfig struct {
// to 0, 1, 2) that will be passed to the executed process. The total FDs
// passed will be 3 + PreserveFDs.
// set tags as `json:"-"` for not supported remote
+ // Optional.
PreserveFDs uint `json:"-"`
// Timezone is the timezone inside the container.
// Local means it has the same timezone as the host machine
+ // Optional.
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