summaryrefslogtreecommitdiff
path: root/pkg/domain/infra
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain/infra')
-rw-r--r--pkg/domain/infra/abi/containers.go272
-rw-r--r--pkg/domain/infra/abi/images.go8
-rw-r--r--pkg/domain/infra/abi/pods.go26
-rw-r--r--pkg/domain/infra/abi/system.go13
-rw-r--r--pkg/domain/infra/abi/terminal/sigproxy_linux.go47
-rw-r--r--pkg/domain/infra/abi/terminal/terminal.go103
-rw-r--r--pkg/domain/infra/abi/terminal/terminal_linux.go123
-rw-r--r--pkg/domain/infra/tunnel/containers.go30
-rw-r--r--pkg/domain/infra/tunnel/helpers.go5
-rw-r--r--pkg/domain/infra/tunnel/images.go9
-rw-r--r--pkg/domain/infra/tunnel/pods.go10
-rw-r--r--pkg/domain/infra/tunnel/system.go12
12 files changed, 641 insertions, 17 deletions
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index d3d51db82..ccbe6d4fd 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -5,16 +5,19 @@ package abi
import (
"context"
"io/ioutil"
+ "strconv"
"strings"
"github.com/containers/buildah"
"github.com/containers/image/v5/manifest"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/libpod/image"
- "github.com/containers/libpod/pkg/adapter/shortcuts"
"github.com/containers/libpod/pkg/checkpoint"
"github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/domain/infra/abi/terminal"
+ "github.com/containers/libpod/pkg/ps"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
"github.com/containers/libpod/pkg/specgen/generate"
@@ -64,7 +67,7 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
var (
responses []entities.WaitReport
)
- ctrs, err := shortcuts.GetContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
+ ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -90,7 +93,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
if options.All {
ctrs, err = ic.Libpod.GetAllContainers()
} else {
- ctrs, err = shortcuts.GetContainersByContext(false, false, namesOrIds, ic.Libpod)
+ ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
}
if err != nil {
return nil, err
@@ -111,7 +114,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
if options.All {
ctrs, err = ic.Libpod.GetAllContainers()
} else {
- ctrs, err = shortcuts.GetContainersByContext(false, false, namesOrIds, ic.Libpod)
+ ctrs, err = getContainersByContext(false, false, namesOrIds, ic.Libpod)
}
if err != nil {
return nil, err
@@ -135,7 +138,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
id := strings.Split(string(content), "\n")[0]
names = append(names, id)
}
- ctrs, err := shortcuts.GetContainersByContext(options.All, options.Latest, names, ic.Libpod)
+ ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
return nil, err
}
@@ -171,7 +174,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
if err != nil {
return nil, err
}
- ctrs, err := shortcuts.GetContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
+ ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -187,7 +190,7 @@ func (ic *ContainerEngine) ContainerRestart(ctx context.Context, namesOrIds []st
var (
reports []*entities.RestartReport
)
- ctrs, err := shortcuts.GetContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
+ ctrs, err := getContainersByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -229,7 +232,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
names = append(names, id)
}
- ctrs, err := shortcuts.GetContainersByContext(options.All, options.Latest, names, ic.Libpod)
+ ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) {
// Failed to get containers. If force is specified, get the containers ID
// and evict them
@@ -277,7 +280,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []string, options entities.InspectOptions) ([]*entities.ContainerInspectReport, error) {
var reports []*entities.ContainerInspectReport
- ctrs, err := shortcuts.GetContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
+ ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
if err != nil {
return nil, err
}
@@ -455,3 +458,254 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
}
return &entities.ContainerCreateReport{Id: ctr.ID()}, nil
}
+
+func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error {
+ ctrs, err := getContainersByContext(false, options.Latest, []string{nameOrId}, ic.Libpod)
+ if err != nil {
+ return err
+ }
+ ctr := ctrs[0]
+ conState, err := ctr.State()
+ if err != nil {
+ return errors.Wrapf(err, "unable to determine state of %s", ctr.ID())
+ }
+ if conState != define.ContainerStateRunning {
+ return errors.Errorf("you can only attach to running containers")
+ }
+
+ // If the container is in a pod, also set to recursively start dependencies
+ if err := terminal.StartAttachCtr(ctx, ctr, options.Stdin, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, false, ctr.PodID() != ""); err != nil && errors.Cause(err) != define.ErrDetach {
+ return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
+ }
+ return nil
+}
+
+func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) {
+ ec := define.ExecErrorCodeGeneric
+ if options.PreserveFDs > 0 {
+ entries, err := ioutil.ReadDir("/proc/self/fd")
+ if err != nil {
+ return ec, errors.Wrapf(err, "unable to read /proc/self/fd")
+ }
+
+ m := make(map[int]bool)
+ for _, e := range entries {
+ i, err := strconv.Atoi(e.Name())
+ if err != nil {
+ return ec, errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name())
+ }
+ m[i] = true
+ }
+
+ for i := 3; i < 3+int(options.PreserveFDs); i++ {
+ if _, found := m[i]; !found {
+ return ec, errors.New("invalid --preserve-fds=N specified. Not enough FDs available")
+ }
+ }
+ }
+ 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)
+ return define.TranslateExecErrorToExitCode(ec, err), err
+}
+
+func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
+ var reports []*entities.ContainerStartReport
+ var exitCode = define.ExecErrorCodeGeneric
+ ctrs, err := getContainersByContext(false, options.Latest, namesOrIds, ic.Libpod)
+ if err != nil {
+ return nil, err
+ }
+ // There can only be one container if attach was used
+ for _, ctr := range ctrs {
+ ctrState, err := ctr.State()
+ if err != nil {
+ return nil, err
+ }
+ 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() != "")
+ if errors.Cause(err) == define.ErrDetach {
+ // User manually detached
+ // Exit cleanly immediately
+ reports = append(reports, &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ Err: nil,
+ ExitCode: 0,
+ })
+ return reports, nil
+ }
+
+ if errors.Cause(err) == define.ErrWillDeadlock {
+ logrus.Debugf("Deadlock error: %v", err)
+ reports = append(reports, &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ Err: err,
+ ExitCode: define.ExitCode(err),
+ })
+ return reports, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID())
+ }
+
+ if ctrRunning {
+ reports = append(reports, &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ Err: nil,
+ ExitCode: 0,
+ })
+ return reports, err
+ }
+
+ if err != nil {
+ reports = append(reports, &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ Err: err,
+ ExitCode: exitCode,
+ })
+ return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID())
+ }
+
+ if ecode, err := ctr.Wait(); err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ // Check events
+ event, err := ic.Libpod.GetLastContainerEvent(ctr.ID(), events.Exited)
+ if err != nil {
+ logrus.Errorf("Cannot get exit code: %v", err)
+ exitCode = define.ExecErrorCodeNotFound
+ } else {
+ exitCode = event.ContainerExitCode
+ }
+ }
+ } else {
+ exitCode = int(ecode)
+ }
+ reports = append(reports, &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ Err: err,
+ ExitCode: exitCode,
+ })
+ return reports, nil
+ } // end attach
+
+ // Start the container if it's not running already.
+ if !ctrRunning {
+ // Handle non-attach start
+ // If the container is in a pod, also set to recursively start dependencies
+ report := &entities.ContainerStartReport{
+ Id: ctr.ID(),
+ ExitCode: 125,
+ }
+ if err := ctr.Start(ctx, ctr.PodID() != ""); err != nil {
+ // if lastError != nil {
+ // fmt.Fprintln(os.Stderr, lastError)
+ // }
+ report.Err = err
+ if errors.Cause(err) == define.ErrWillDeadlock {
+ report.Err = errors.Wrapf(err, "please run 'podman system renumber' to resolve deadlocks")
+ reports = append(reports, report)
+ continue
+ }
+ report.Err = errors.Wrapf(err, "unable to start container %q", ctr.ID())
+ reports = append(reports, report)
+ continue
+ }
+ report.ExitCode = 0
+ reports = append(reports, report)
+ }
+ }
+ return reports, nil
+}
+
+func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
+ return ps.GetContainerLists(ic.Libpod, options)
+}
+
+// ContainerDiff provides changes to given container
+func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, opts entities.DiffOptions) (*entities.DiffReport, error) {
+ if opts.Latest {
+ ctnr, err := ic.Libpod.GetLatestContainer()
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to get latest container")
+ }
+ nameOrId = ctnr.ID()
+ }
+ changes, err := ic.Libpod.GetDiff("", nameOrId)
+ return &entities.DiffReport{Changes: changes}, err
+}
+
+func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) {
+ var (
+ joinPod bool
+ )
+ if err := generate.CompleteSpec(ctx, ic.Libpod, opts.Spec); err != nil {
+ return nil, err
+ }
+ ctr, err := generate.MakeContainer(ic.Libpod, opts.Spec)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(ctr.PodID()) > 0 {
+ joinPod = true
+ }
+ report := entities.ContainerRunReport{Id: ctr.ID()}
+
+ if logrus.GetLevel() == logrus.DebugLevel {
+ cgroupPath, err := ctr.CGroupPath()
+ if err == nil {
+ logrus.Debugf("container %q has CgroupParent %q", ctr.ID(), cgroupPath)
+ }
+ }
+ 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 {
+ // This means the command did not exist
+ report.ExitCode = define.ExitCode(err)
+ return &report, err
+ }
+
+ return &report, nil
+ }
+
+ // 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 {
+ // We've manually detached from the container
+ // Do not perform cleanup, or wait for container exit code
+ // Just exit immediately
+ if errors.Cause(err) == define.ErrDetach {
+ report.ExitCode = 0
+ return &report, nil
+ }
+ if opts.Rm {
+ if deleteError := ic.Libpod.RemoveContainer(ctx, ctr, true, false); deleteError != nil {
+ logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID())
+ }
+ }
+ if errors.Cause(err) == define.ErrWillDeadlock {
+ logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err)
+ report.ExitCode = define.ExitCode(err)
+ return &report, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID())
+ }
+ report.ExitCode = define.ExitCode(err)
+ return &report, err
+ }
+
+ if ecode, err := ctr.Wait(); err != nil {
+ if errors.Cause(err) == define.ErrNoSuchCtr {
+ // Check events
+ event, err := ic.Libpod.GetLastContainerEvent(ctr.ID(), events.Exited)
+ if err != nil {
+ logrus.Errorf("Cannot get exit code: %v", err)
+ report.ExitCode = define.ExecErrorCodeNotFound
+ } else {
+ report.ExitCode = event.ContainerExitCode
+ }
+ }
+ } else {
+ report.ExitCode = int(ecode)
+ }
+ return &report, nil
+}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 9d706a112..2edef2723 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -413,3 +413,11 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrId string, tags []string,
}
return newImage.Save(ctx, nameOrId, options.Format, options.Output, tags, options.Quiet, options.Compress)
}
+
+func (ir *ImageEngine) Diff(_ context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) {
+ changes, err := ir.Libpod.GetDiff("", nameOrId)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.DiffReport{Changes: changes}, nil
+}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index 494a048ec..c3e5d59bc 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -5,9 +5,10 @@ package abi
import (
"context"
+ lpfilters "github.com/containers/libpod/libpod/filters"
+
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/libpod/podfilters"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/signal"
"github.com/containers/libpod/pkg/specgen"
@@ -281,7 +282,7 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
)
for k, v := range options.Filters {
for _, filter := range v {
- f, err := podfilters.GeneratePodFilterFunc(k, filter)
+ f, err := lpfilters.GeneratePodFilterFunc(k, filter)
if err != nil {
return nil, err
}
@@ -331,3 +332,24 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
}
return reports, nil
}
+
+func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodInspectOptions) (*entities.PodInspectReport, error) {
+ var (
+ pod *libpod.Pod
+ err error
+ )
+ // Look up the pod.
+ if options.Latest {
+ pod, err = ic.Libpod.GetLatestPod()
+ } else {
+ pod, err = ic.Libpod.LookupPod(options.NameOrID)
+ }
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to lookup requested container")
+ }
+ inspect, err := pod.Inspect()
+ if err != nil {
+ return nil, err
+ }
+ return &entities.PodInspectReport{PodInspect: inspect}, nil
+}
diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go
new file mode 100644
index 000000000..8aaa69847
--- /dev/null
+++ b/pkg/domain/infra/abi/system.go
@@ -0,0 +1,13 @@
+// +build ABISupport
+
+package abi
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+)
+
+func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
+ return ic.Libpod.Info()
+}
diff --git a/pkg/domain/infra/abi/terminal/sigproxy_linux.go b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
new file mode 100644
index 000000000..d7f5853d8
--- /dev/null
+++ b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
@@ -0,0 +1,47 @@
+// +build ABISupport
+
+package terminal
+
+import (
+ "os"
+ "syscall"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/signal"
+ "github.com/sirupsen/logrus"
+)
+
+// ProxySignals ...
+func ProxySignals(ctr *libpod.Container) {
+ sigBuffer := make(chan os.Signal, 128)
+ signal.CatchAll(sigBuffer)
+
+ logrus.Debugf("Enabling signal proxying")
+
+ go func() {
+ for s := range sigBuffer {
+ // Ignore SIGCHLD and SIGPIPE - these are mostly likely
+ // intended for the podman command itself.
+ // SIGURG was added because of golang 1.14 and its preemptive changes
+ // causing more signals to "show up".
+ // https://github.com/containers/libpod/issues/5483
+ if s == syscall.SIGCHLD || s == syscall.SIGPIPE || s == syscall.SIGURG {
+ continue
+ }
+
+ if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil {
+ // If the container dies, and we find out here,
+ // we need to forward that one signal to
+ // ourselves so that it is not lost, and then
+ // we terminate the proxy and let the defaults
+ // play out.
+ logrus.Errorf("Error forwarding signal %d to container %s: %v", s, ctr.ID(), err)
+ signal.StopCatch(sigBuffer)
+ if err := syscall.Kill(syscall.Getpid(), s.(syscall.Signal)); err != nil {
+ logrus.Errorf("failed to kill pid %d", syscall.Getpid())
+ }
+ return
+ }
+ }
+ }()
+}
diff --git a/pkg/domain/infra/abi/terminal/terminal.go b/pkg/domain/infra/abi/terminal/terminal.go
new file mode 100644
index 000000000..f187bdd6b
--- /dev/null
+++ b/pkg/domain/infra/abi/terminal/terminal.go
@@ -0,0 +1,103 @@
+// +build ABISupport
+
+package terminal
+
+import (
+ "context"
+ "os"
+ "os/signal"
+
+ lsignal "github.com/containers/libpod/pkg/signal"
+ "github.com/docker/docker/pkg/term"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "k8s.io/client-go/tools/remotecommand"
+)
+
+// RawTtyFormatter ...
+type RawTtyFormatter struct {
+}
+
+// getResize returns a TerminalSize command matching stdin's current
+// size on success, and nil on errors.
+func getResize() *remotecommand.TerminalSize {
+ winsize, err := term.GetWinsize(os.Stdin.Fd())
+ if err != nil {
+ logrus.Warnf("Could not get terminal size %v", err)
+ return nil
+ }
+ return &remotecommand.TerminalSize{
+ Width: winsize.Width,
+ Height: winsize.Height,
+ }
+}
+
+// Helper for prepareAttach - set up a goroutine to generate terminal resize events
+func resizeTty(ctx context.Context, resize chan remotecommand.TerminalSize) {
+ sigchan := make(chan os.Signal, 1)
+ signal.Notify(sigchan, lsignal.SIGWINCH)
+ go func() {
+ defer close(resize)
+ // Update the terminal size immediately without waiting
+ // for a SIGWINCH to get the correct initial size.
+ resizeEvent := getResize()
+ for {
+ if resizeEvent == nil {
+ select {
+ case <-ctx.Done():
+ return
+ case <-sigchan:
+ resizeEvent = getResize()
+ }
+ } else {
+ select {
+ case <-ctx.Done():
+ return
+ case <-sigchan:
+ resizeEvent = getResize()
+ case resize <- *resizeEvent:
+ resizeEvent = nil
+ }
+ }
+ }
+ }()
+}
+
+func restoreTerminal(state *term.State) error {
+ logrus.SetFormatter(&logrus.TextFormatter{})
+ return term.RestoreTerminal(os.Stdin.Fd(), state)
+}
+
+// Format ...
+func (f *RawTtyFormatter) Format(entry *logrus.Entry) ([]byte, error) {
+ textFormatter := logrus.TextFormatter{}
+ bytes, err := textFormatter.Format(entry)
+
+ if err == nil {
+ bytes = append(bytes, '\r')
+ }
+
+ return bytes, err
+}
+
+func handleTerminalAttach(ctx context.Context, resize chan remotecommand.TerminalSize) (context.CancelFunc, *term.State, error) {
+ logrus.Debugf("Handling terminal attach")
+
+ subCtx, cancel := context.WithCancel(ctx)
+
+ resizeTty(subCtx, resize)
+
+ oldTermState, err := term.SaveState(os.Stdin.Fd())
+ if err != nil {
+ // allow caller to not have to do any cleaning up if we error here
+ cancel()
+ return nil, nil, errors.Wrapf(err, "unable to save terminal state")
+ }
+
+ logrus.SetFormatter(&RawTtyFormatter{})
+ if _, err := term.SetRawTerminal(os.Stdin.Fd()); err != nil {
+ return cancel, nil, err
+ }
+
+ return cancel, oldTermState, nil
+}
diff --git a/pkg/domain/infra/abi/terminal/terminal_linux.go b/pkg/domain/infra/abi/terminal/terminal_linux.go
new file mode 100644
index 000000000..664205df1
--- /dev/null
+++ b/pkg/domain/infra/abi/terminal/terminal_linux.go
@@ -0,0 +1,123 @@
+// +build ABISupport
+
+package terminal
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/crypto/ssh/terminal"
+ "k8s.io/client-go/tools/remotecommand"
+)
+
+// 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) {
+ 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 {
+ cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
+ if err != nil {
+ return -1, err
+ }
+ defer cancel()
+ defer func() {
+ if err := restoreTerminal(oldTermState); err != nil {
+ logrus.Errorf("unable to restore terminal: %q", err)
+ }
+ }()
+ }
+
+ 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)
+}
+
+// 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
+ 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 && ctr.Spec().Process.Terminal {
+ cancel, oldTermState, err := handleTerminalAttach(ctx, resize)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err := restoreTerminal(oldTermState); err != nil {
+ logrus.Errorf("unable to restore terminal: %q", err)
+ }
+ }()
+ defer cancel()
+ }
+
+ streams := new(define.AttachStreams)
+ streams.OutputStream = stdout
+ streams.ErrorStream = stderr
+ streams.InputStream = bufio.NewReader(stdin)
+ streams.AttachOutput = true
+ streams.AttachError = true
+ streams.AttachInput = true
+
+ if stdout == nil {
+ logrus.Debugf("Not attaching to stdout")
+ streams.AttachOutput = false
+ }
+ if stderr == nil {
+ logrus.Debugf("Not attaching to stderr")
+ streams.AttachError = false
+ }
+ if stdin == nil {
+ logrus.Debugf("Not attaching to stdin")
+ streams.AttachInput = false
+ }
+
+ if !startContainer {
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ return ctr.Attach(streams, detachKeys, resize)
+ }
+
+ attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive)
+ if err != nil {
+ return err
+ }
+
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ if stdout == nil && stderr == nil {
+ fmt.Printf("%s\n", ctr.ID())
+ }
+
+ err = <-attachChan
+ if err != nil {
+ return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
+ }
+
+ return nil
+}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index ae8994cba..b22c6e3ba 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -7,7 +7,6 @@ import (
"github.com/containers/image/v5/docker/reference"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/pkg/api/handlers/libpod"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/containers/libpod/pkg/specgen"
@@ -233,7 +232,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
var (
reports []*entities.CheckpointReport
err error
- ctrs []libpod.ListContainer
+ ctrs []entities.ListContainer
)
if options.All {
@@ -268,7 +267,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
var (
reports []*entities.RestoreReport
err error
- ctrs []libpod.ListContainer
+ ctrs []entities.ListContainer
)
if options.All {
allCtrs, err := getContainersByContext(ic.ClientCxt, true, []string{})
@@ -305,3 +304,28 @@ func (ic *ContainerEngine) ContainerCreate(ctx context.Context, s *specgen.SpecG
}
return &entities.ContainerCreateReport{Id: response.ID}, nil
}
+
+func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrId string, options entities.AttachOptions) error {
+ return errors.New("not implemented")
+}
+
+func (ic *ContainerEngine) ContainerExec(ctx context.Context, nameOrId string, options entities.ExecOptions) (int, error) {
+ return 125, errors.New("not implemented")
+}
+
+func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []string, options entities.ContainerStartOptions) ([]*entities.ContainerStartReport, error) {
+ return nil, errors.New("not implemented")
+}
+
+func (ic *ContainerEngine) ContainerList(ctx context.Context, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
+ return containers.List(ic.ClientCxt, options.Filters, &options.All, &options.Last, &options.Pod, &options.Size, &options.Sync)
+}
+
+func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.ContainerRunOptions) (*entities.ContainerRunReport, error) {
+ return nil, errors.New("not implemented")
+}
+
+func (ic *ContainerEngine) ContainerDiff(ctx context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) {
+ changes, err := containers.Diff(ic.ClientCxt, nameOrId)
+ return &entities.DiffReport{Changes: changes}, err
+}
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index f9183c955..682d60d6a 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -5,7 +5,6 @@ import (
"strings"
"github.com/containers/libpod/libpod/define"
- "github.com/containers/libpod/pkg/api/handlers/libpod"
"github.com/containers/libpod/pkg/bindings"
"github.com/containers/libpod/pkg/bindings/containers"
"github.com/containers/libpod/pkg/bindings/pods"
@@ -14,9 +13,9 @@ import (
"github.com/pkg/errors"
)
-func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]libpod.ListContainer, error) {
+func getContainersByContext(contextWithConnection context.Context, all bool, namesOrIds []string) ([]entities.ListContainer, error) {
var (
- cons []libpod.ListContainer
+ cons []entities.ListContainer
)
if all && len(namesOrIds) > 0 {
return nil, errors.New("cannot lookup containers and all")
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 516914a68..66abd7f47 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -241,3 +241,12 @@ func (ir *ImageEngine) Save(ctx context.Context, nameOrId string, tags []string,
}
return utils2.UntarToFileSystem(options.Output, f, nil)
}
+
+// Diff reports the changes to the given image
+func (ir *ImageEngine) Diff(ctx context.Context, nameOrId string, _ entities.DiffOptions) (*entities.DiffReport, error) {
+ changes, err := images.Diff(ir.ClientCxt, nameOrId)
+ if err != nil {
+ return nil, err
+ }
+ return &entities.DiffReport{Changes: changes}, nil
+}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index ad87a0a29..dad77284f 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -197,3 +197,13 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
return pods.List(ic.ClientCxt, options.Filters)
}
+
+func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodInspectOptions) (*entities.PodInspectReport, error) {
+ switch {
+ case options.Latest:
+ return nil, errors.New("latest is not supported")
+ case options.NameOrID == "":
+ return nil, errors.New("NameOrID must be specified")
+ }
+ return pods.Inspect(ic.ClientCxt, options.NameOrID)
+}
diff --git a/pkg/domain/infra/tunnel/system.go b/pkg/domain/infra/tunnel/system.go
new file mode 100644
index 000000000..5d6346234
--- /dev/null
+++ b/pkg/domain/infra/tunnel/system.go
@@ -0,0 +1,12 @@
+package tunnel
+
+import (
+ "context"
+
+ "github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/pkg/bindings/system"
+)
+
+func (ic *ContainerEngine) Info(ctx context.Context) (*define.Info, error) {
+ return system.Info(ic.ClientCxt)
+}