diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/libpod/healthcheck.go | 24 | ||||
-rw-r--r-- | pkg/domain/entities/containers.go | 2 | ||||
-rw-r--r-- | pkg/domain/entities/engine_container.go | 3 | ||||
-rw-r--r-- | pkg/domain/infra/abi/containers.go | 84 | ||||
-rw-r--r-- | pkg/domain/infra/abi/healthcheck.go | 7 | ||||
-rw-r--r-- | pkg/domain/infra/abi/terminal/terminal_linux.go | 14 | ||||
-rw-r--r-- | pkg/domain/infra/tunnel/containers.go | 12 | ||||
-rw-r--r-- | pkg/specgen/generate/container_create.go | 21 | ||||
-rw-r--r-- | pkg/util/mountOpts_linux.go | 2 | ||||
-rw-r--r-- | pkg/varlinkapi/containers.go | 8 |
10 files changed, 129 insertions, 48 deletions
diff --git a/pkg/api/handlers/libpod/healthcheck.go b/pkg/api/handlers/libpod/healthcheck.go index 6eb2ab0e3..0ca3574b7 100644 --- a/pkg/api/handlers/libpod/healthcheck.go +++ b/pkg/api/handlers/libpod/healthcheck.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/api/handlers/utils" ) @@ -12,32 +13,27 @@ func RunHealthCheck(w http.ResponseWriter, r *http.Request) { name := utils.GetName(r) status, err := runtime.HealthCheck(name) if err != nil { - if status == libpod.HealthCheckContainerNotFound { + if status == define.HealthCheckContainerNotFound { utils.ContainerNotFound(w, name, err) return } - if status == libpod.HealthCheckNotDefined { + if status == define.HealthCheckNotDefined { utils.Error(w, "no healthcheck defined", http.StatusConflict, err) return } - if status == libpod.HealthCheckContainerStopped { + if status == define.HealthCheckContainerStopped { utils.Error(w, "container not running", http.StatusConflict, err) return } utils.InternalServerError(w, err) return } - ctr, err := runtime.LookupContainer(name) - if err != nil { - utils.InternalServerError(w, err) - return + hcStatus := define.HealthCheckUnhealthy + if status == define.HealthCheckSuccess { + hcStatus = define.HealthCheckHealthy } - - hcLog, err := ctr.GetHealthCheckLog() - if err != nil { - utils.InternalServerError(w, err) - return + report := define.HealthCheckResults{ + Status: hcStatus, } - - utils.WriteResponse(w, http.StatusOK, hcLog) + utils.WriteResponse(w, http.StatusOK, report) } diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go index 3cc4b6db1..8d85a9b23 100644 --- a/pkg/domain/entities/containers.go +++ b/pkg/domain/entities/containers.go @@ -242,7 +242,6 @@ type ExecOptions struct { Latest bool PreserveFDs uint Privileged bool - Streams define.AttachStreams Tty bool User string WorkDir string @@ -311,6 +310,7 @@ type ContainerRunReport struct { // cleanup command type ContainerCleanupOptions struct { All bool + Exec string Latest bool Remove bool RemoveImage bool diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go index e77f0758b..3d5161745 100644 --- a/pkg/domain/entities/engine_container.go +++ b/pkg/domain/entities/engine_container.go @@ -19,7 +19,8 @@ type ContainerEngine interface { ContainerCp(ctx context.Context, source, dest string, options ContainerCpOptions) (*ContainerCpReport, error) ContainerCreate(ctx context.Context, s *specgen.SpecGenerator) (*ContainerCreateReport, error) ContainerDiff(ctx context.Context, nameOrId string, options DiffOptions) (*DiffReport, error) - ContainerExec(ctx context.Context, nameOrId string, options ExecOptions) (int, error) + ContainerExec(ctx context.Context, nameOrId string, options ExecOptions, streams define.AttachStreams) (int, error) + ContainerExecDetached(ctx context.Context, nameOrID string, options ExecOptions) (string, error) ContainerExists(ctx context.Context, nameOrId string) (*BoolReport, error) ContainerExport(ctx context.Context, nameOrId string, options ContainerExportOptions) error ContainerInit(ctx context.Context, namesOrIds []string, options ContainerInitOptions) ([]*ContainerInitReport, error) diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index 035efe575..b4e38ca23 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -536,7 +536,22 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, return nil } -func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { +func makeExecConfig(options entities.ExecOptions) *libpod.ExecConfig { + execConfig := new(libpod.ExecConfig) + execConfig.Command = options.Cmd + execConfig.Terminal = options.Tty + execConfig.Privileged = options.Privileged + execConfig.Environment = options.Envs + execConfig.User = options.User + execConfig.WorkDir = options.WorkDir + execConfig.DetachKeys = &options.DetachKeys + execConfig.PreserveFDs = options.PreserveFDs + execConfig.AttachStdin = options.Interactive + + return execConfig +} + +func checkExecPreserveFDs(options entities.ExecOptions) (int, error) { ec := define.ExecErrorCodeGeneric if options.PreserveFDs > 0 { entries, err := ioutil.ReadDir("/proc/self/fd") @@ -559,15 +574,66 @@ func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, o } } } + return ec, nil +} + +func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions, streams define.AttachStreams) (int, error) { + ec, err := checkExecPreserveFDs(options) + if err != nil { + return ec, err + } ctrs, err := getContainersByContext(false, options.Latest, []string{nameOrId}, ic.Libpod) if err != nil { return ec, err } ctr := ctrs[0] - ec, err = terminal.ExecAttachCtr(ctx, ctr, options.Tty, options.Privileged, options.Envs, options.Cmd, options.User, options.WorkDir, &options.Streams, options.PreserveFDs, options.DetachKeys) + + execConfig := makeExecConfig(options) + + ec, err = terminal.ExecAttachCtr(ctx, ctr, execConfig, &streams) return define.TranslateExecErrorToExitCode(ec, err), err } +func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrId string, options entities.ExecOptions) (string, error) { + _, err := checkExecPreserveFDs(options) + if err != nil { + return "", err + } + ctrs, err := getContainersByContext(false, options.Latest, []string{nameOrId}, ic.Libpod) + if err != nil { + return "", err + } + ctr := ctrs[0] + + execConfig := makeExecConfig(options) + + // Make an exit command + storageConfig := ic.Libpod.StorageConfig() + runtimeConfig, err := ic.Libpod.GetConfig() + if err != nil { + return "", errors.Wrapf(err, "error retrieving Libpod configuration to build exec exit command") + } + podmanPath, err := os.Executable() + if err != nil { + return "", errors.Wrapf(err, "error retrieving executable to build exec exit command") + } + // TODO: Add some ability to toggle syslog + exitCommandArgs := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, podmanPath, false, true, true) + execConfig.ExitCommand = exitCommandArgs + + // Create and start the exec session + id, err := ctr.ExecCreate(execConfig) + if err != nil { + return "", err + } + + // TODO: we should try and retrieve exit code if this fails. + if err := ctr.ExecStart(id); err != nil { + return "", err + } + return id, nil +} + func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) { var reports []*entities.ContainerStartReport var exitCode = define.ExecErrorCodeGeneric @@ -836,6 +902,20 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st for _, ctr := range ctrs { var err error report := entities.ContainerCleanupReport{Id: ctr.ID()} + + if options.Exec != "" { + if options.Remove { + if err := ctr.ExecRemove(options.Exec, false); err != nil { + return nil, err + } + } else { + if err := ctr.ExecCleanup(options.Exec); err != nil { + return nil, err + } + } + return []*entities.ContainerCleanupReport{}, nil + } + if options.Remove { err = ic.Libpod.RemoveContainer(ctx, ctr, false, true) if err != nil { diff --git a/pkg/domain/infra/abi/healthcheck.go b/pkg/domain/infra/abi/healthcheck.go index 351bf4f7e..4e925ef56 100644 --- a/pkg/domain/infra/abi/healthcheck.go +++ b/pkg/domain/infra/abi/healthcheck.go @@ -3,7 +3,6 @@ package abi import ( "context" - "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/domain/entities" ) @@ -13,9 +12,9 @@ func (ic *ContainerEngine) HealthCheckRun(ctx context.Context, nameOrId string, if err != nil { return nil, err } - hcStatus := "unhealthy" - if status == libpod.HealthCheckSuccess { - hcStatus = "healthy" + hcStatus := define.HealthCheckUnhealthy + if status == define.HealthCheckSuccess { + hcStatus = define.HealthCheckHealthy } report := define.HealthCheckResults{ Status: hcStatus, diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go index 15701342f..8d9cdde03 100644 --- a/pkg/domain/infra/abi/terminal/terminal_linux.go +++ b/pkg/domain/infra/abi/terminal/terminal_linux.go @@ -15,13 +15,13 @@ import ( ) // ExecAttachCtr execs and attaches to a container -func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged bool, env map[string]string, cmd []string, user, workDir string, streams *define.AttachStreams, preserveFDs uint, detachKeys string) (int, error) { +func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, execConfig *libpod.ExecConfig, streams *define.AttachStreams) (int, error) { resize := make(chan remotecommand.TerminalSize) haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd())) // Check if we are attached to a terminal. If we are, generate resize // events, and set the terminal to raw mode - if haveTerminal && tty { + if haveTerminal && execConfig.Terminal { cancel, oldTermState, err := handleTerminalAttach(ctx, resize) if err != nil { return -1, err @@ -34,16 +34,6 @@ func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged b }() } - execConfig := new(libpod.ExecConfig) - execConfig.Command = cmd - execConfig.Terminal = tty - execConfig.Privileged = privileged - execConfig.Environment = env - execConfig.User = user - execConfig.WorkDir = workDir - execConfig.DetachKeys = &detachKeys - execConfig.PreserveFDs = preserveFDs - return ctr.Exec(execConfig, streams, resize) } diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go index 828bfae5b..445b49ba8 100644 --- a/pkg/domain/infra/tunnel/containers.go +++ b/pkg/domain/infra/tunnel/containers.go @@ -4,6 +4,7 @@ import ( "context" "io" "os" + "strings" "github.com/containers/common/pkg/config" "github.com/containers/image/v5/docker/reference" @@ -329,10 +330,14 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, return containers.Attach(ic.ClientCxt, nameOrId, &options.DetachKeys, nil, bindings.PTrue, options.Stdin, options.Stdout, options.Stderr, nil) } -func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) { +func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions, streams define.AttachStreams) (int, error) { return 125, errors.New("not implemented") } +func (ic *ContainerEngine) ContainerExecDetached(ctx context.Context, nameOrID string, options entities.ExecOptions) (string, error) { + return "", errors.New("not implemented") +} + func startAndAttach(ic *ContainerEngine, name string, detachKeys *string, input, output, errput *os.File) error { //nolint attachErr := make(chan error) attachReady := make(chan bool) @@ -405,6 +410,11 @@ func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []strin } for _, ctr := range ctrs { err := containers.ContainerInit(ic.ClientCxt, ctr.ID) + // When using all, it is NOT considered an error if a container + // has already been init'd. + if err != nil && options.All && strings.Contains(errors.Cause(err).Error(), define.ErrCtrStateInvalid.Error()) { + err = nil + } reports = append(reports, &entities.ContainerInitReport{ Err: err, Id: ctr.ID, diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index f3aaf96bf..ffd7fd4dd 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -111,7 +111,8 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener if err != nil { return nil, err } - options = append(options, createExitCommandOption(s, rt.StorageConfig(), rtc, podmanPath)) + // TODO: Enable syslog support - we'll need to put this in SpecGen. + options = append(options, libpod.WithExitCommand(CreateExitCommandArgs(rt.StorageConfig(), rtc, podmanPath, false, s.Remove, false))) runtimeSpec, err := SpecGenToOCI(ctx, s, rt, rtc, newImage, finalMounts) if err != nil { @@ -228,7 +229,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. return options, nil } -func createExitCommandOption(s *specgen.SpecGenerator, storageConfig storage.StoreOptions, config *config.Config, podmanPath string) libpod.CtrCreateOption { +func CreateExitCommandArgs(storageConfig storage.StoreOptions, config *config.Config, podmanPath string, syslog, rm bool, exec bool) []string { // We need a cleanup process for containers in the current model. // But we can't assume that the caller is Podman - it could be another // user of the API. @@ -255,14 +256,18 @@ func createExitCommandOption(s *specgen.SpecGenerator, storageConfig storage.Sto command = append(command, []string{"--events-backend", config.Engine.EventsLogger}...) } - // TODO Mheon wants to leave this for now - //if s.sys { - // command = append(command, "--syslog", "true") - //} + if syslog { + command = append(command, "--syslog", "true") + } command = append(command, []string{"container", "cleanup"}...) - if s.Remove { + if rm { command = append(command, "--rm") } - return libpod.WithExitCommand(command) + + if exec { + command = append(command, "--exec") + } + + return command } diff --git a/pkg/util/mountOpts_linux.go b/pkg/util/mountOpts_linux.go index 3eac4dd25..bc7c675f3 100644 --- a/pkg/util/mountOpts_linux.go +++ b/pkg/util/mountOpts_linux.go @@ -7,7 +7,7 @@ import ( ) func getDefaultMountOptions(path string) (defaultMountOptions, error) { - opts := defaultMountOptions{true, true, true} + opts := defaultMountOptions{false, true, true} if path == "" { return opts, nil } diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index 258cb8652..291353cad 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -901,12 +901,12 @@ func (i *VarlinkAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.Exec // HealthCheckRun executes defined container's healthcheck command and returns the container's health status. func (i *VarlinkAPI) HealthCheckRun(call iopodman.VarlinkCall, nameOrID string) error { hcStatus, err := i.Runtime.HealthCheck(nameOrID) - if err != nil && hcStatus != libpod.HealthCheckFailure { + if err != nil && hcStatus != define.HealthCheckFailure { return call.ReplyErrorOccurred(err.Error()) } - status := libpod.HealthCheckUnhealthy - if hcStatus == libpod.HealthCheckSuccess { - status = libpod.HealthCheckHealthy + status := define.HealthCheckUnhealthy + if hcStatus == define.HealthCheckSuccess { + status = define.HealthCheckHealthy } return call.ReplyHealthCheckRun(status) } |