summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/client.go35
-rw-r--r--pkg/adapter/client_config.go4
-rw-r--r--pkg/adapter/containers.go12
-rw-r--r--pkg/adapter/containers_remote.go35
-rw-r--r--pkg/adapter/errors.go31
-rw-r--r--pkg/adapter/info_remote.go7
-rw-r--r--pkg/adapter/pods_remote.go6
-rw-r--r--pkg/adapter/runtime.go8
-rw-r--r--pkg/adapter/runtime_remote.go50
-rw-r--r--pkg/varlinkapi/attach.go1
-rw-r--r--pkg/varlinkapi/containers.go17
-rw-r--r--pkg/varlinkapi/pods.go6
-rw-r--r--pkg/varlinkapi/system.go17
13 files changed, 179 insertions, 50 deletions
diff --git a/pkg/adapter/client.go b/pkg/adapter/client.go
index 6512a5952..f672a92a6 100644
--- a/pkg/adapter/client.go
+++ b/pkg/adapter/client.go
@@ -3,30 +3,45 @@
package adapter
import (
+ "fmt"
"os"
- "github.com/sirupsen/logrus"
+ "github.com/pkg/errors"
"github.com/varlink/go/varlink"
)
-// DefaultAddress is the default address of the varlink socket
-const DefaultAddress = "unix:/run/podman/io.podman"
+type VarlinkConnectionInfo struct {
+ RemoteUserName string
+ RemoteHost string
+ VarlinkAddress string
+}
// Connect provides a varlink connection
func (r RemoteRuntime) Connect() (*varlink.Connection, error) {
- var err error
- var connection *varlink.Connection
- if bridge := os.Getenv("PODMAN_VARLINK_BRIDGE"); bridge != "" {
- logrus.Infof("Connecting with varlink bridge")
- logrus.Debugf("%s", bridge)
+ var (
+ err error
+ connection *varlink.Connection
+ )
+
+ logLevel := r.cmd.LogLevel
+
+ // I'm leaving this here for now as a document of the birdge format. It can be removed later once the bridge
+ // function is more flushed out.
+ //bridge := `ssh -T root@192.168.122.1 "/usr/bin/varlink -A '/usr/bin/podman varlink \$VARLINK_ADDRESS' bridge"`
+ if len(r.cmd.RemoteHost) > 0 {
+ // The user has provided a remote host endpoint
+ if len(r.cmd.RemoteUserName) < 1 {
+ return nil, errors.New("you must provide a username when providing a remote host name")
+ }
+ bridge := fmt.Sprintf(`ssh -T %s@%s /usr/bin/varlink -A \'/usr/bin/podman --log-level=%s varlink \\\$VARLINK_ADDRESS\' bridge`, r.cmd.RemoteUserName, r.cmd.RemoteHost, logLevel)
+ connection, err = varlink.NewBridge(bridge)
+ } else if bridge := os.Getenv("PODMAN_VARLINK_BRIDGE"); bridge != "" {
connection, err = varlink.NewBridge(bridge)
} else {
address := os.Getenv("PODMAN_VARLINK_ADDRESS")
if address == "" {
address = DefaultAddress
}
- logrus.Infof("Connecting with varlink address")
- logrus.Debugf("%s", address)
connection, err = varlink.NewConnection(address)
}
if err != nil {
diff --git a/pkg/adapter/client_config.go b/pkg/adapter/client_config.go
new file mode 100644
index 000000000..d165ef1cc
--- /dev/null
+++ b/pkg/adapter/client_config.go
@@ -0,0 +1,4 @@
+package adapter
+
+// DefaultAddress is the default address of the varlink socket
+const DefaultAddress = "unix:/run/podman/io.podman"
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 0721af773..ff7b6377a 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -413,7 +413,9 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
if c.IsSet("rm") {
- r.Runtime.RemoveContainer(ctx, ctr, false, true)
+ if err := r.Runtime.RemoveContainer(ctx, ctr, false, false); err != nil {
+ logrus.Errorf("Error removing container %s: %v", ctr.ID(), err)
+ }
}
return exitCode, nil
@@ -965,8 +967,9 @@ func (r *LocalRuntime) CleanupContainers(ctx context.Context, cli *cliconfig.Cle
return ok, failures, nil
}
+// Only used when cleaning up containers
func removeContainer(ctx context.Context, ctr *libpod.Container, runtime *LocalRuntime) error {
- if err := runtime.RemoveContainer(ctx, ctr, false, true); err != nil {
+ if err := runtime.RemoveContainer(ctx, ctr, false, false); err != nil {
return errors.Wrapf(err, "failed to cleanup and remove container %v", ctr.ID())
}
return nil
@@ -1022,3 +1025,8 @@ func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (stri
}
return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, ctr.Config().StaticDir, timeout)
}
+
+// GetNamespaces returns namespace information about a container for PS
+func (r *LocalRuntime) GetNamespaces(container shared.PsContainerOutput) *shared.Namespace {
+ return shared.GetNamespaces(container.Pid)
+}
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index 201249fc3..63b0f9d2f 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -234,15 +234,25 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa
ids, err := iopodman.GetContainersByContext().Call(r.Conn, cli.All, cli.Latest, cli.InputArgs)
if err != nil {
- return ok, failures, err
+ return ok, failures, TranslateError(err)
}
for _, id := range ids {
- stopped, err := iopodman.StopContainer().Call(r.Conn, id, int64(cli.Timeout))
- if err != nil {
+ if _, err := iopodman.StopContainer().Call(r.Conn, id, int64(cli.Timeout)); err != nil {
+ transError := TranslateError(err)
+ if errors.Cause(transError) == libpod.ErrCtrStopped {
+ ok = append(ok, id)
+ continue
+ }
+ if errors.Cause(transError) == libpod.ErrCtrStateInvalid && cli.All {
+ ok = append(ok, id)
+ continue
+ }
failures[id] = err
} else {
- ok = append(ok, stopped)
+ // We should be using ID here because in varlink, only successful returns
+ // include the string id
+ ok = append(ok, id)
}
}
return ok, failures, nil
@@ -310,7 +320,7 @@ func (r *LocalRuntime) KillContainers(ctx context.Context, cli *cliconfig.KillVa
func (r *LocalRuntime) RemoveContainers(ctx context.Context, cli *cliconfig.RmValues) ([]string, map[string]error, error) {
ids, err := iopodman.GetContainersByContext().Call(r.Conn, cli.All, cli.Latest, cli.InputArgs)
if err != nil {
- return nil, nil, err
+ return nil, nil, TranslateError(err)
}
var (
@@ -961,3 +971,18 @@ func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (string, error) {
return iopodman.GenerateSystemd().Call(r.Conn, c.InputArgs[0], c.RestartPolicy, int64(c.StopTimeout), c.Name)
}
+
+// GetNamespaces returns namespace information about a container for PS
+func (r *LocalRuntime) GetNamespaces(container shared.PsContainerOutput) *shared.Namespace {
+ ns := shared.Namespace{
+ PID: container.PID,
+ Cgroup: container.Cgroup,
+ IPC: container.IPC,
+ MNT: container.MNT,
+ NET: container.NET,
+ PIDNS: container.PIDNS,
+ User: container.User,
+ UTS: container.UTS,
+ }
+ return &ns
+}
diff --git a/pkg/adapter/errors.go b/pkg/adapter/errors.go
new file mode 100644
index 000000000..7fbbabd93
--- /dev/null
+++ b/pkg/adapter/errors.go
@@ -0,0 +1,31 @@
+// +build remoteclient
+
+package adapter
+
+import (
+ iopodman "github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/containers/libpod/libpod"
+ "github.com/pkg/errors"
+)
+
+// TranslateMapErrors translates the errors a typical podman output struct
+// from varlink errors to libpod errors
+func TranslateMapErrors(failures map[string]error) map[string]error {
+ for k, v := range failures {
+ failures[k] = TranslateError(v)
+ }
+ return failures
+}
+
+// TranslateError converts a single varlink error to a libpod error
+func TranslateError(err error) error {
+ switch err.(type) {
+ case *iopodman.ContainerNotFound:
+ return errors.Wrap(libpod.ErrNoSuchCtr, err.Error())
+ case *iopodman.ErrCtrStopped:
+ return errors.Wrap(libpod.ErrCtrStopped, err.Error())
+ case *iopodman.InvalidState:
+ return errors.Wrap(libpod.ErrCtrStateInvalid, err.Error())
+ }
+ return err
+}
diff --git a/pkg/adapter/info_remote.go b/pkg/adapter/info_remote.go
index 3b691ed17..3b2d02a5a 100644
--- a/pkg/adapter/info_remote.go
+++ b/pkg/adapter/info_remote.go
@@ -20,12 +20,7 @@ func (r RemoteRuntime) Info() ([]libpod.InfoData, error) {
registries := make(map[string]interface{})
insecureRegistries := make(map[string]interface{})
- conn, err := r.Connect()
- if err != nil {
- return nil, err
- }
- defer conn.Close()
- info, err := iopodman.GetInfo().Call(conn)
+ info, err := iopodman.GetInfo().Call(r.Conn)
if err != nil {
return nil, err
}
diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go
index 7cf38aac0..e2c97c36a 100644
--- a/pkg/adapter/pods_remote.go
+++ b/pkg/adapter/pods_remote.go
@@ -172,11 +172,15 @@ func (r *LocalRuntime) StartPods(ctx context.Context, cli *cliconfig.PodStartVal
// CreatePod creates a pod for the remote client over a varlink connection
func (r *LocalRuntime) CreatePod(ctx context.Context, cli *cliconfig.PodCreateValues, labels map[string]string) (string, error) {
+ var share []string
+ if cli.Share != "" {
+ share = strings.Split(cli.Share, ",")
+ }
pc := iopodman.PodCreate{
Name: cli.Name,
CgroupParent: cli.CgroupParent,
Labels: labels,
- Share: strings.Split(cli.Share, ","),
+ Share: share,
Infra: cli.Infra,
InfraCommand: cli.InfraCommand,
InfraImage: cli.InfraCommand,
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 0d840d65b..21613c425 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -5,12 +5,13 @@ package adapter
import (
"bufio"
"context"
- "github.com/containers/libpod/cmd/podman/shared"
"io"
"io/ioutil"
"os"
"text/template"
+ "github.com/containers/libpod/cmd/podman/shared"
+
"github.com/containers/buildah"
"github.com/containers/buildah/imagebuildah"
"github.com/containers/buildah/pkg/parse"
@@ -392,3 +393,8 @@ func (r *LocalRuntime) GetPodsByStatus(statuses []string) ([]*libpod.Pod, error)
return pods, nil
}
+
+// GetVersion is an alias to satisfy interface{}
+func (r *LocalRuntime) GetVersion() (libpod.Version, error) {
+ return libpod.GetVersion()
+}
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 4986d16f7..e86287462 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -9,12 +9,13 @@ import (
"fmt"
"io"
"io/ioutil"
- v1 "k8s.io/api/core/v1"
"os"
"strings"
"text/template"
"time"
+ v1 "k8s.io/api/core/v1"
+
"github.com/containers/buildah/imagebuildah"
"github.com/containers/image/docker/reference"
"github.com/containers/image/types"
@@ -38,6 +39,7 @@ type RemoteImageRuntime struct{}
type RemoteRuntime struct {
Conn *varlink.Connection
Remote bool
+ cmd cliconfig.MainFlags
}
// LocalRuntime describes a typical libpod runtime
@@ -47,17 +49,17 @@ type LocalRuntime struct {
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
- runtime := RemoteRuntime{}
+ runtime := RemoteRuntime{
+ Remote: true,
+ cmd: c.GlobalFlags,
+ }
conn, err := runtime.Connect()
if err != nil {
return nil, err
}
-
+ runtime.Conn = conn
return &LocalRuntime{
- &RemoteRuntime{
- Conn: conn,
- Remote: true,
- },
+ &runtime,
}, nil
}
@@ -414,19 +416,19 @@ func (r *LocalRuntime) Build(ctx context.Context, c *cliconfig.BuildValues, opti
Compression: string(options.Compression),
DefaultsMountFilePath: options.DefaultMountsFilePath,
Dockerfiles: dockerfiles,
- //Err: string(options.Err),
+ // Err: string(options.Err),
ForceRmIntermediateCtrs: options.ForceRmIntermediateCtrs,
Iidfile: options.IIDFile,
Label: options.Labels,
Layers: options.Layers,
Nocache: options.NoCache,
- //Out:
+ // Out:
Output: options.Output,
OutputFormat: options.OutputFormat,
PullPolicy: options.PullPolicy.String(),
Quiet: options.Quiet,
RemoteIntermediateCtrs: options.RemoveIntermediateCtrs,
- //ReportWriter:
+ // ReportWriter:
RuntimeArgs: options.RuntimeArgs,
SignaturePolicyPath: options.SignaturePolicyPath,
Squash: options.Squash,
@@ -610,7 +612,7 @@ func (r *LocalRuntime) InspectVolumes(ctx context.Context, c *cliconfig.VolumeIn
return varlinkVolumeToVolume(r, reply), nil
}
-//Volumes returns a slice of adapter.volumes based on information about libpod
+// Volumes returns a slice of adapter.volumes based on information about libpod
// volumes over a varlink connection
func (r *LocalRuntime) Volumes(ctx context.Context) ([]*Volume, error) {
reply, err := iopodman.GetVolumes().Call(r.Conn, []string{}, true)
@@ -906,3 +908,29 @@ func (r *LocalRuntime) GetContainersByContext(all bool, latest bool, namesOrIDs
}
return containers, nil
}
+
+// GetVersion returns version information from service
+func (r *LocalRuntime) GetVersion() (libpod.Version, error) {
+ version, goVersion, gitCommit, built, osArch, apiVersion, err := iopodman.GetVersion().Call(r.Conn)
+ if err != nil {
+ return libpod.Version{}, errors.Wrapf(err, "Unable to obtain server version information")
+ }
+
+ var buildTime int64
+ if built != "" {
+ t, err := time.Parse(time.RFC3339, built)
+ if err != nil {
+ return libpod.Version{}, nil
+ }
+ buildTime = t.Unix()
+ }
+
+ return libpod.Version{
+ RemoteAPIVersion: apiVersion,
+ Version: version,
+ GoVersion: goVersion,
+ GitCommit: gitCommit,
+ Built: buildTime,
+ OsArch: osArch,
+ }, nil
+}
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index 6c62d3514..2234899a5 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -60,6 +60,7 @@ func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys st
if !start && state != libpod.ContainerStateRunning {
return call.ReplyErrorOccurred("container must be running to attach")
}
+ call.Reply(nil)
reader, writer, _, pw, streams := setupStreams(call)
go func() {
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index c8be41636..8611a1a7d 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -119,6 +119,9 @@ func (i *LibpodAPI) GetContainersByContext(call iopodman.VarlinkCall, all, lates
ctrs, err := shortcuts.GetContainersByContext(all, latest, input, i.Runtime)
if err != nil {
+ if errors.Cause(err) == libpod.ErrNoSuchCtr {
+ return call.ReplyContainerNotFound("", err.Error())
+ }
return call.ReplyErrorOccurred(err.Error())
}
@@ -359,7 +362,11 @@ func (i *LibpodAPI) StartContainer(call iopodman.VarlinkCall, name string) error
if state == libpod.ContainerStateRunning || state == libpod.ContainerStatePaused {
return call.ReplyErrorOccurred("container is already running or paused")
}
- if err := ctr.Start(getContext(), false); err != nil {
+ recursive := false
+ if ctr.PodID() != "" {
+ recursive = true
+ }
+ if err := ctr.Start(getContext(), recursive); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyStartContainer(ctr.ID())
@@ -386,7 +393,13 @@ func (i *LibpodAPI) StopContainer(call iopodman.VarlinkCall, name string, timeou
if err != nil {
return call.ReplyContainerNotFound(name, err.Error())
}
- if err := ctr.StopWithTimeout(uint(timeout)); err != nil && err != libpod.ErrCtrStopped {
+ if err := ctr.StopWithTimeout(uint(timeout)); err != nil {
+ if errors.Cause(err) == libpod.ErrCtrStopped {
+ return call.ReplyErrCtrStopped(ctr.ID())
+ }
+ if errors.Cause(err) == libpod.ErrCtrStateInvalid {
+ return call.ReplyInvalidState(ctr.ID(), err.Error())
+ }
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyStopContainer(ctr.ID())
diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go
index f34375bf5..c0fd8b1f7 100644
--- a/pkg/varlinkapi/pods.go
+++ b/pkg/varlinkapi/pods.go
@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"github.com/containers/libpod/pkg/adapter/shortcuts"
- "github.com/containers/libpod/pkg/rootless"
"syscall"
"github.com/containers/libpod/cmd/podman/shared"
@@ -37,12 +36,9 @@ func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCrea
if !create.Infra {
return call.ReplyErrorOccurred("you must have an infra container to publish port bindings to the host")
}
- if rootless.IsRootless() {
- return call.ReplyErrorOccurred("rootless networking does not allow port binding to the host")
- }
portBindings, err := shared.CreatePortBindings(create.Publish)
if err != nil {
- return err
+ return call.ReplyErrorOccurred(err.Error())
}
options = append(options, libpod.WithInfraContainerPorts(portBindings))
diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go
index 7f436a954..59bfec75b 100644
--- a/pkg/varlinkapi/system.go
+++ b/pkg/varlinkapi/system.go
@@ -86,15 +86,18 @@ func (i *LibpodAPI) GetInfo(call iopodman.VarlinkCall) error {
Graph_status: graphStatus,
}
- registriesInterface := info[2].Data["registries"]
- insecureRegistriesInterface := info[3].Data["registries"]
- if registriesInterface != nil {
- registries = registriesInterface.([]string)
+ if len(info) > 2 {
+ registriesInterface := info[2].Data["registries"]
+ if registriesInterface != nil {
+ registries = registriesInterface.([]string)
+ }
}
- if insecureRegistriesInterface != nil {
- insecureRegistries = insecureRegistriesInterface.([]string)
+ if len(info) > 3 {
+ insecureRegistriesInterface := info[3].Data["registries"]
+ if insecureRegistriesInterface != nil {
+ insecureRegistries = insecureRegistriesInterface.([]string)
+ }
}
-
podmanInfo.Store = infoStore
podmanInfo.Podman = pmaninfo
podmanInfo.Registries = registries