varlink images

implement varlink image functions for working with libpod with the exception of a
couple due to incompletions on the libpod side of things (build).

also, created a first pass at a libpodpy package which will stand as a client to
working with libpod's varlink methods using python.

Signed-off-by: baude <bbaude@redhat.com>

Closes: #669
Approved by: baude
This commit is contained in:
baude
2018-04-23 13:32:41 -05:00
committed by Atomic Bot
parent 0ccfd7dc20
commit 39a7a773a6
55 changed files with 1576 additions and 997 deletions

View File

@ -247,10 +247,10 @@ install.tools: .install.gitvalidation .install.gometalinter .install.md2man
make all install; \ make all install; \
fi fi
varlink_generate: .gopathok cmd/podman/ioprojectatomicpodman/ioprojectatomicpodman.go varlink_generate: .gopathok cmd/podman/varlink/ioprojectatomicpodman.go
cmd/podman/ioprojectatomicpodman/ioprojectatomicpodman.go: cmd/podman/ioprojectatomicpodman/io.projectatomic.podman.varlink cmd/podman/varlink/ioprojectatomicpodman.go: cmd/podman/varlink/io.projectatomic.podman.varlink
$(GO) generate ./cmd/podman/ioprojectatomicpodman/... $(GO) generate ./cmd/podman/varlink/...
validate: gofmt .gitvalidation validate: gofmt .gitvalidation

View File

@ -4,6 +4,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -45,7 +46,7 @@ func attachCmd(c *cli.Context) error {
return errors.Errorf("attach requires the name or id of one running container or the latest flag") return errors.Errorf("attach requires the name or id of one running container or the latest flag")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -7,6 +7,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/buildah" "github.com/projectatomic/libpod/libpod/buildah"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
@ -55,7 +56,7 @@ func commitCmd(c *cli.Context) error {
if err := validateFlags(c, commitFlags); err != nil { if err := validateFlags(c, commitFlags); err != nil {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/opencontainers/selinux/go-selinux/label" "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/projectatomic/libpod/pkg/inspect" "github.com/projectatomic/libpod/pkg/inspect"
@ -173,7 +174,7 @@ func createCmd(c *cli.Context) error {
return errors.Errorf("image name or ID is required") return errors.Errorf("image name or ID is required")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -82,7 +83,7 @@ func diffCmd(c *cli.Context) error {
return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME") return errors.Errorf("container, image, or layer name must be specified: podman diff [options [...]] ID-NAME")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -66,7 +67,7 @@ func execCmd(c *cli.Context) error {
argStart = 0 argStart = 0
} }
cmd := args[argStart:] cmd := args[argStart:]
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -4,6 +4,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -34,7 +35,7 @@ func exportCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -83,7 +84,7 @@ func historyCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -10,6 +10,7 @@ import (
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -90,7 +91,7 @@ func imagesCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "Could not get runtime") return errors.Wrapf(err, "Could not get runtime")
} }

View File

@ -7,11 +7,12 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"strings"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/projectatomic/libpod/pkg/util"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -49,7 +50,7 @@ func importCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }
@ -76,7 +77,7 @@ func importCmd(c *cli.Context) error {
changes := v1.ImageConfig{} changes := v1.ImageConfig{}
if c.IsSet("change") { if c.IsSet("change") {
changes, err = getImageConfig(c.StringSlice("change")) changes, err = util.GetImageConfig(c.StringSlice("change"))
if err != nil { if err != nil {
return errors.Wrapf(err, "error adding config changes to image %q", source) return errors.Wrapf(err, "error adding config changes to image %q", source)
} }
@ -138,68 +139,3 @@ func downloadFromURL(source string) (string, error) {
return outFile.Name(), nil return outFile.Name(), nil
} }
// getImageConfig converts the --change flag values in the format "CMD=/bin/bash USER=example"
// to a type v1.ImageConfig
func getImageConfig(changes []string) (v1.ImageConfig, error) {
// USER=value | EXPOSE=value | ENV=value | ENTRYPOINT=value |
// CMD=value | VOLUME=value | WORKDIR=value | LABEL=key=value | STOPSIGNAL=value
var (
user string
env []string
entrypoint []string
cmd []string
workingDir string
stopSignal string
)
exposedPorts := make(map[string]struct{})
volumes := make(map[string]struct{})
labels := make(map[string]string)
for _, ch := range changes {
pair := strings.Split(ch, "=")
if len(pair) == 1 {
return v1.ImageConfig{}, errors.Errorf("no value given for instruction %q", ch)
}
switch pair[0] {
case "USER":
user = pair[1]
case "EXPOSE":
var st struct{}
exposedPorts[pair[1]] = st
case "ENV":
env = append(env, pair[1])
case "ENTRYPOINT":
entrypoint = append(entrypoint, pair[1])
case "CMD":
cmd = append(cmd, pair[1])
case "VOLUME":
var st struct{}
volumes[pair[1]] = st
case "WORKDIR":
workingDir = pair[1]
case "LABEL":
if len(pair) == 3 {
labels[pair[1]] = pair[2]
} else {
labels[pair[1]] = ""
}
case "STOPSIGNAL":
stopSignal = pair[1]
}
}
return v1.ImageConfig{
User: user,
ExposedPorts: exposedPorts,
Env: env,
Entrypoint: entrypoint,
Cmd: cmd,
Volumes: volumes,
WorkingDir: workingDir,
Labels: labels,
StopSignal: stopSignal,
}, nil
}

View File

@ -5,6 +5,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -37,7 +38,7 @@ func infoCmd(c *cli.Context) error {
} }
info := map[string]interface{}{} info := map[string]interface{}{}
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -8,6 +8,7 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/pkg/inspect" "github.com/projectatomic/libpod/pkg/inspect"
"github.com/projectatomic/libpod/pkg/util" "github.com/projectatomic/libpod/pkg/util"
@ -64,7 +65,7 @@ func inspectCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -44,7 +45,7 @@ func killCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -0,0 +1,59 @@
package libpodruntime
import (
"github.com/containers/storage"
"github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli"
)
// GetRuntime generates a new libpod runtime configured by command line options
func GetRuntime(c *cli.Context) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
if c.GlobalIsSet("root") || c.GlobalIsSet("runroot") ||
c.GlobalIsSet("storage-opt") || c.GlobalIsSet("storage-driver") {
storageOpts := storage.DefaultStoreOptions
if c.GlobalIsSet("root") {
storageOpts.GraphRoot = c.GlobalString("root")
}
if c.GlobalIsSet("runroot") {
storageOpts.RunRoot = c.GlobalString("runroot")
}
if c.GlobalIsSet("storage-driver") {
storageOpts.GraphDriverName = c.GlobalString("storage-driver")
}
if c.GlobalIsSet("storage-opt") {
storageOpts.GraphDriverOptions = c.GlobalStringSlice("storage-opt")
}
options = append(options, libpod.WithStorageConfig(storageOpts))
}
// TODO CLI flags for image config?
// TODO CLI flag for signature policy?
if c.GlobalIsSet("runtime") {
options = append(options, libpod.WithOCIRuntime(c.GlobalString("runtime")))
}
if c.GlobalIsSet("conmon") {
options = append(options, libpod.WithConmonPath(c.GlobalString("conmon")))
}
// TODO flag to set CGroup manager?
// TODO flag to set libpod static dir?
// TODO flag to set libpod tmp dir?
if c.GlobalIsSet("cni-config-dir") {
options = append(options, libpod.WithCNIConfigDir(c.GlobalString("cni-config-dir")))
}
if c.GlobalIsSet("default-mounts-file") {
options = append(options, libpod.WithDefaultMountsFile(c.GlobalString("default-mounts-file")))
}
options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path")))
// TODO flag to set CNI plugins dir?
return libpod.NewRuntime(options...)
}

View File

@ -7,6 +7,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
libpodImage "github.com/projectatomic/libpod/libpod/image" libpodImage "github.com/projectatomic/libpod/libpod/image"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -56,7 +57,7 @@ func loadCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -9,6 +9,7 @@ import (
"bufio" "bufio"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -67,7 +68,7 @@ func logsCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
of "github.com/projectatomic/libpod/cmd/podman/formats" of "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -50,7 +51,7 @@ func mountCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -24,7 +25,7 @@ var (
) )
func pauseCmd(c *cli.Context) error { func pauseCmd(c *cli.Context) error {
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -88,7 +89,7 @@ func portCmd(c *cli.Context) error {
} }
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -16,6 +16,7 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/pkg/util" "github.com/projectatomic/libpod/pkg/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -154,7 +155,7 @@ func psCmd(c *cli.Context) error {
return errors.Wrapf(err, "error with flags passed") return errors.Wrapf(err, "error with flags passed")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
image2 "github.com/projectatomic/libpod/libpod/image" image2 "github.com/projectatomic/libpod/libpod/image"
"github.com/projectatomic/libpod/pkg/util" "github.com/projectatomic/libpod/pkg/util"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -59,7 +60,7 @@ var (
// to copy an image from a registry to a local machine // to copy an image from a registry to a local machine
func pullCmd(c *cli.Context) error { func pullCmd(c *cli.Context) error {
forceSecure := false forceSecure := false
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/containers/image/types" "github.com/containers/image/types"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/projectatomic/libpod/pkg/util" "github.com/projectatomic/libpod/pkg/util"
@ -117,7 +118,7 @@ func pushCmd(c *cli.Context) error {
registryCreds = creds registryCreds = creds
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not create runtime") return errors.Wrapf(err, "could not create runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -41,7 +42,7 @@ func restartCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -40,7 +41,7 @@ func rmCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -38,7 +39,7 @@ func rmiCmd(c *cli.Context) error {
return err return err
} }
removeAll := c.Bool("all") removeAll := c.Bool("all")
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/projectatomic/libpod/libpod/image" "github.com/projectatomic/libpod/libpod/image"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -49,7 +50,7 @@ func runCmd(c *cli.Context) error {
} }
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -8,6 +8,7 @@ import (
"github.com/containers/image/manifest" "github.com/containers/image/manifest"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
libpodImage "github.com/projectatomic/libpod/libpod/image" libpodImage "github.com/projectatomic/libpod/libpod/image"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -64,7 +65,7 @@ func saveCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not create runtime") return errors.Wrapf(err, "could not create runtime")
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/containers/image/docker" "github.com/containers/image/docker"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod/common" "github.com/projectatomic/libpod/libpod/common"
sysreg "github.com/projectatomic/libpod/pkg/registries" sysreg "github.com/projectatomic/libpod/pkg/registries"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -92,7 +93,7 @@ func searchCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -67,7 +68,7 @@ func startCmd(c *cli.Context) error {
return errors.Wrapf(libpod.ErrInvalidArg, "you cannot use sig-proxy without --attach") return errors.Wrapf(libpod.ErrInvalidArg, "you cannot use sig-proxy without --attach")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/formats" "github.com/projectatomic/libpod/cmd/podman/formats"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -78,7 +79,7 @@ func statsCmd(c *cli.Context) error {
return errors.Errorf("--all, --latest and containers cannot be used together") return errors.Errorf("--all, --latest and containers cannot be used together")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -54,7 +55,7 @@ func stopCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -21,7 +22,7 @@ func tagCmd(c *cli.Context) error {
if len(args) < 2 { if len(args) < 2 {
return errors.Errorf("image name and at least one new name must be specified") return errors.Errorf("image name and at least one new name must be specified")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not create runtime") return errors.Wrapf(err, "could not create runtime")
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -42,7 +43,7 @@ func topCmd(c *cli.Context) error {
return err return err
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -2,6 +2,7 @@ package main
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -17,7 +18,7 @@ var (
) )
func umountCmd(c *cli.Context) error { func umountCmd(c *cli.Context) error {
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -24,7 +25,7 @@ var (
) )
func unpauseCmd(c *cli.Context) error { func unpauseCmd(c *cli.Context) error {
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get runtime") return errors.Wrapf(err, "could not get runtime")
} }

View File

@ -5,69 +5,15 @@ import (
"os" "os"
gosignal "os/signal" gosignal "os/signal"
"github.com/containers/storage"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/term" "github.com/docker/docker/pkg/term"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
"k8s.io/client-go/tools/remotecommand" "k8s.io/client-go/tools/remotecommand"
) )
// Generate a new libpod runtime configured by command line options
func getRuntime(c *cli.Context) (*libpod.Runtime, error) {
options := []libpod.RuntimeOption{}
if c.GlobalIsSet("root") || c.GlobalIsSet("runroot") ||
c.GlobalIsSet("storage-opt") || c.GlobalIsSet("storage-driver") {
storageOpts := storage.DefaultStoreOptions
if c.GlobalIsSet("root") {
storageOpts.GraphRoot = c.GlobalString("root")
}
if c.GlobalIsSet("runroot") {
storageOpts.RunRoot = c.GlobalString("runroot")
}
if c.GlobalIsSet("storage-driver") {
storageOpts.GraphDriverName = c.GlobalString("storage-driver")
}
if c.GlobalIsSet("storage-opt") {
storageOpts.GraphDriverOptions = c.GlobalStringSlice("storage-opt")
}
options = append(options, libpod.WithStorageConfig(storageOpts))
}
// TODO CLI flags for image config?
// TODO CLI flag for signature policy?
if c.GlobalIsSet("runtime") {
options = append(options, libpod.WithOCIRuntime(c.GlobalString("runtime")))
}
if c.GlobalIsSet("conmon") {
options = append(options, libpod.WithConmonPath(c.GlobalString("conmon")))
}
// TODO flag to set CGroup manager?
// TODO flag to set libpod static dir?
// TODO flag to set libpod tmp dir?
if c.GlobalIsSet("cni-config-dir") {
options = append(options, libpod.WithCNIConfigDir(c.GlobalString("cni-config-dir")))
}
if c.GlobalIsSet("default-mounts-file") {
options = append(options, libpod.WithDefaultMountsFile(c.GlobalString("default-mounts-file")))
}
options = append(options, libpod.WithHooksDir(c.GlobalString("hooks-dir-path")))
// TODO flag to set CNI plugins dir?
return libpod.NewRuntime(options...)
}
// Attach to a container // Attach to a container
func attachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool) error { func attachCtr(ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool) error {
resize := make(chan remotecommand.TerminalSize) resize := make(chan remotecommand.TerminalSize)

View File

@ -2,7 +2,7 @@ package main
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman" ioprojectatomicpodman "github.com/projectatomic/libpod/cmd/podman/varlink"
"github.com/projectatomic/libpod/pkg/varlinkapi" "github.com/projectatomic/libpod/pkg/varlinkapi"
"github.com/projectatomic/libpod/version" "github.com/projectatomic/libpod/version"
"github.com/urfave/cli" "github.com/urfave/cli"
@ -32,7 +32,7 @@ func varlinkCmd(c *cli.Context) error {
return errors.Errorf("you must provide a varlink URI") return errors.Errorf("you must provide a varlink URI")
} }
var varlinkInterfaces = []*ioprojectatomicpodman.VarlinkInterface{varlinkapi.VarlinkLibpod} var varlinkInterfaces = []*ioprojectatomicpodman.VarlinkInterface{varlinkapi.New(c)}
// Register varlink service. The metadata can be retrieved with: // Register varlink service. The metadata can be retrieved with:
// $ varlink info [varlink address URI] // $ varlink info [varlink address URI]
service, err := varlink.NewService( service, err := varlink.NewService(

View File

@ -1,6 +1,8 @@
# Podman Service Interface # Podman Service Interface
interface io.projectatomic.podman interface io.projectatomic.podman
# Version is the structure returned by GetVersion
type Version ( type Version (
version: string, version: string,
go_version: string, go_version: string,
@ -17,6 +19,40 @@ type StringResponse (
message: string message: string
) )
# ImageInList describes the structure that is returned in
# ListImages.
type ImageInList (
id: string,
parentId: string,
repoTags: []string,
repoDigests: []string,
created: string,
size: int,
virtualSize: int,
containers: int,
labels: [string]string
)
# ImageHistory describes the returned structure from ImageHistory.
type ImageHistory (
id: string,
created: string,
createdBy: string,
tags: []string,
size: int,
comment: string
)
# ImageSearch is the returned structure for SearchImage. It is returned
# in arrary form.
type ImageSearch (
description: string,
is_official: bool,
is_automated: bool,
name: string,
star_count: int
)
# System # System
method Ping() -> (ping: StringResponse) method Ping() -> (ping: StringResponse)
method GetVersion() -> (version: Version) method GetVersion() -> (version: Version)
@ -45,21 +81,24 @@ method RemoveContainer() -> (notimplemented: NotImplemented)
method DeleteStoppedContainers() -> (notimplemented: NotImplemented) method DeleteStoppedContainers() -> (notimplemented: NotImplemented)
# Images # Images
method ListImages() -> (notimplemented: NotImplemented) method ListImages() -> (images: []ImageInList)
method BuildImage() -> (notimplemented: NotImplemented) method BuildImage() -> (notimplemented: NotImplemented)
method CreateImage() -> (notimplemented: NotImplemented) method CreateImage() -> (notimplemented: NotImplemented)
method InspectImage() -> (notimplemented: NotImplemented) method InspectImage(name: string) -> (image: string)
method HistoryImage() -> (notimplemented: NotImplemented) method HistoryImage(name: string) -> (history: []ImageHistory)
method PushImage() -> (notimplemented: NotImplemented) method PushImage(name: string, tag: string, tlsverify: bool) -> ()
method TagImage() -> (notimplemented: NotImplemented) method TagImage(name: string, tagged: string) -> ()
method RemoveImage() -> (notimplemented: NotImplemented) method RemoveImage(name: string, force: bool) -> ()
method SearchImage() -> (notimplemented: NotImplemented) method SearchImage(name: string, limit: int) -> (images: []ImageSearch)
method DeleteUnusedImages() -> (notimplemented: NotImplemented) method DeleteUnusedImages() -> (images: []string)
method CreateFromContainer() -> (notimplemented: NotImplemented) method CreateFromContainer() -> (notimplemented: NotImplemented)
method ImportImage() -> (notimplemented: NotImplemented) method ImportImage(source: string, reference: string, message: string, changes: []string) -> (id: string)
method ExportImage() -> (notimplemented: NotImplemented) method ExportImage(name: string, destination: string, compress: bool) -> ()
method PullImage() -> (notimplemented: NotImplemented) method PullImage(name: string) -> (id: string)
# Something failed # Something failed
error ActionFailed (reason: string) error ActionFailed (reason: string)
error ImageNotFound (imagename: string)
error ErrorOccurred (reason: string)
error RuntimeError (reason: string)

View File

@ -5,6 +5,7 @@ import (
"os" "os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -31,7 +32,7 @@ func waitCmd(c *cli.Context) error {
return errors.Errorf("you must provide at least one container name or id") return errors.Errorf("you must provide at least one container name or id")
} }
runtime, err := getRuntime(c) runtime, err := libpodruntime.GetRuntime(c)
if err != nil { if err != nil {
return errors.Wrapf(err, "error creating libpod runtime") return errors.Wrapf(err, "error creating libpod runtime")
} }

View File

@ -0,0 +1,4 @@
#__version__ = version
__title__ = 'libpod'

View File

@ -0,0 +1,45 @@
from varlink import Client
from libpodpy.images import Images
from libpodpy.system import System
from libpodpy.containers import Containers
class LibpodClient(object):
"""
A client for communicating with a Docker server.
Example:
>>> from libpodpy import client
>>> c = client.LibpodClient("unix:/run/podman/io.projectatomic.podman")
Args:
Requires the varlink URI for libpod
"""
def __init__(self, varlink_uri):
c = Client(address=varlink_uri)
self.conn = c.open("io.projectatomic.podman")
@property
def images(self):
"""
An object for managing images through libpod
"""
return Images(self.conn)
@property
def system(self):
"""
An object for system related calls through libpod
"""
return System(self.conn)
@property
def containers(self):
"""
An object for managing containers through libpod
"""
return Containers(self.conn)

View File

@ -0,0 +1,8 @@
class Containers(object):
def __init__(self, client):
self.client = client
def List(self):
pass

View File

@ -0,0 +1,15 @@
class Images(object):
"""
The Images class deals with image related functions for libpod.
"""
def __init__(self, client):
self.client = client
def List(self):
"""
Lists all images in the libpod image store
return: a list of ImageList objects
"""
return self.client.ListImages()

View File

@ -0,0 +1,10 @@
class System(object):
def __init__(self, client):
self.client = client
def Ping(self):
return self.client.Ping()
def Version(self):
return self.client.GetVersion()

View File

@ -274,6 +274,15 @@ func (i *Image) Names() []string {
return i.image.Names return i.image.Names
} }
// RepoDigests returns a string array of repodigests associated with the image
func (i *Image) RepoDigests() []string {
var repoDigests []string
for _, name := range i.Names() {
repoDigests = append(repoDigests, strings.SplitN(name, ":", 2)[0]+"@"+i.Digest().String())
}
return repoDigests
}
// Created returns the time the image was created // Created returns the time the image was created
func (i *Image) Created() time.Time { func (i *Image) Created() time.Time {
return i.image.Created return i.image.Created
@ -778,3 +787,18 @@ func splitString(input string) string {
func (i *Image) InputIsID() bool { func (i *Image) InputIsID() bool {
return strings.HasPrefix(i.ID(), i.InputName) return strings.HasPrefix(i.ID(), i.InputName)
} }
// Containers a list of container IDs associated with the image
func (i *Image) Containers() ([]string, error) {
containers, err := i.imageruntime.store.Containers()
if err != nil {
return nil, err
}
var imageContainers []string
for _, c := range containers {
if c.ImageID == i.ID() {
imageContainers = append(imageContainers, c.ID)
}
}
return imageContainers, err
}

View File

@ -4,7 +4,6 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman"
podmanVersion "github.com/projectatomic/libpod/version" podmanVersion "github.com/projectatomic/libpod/version"
) )
@ -20,7 +19,6 @@ var (
//Version is an output struct for varlink //Version is an output struct for varlink
type Version struct { type Version struct {
ioprojectatomicpodman.VarlinkInterface
Version string Version string
GoVersion string GoVersion string
GitCommit string GitCommit string

View File

@ -5,6 +5,7 @@ import (
"strings" "strings"
"github.com/containers/image/types" "github.com/containers/image/types"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -54,3 +55,68 @@ func StringInSlice(s string, sl []string) bool {
} }
return false return false
} }
// GetImageConfig converts the --change flag values in the format "CMD=/bin/bash USER=example"
// to a type v1.ImageConfig
func GetImageConfig(changes []string) (v1.ImageConfig, error) {
// USER=value | EXPOSE=value | ENV=value | ENTRYPOINT=value |
// CMD=value | VOLUME=value | WORKDIR=value | LABEL=key=value | STOPSIGNAL=value
var (
user string
env []string
entrypoint []string
cmd []string
workingDir string
stopSignal string
)
exposedPorts := make(map[string]struct{})
volumes := make(map[string]struct{})
labels := make(map[string]string)
for _, ch := range changes {
pair := strings.Split(ch, "=")
if len(pair) == 1 {
return v1.ImageConfig{}, errors.Errorf("no value given for instruction %q", ch)
}
switch pair[0] {
case "USER":
user = pair[1]
case "EXPOSE":
var st struct{}
exposedPorts[pair[1]] = st
case "ENV":
env = append(env, pair[1])
case "ENTRYPOINT":
entrypoint = append(entrypoint, pair[1])
case "CMD":
cmd = append(cmd, pair[1])
case "VOLUME":
var st struct{}
volumes[pair[1]] = st
case "WORKDIR":
workingDir = pair[1]
case "LABEL":
if len(pair) == 3 {
labels[pair[1]] = pair[2]
} else {
labels[pair[1]] = ""
}
case "STOPSIGNAL":
stopSignal = pair[1]
}
}
return v1.ImageConfig{
User: user,
ExposedPorts: exposedPorts,
Env: env,
Entrypoint: entrypoint,
Cmd: cmd,
Volumes: volumes,
WorkingDir: workingDir,
Labels: labels,
StopSignal: stopSignal,
}, nil
}

View File

@ -1,14 +1,18 @@
package varlinkapi package varlinkapi
import "github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman" import (
ioprojectatomicpodman "github.com/projectatomic/libpod/cmd/podman/varlink"
"github.com/urfave/cli"
)
// LibpodAPI is the basic varlink struct for libpod // LibpodAPI is the basic varlink struct for libpod
type LibpodAPI struct { type LibpodAPI struct {
Cli *cli.Context
ioprojectatomicpodman.VarlinkInterface ioprojectatomicpodman.VarlinkInterface
} }
var ( // New creates a new varlink client
lp = LibpodAPI{} func New(cli *cli.Context) *ioprojectatomicpodman.VarlinkInterface {
// VarlinkLibpod instantiation lp := LibpodAPI{Cli: cli}
VarlinkLibpod = ioprojectatomicpodman.VarlinkNew(&lp) return ioprojectatomicpodman.VarlinkNew(&lp)
) }

View File

@ -1,7 +1,7 @@
package varlinkapi package varlinkapi
import ( import (
"github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman" ioprojectatomicpodman "github.com/projectatomic/libpod/cmd/podman/varlink"
) )
// ListContainers ... // ListContainers ...

View File

@ -1,75 +1,285 @@
package varlinkapi package varlinkapi
import ( import (
"github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman" "encoding/json"
"fmt"
"github.com/containers/image/docker"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
ioprojectatomicpodman "github.com/projectatomic/libpod/cmd/podman/varlink"
"github.com/projectatomic/libpod/libpod/image"
sysreg "github.com/projectatomic/libpod/pkg/registries"
"github.com/projectatomic/libpod/pkg/util"
) )
// ListImages ... // ListImages lists all the images in the store
// It requires no inputs.
func (i *LibpodAPI) ListImages(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) ListImages(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("ListImages") runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
images, err := runtime.ImageRuntime().GetImages()
if err != nil {
return call.ReplyErrorOccurred(fmt.Sprintf("unable to get list of images %q", err))
}
var imageList []ioprojectatomicpodman.ImageInList
for _, image := range images {
//size, _:= image.Size(getContext())
labels, _ := image.Labels(getContext())
containers, _ := image.Containers()
i := ioprojectatomicpodman.ImageInList{
Id: image.ID(),
ParentId: image.Parent,
RepoTags: image.Names(),
RepoDigests: image.RepoDigests(),
Created: image.Created().String(),
//Size: size,
VirtualSize: image.VirtualSize,
Containers: int64(len(containers)),
Labels: labels,
}
imageList = append(imageList, i)
}
return call.ReplyListImages(imageList)
} }
// BuildImage ... // BuildImage ...
// TODO Waiting for buildah to be vendored into libpod to do this only one
func (i *LibpodAPI) BuildImage(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) BuildImage(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("BuildImage") return call.ReplyMethodNotImplemented("BuildImage")
} }
// CreateImage ... // CreateImage ...
// TODO With Pull being added, should we skip Create?
func (i *LibpodAPI) CreateImage(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) CreateImage(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("CreateImage") return call.ReplyMethodNotImplemented("CreateImage")
} }
// InspectImage ... // InspectImage returns an image's inspect information as a string that can be serialized.
func (i *LibpodAPI) InspectImage(call ioprojectatomicpodman.VarlinkCall) error { // Requires an image ID or name
return call.ReplyMethodNotImplemented("InspectImage") func (i *LibpodAPI) InspectImage(call ioprojectatomicpodman.VarlinkCall, name string) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(name)
}
inspectInfo, err := newImage.Inspect(getContext())
b, err := json.Marshal(inspectInfo)
if err != nil {
return call.ReplyErrorOccurred(fmt.Sprintf("unable to serialize"))
}
return call.ReplyInspectImage(string(b))
} }
// HistoryImage ... // HistoryImage returns the history of the image's layers
func (i *LibpodAPI) HistoryImage(call ioprojectatomicpodman.VarlinkCall) error { // Requires an image or name
return call.ReplyMethodNotImplemented("HistoryImage") func (i *LibpodAPI) HistoryImage(call ioprojectatomicpodman.VarlinkCall, name string) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(name)
}
history, layerInfos, err := newImage.History(getContext())
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
var histories []ioprojectatomicpodman.ImageHistory
for i, h := range history {
imageHistory := ioprojectatomicpodman.ImageHistory{
Id: newImage.ID(),
Created: h.Created.String(),
CreatedBy: h.CreatedBy,
Tags: newImage.Names(),
Size: layerInfos[i].Size,
Comment: h.Comment,
}
histories = append(histories, imageHistory)
}
return call.ReplyHistoryImage(histories)
} }
// PushImage ... // PushImage pushes an local image to registry
func (i *LibpodAPI) PushImage(call ioprojectatomicpodman.VarlinkCall) error { // TODO We need to add options for signing, credentials, and tls
return call.ReplyMethodNotImplemented("PushImage") func (i *LibpodAPI) PushImage(call ioprojectatomicpodman.VarlinkCall, name, tag string, tlsVerify bool) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(err.Error())
}
destname := name
if tag != "" {
destname = tag
} }
// TagImage ... dockerRegistryOptions := image.DockerRegistryOptions{
func (i *LibpodAPI) TagImage(call ioprojectatomicpodman.VarlinkCall) error { DockerInsecureSkipTLSVerify: !tlsVerify,
return call.ReplyMethodNotImplemented("TagImage")
} }
// RemoveImage ... so := image.SigningOptions{}
func (i *LibpodAPI) RemoveImage(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("RemoveImage") if err := newImage.PushImage(getContext(), destname, "", "", "", nil, false, so, &dockerRegistryOptions); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyPushImage()
} }
// SearchImage ... // TagImage accepts an image name and tag as strings and tags an image in the local store.
func (i *LibpodAPI) SearchImage(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) TagImage(call ioprojectatomicpodman.VarlinkCall, name, tag string) error {
return call.ReplyMethodNotImplemented("SearchImage") runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(name)
}
if err := newImage.TagImage(tag); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyTagImage()
} }
// DeleteUnusedImages ... // RemoveImage accepts a image name or ID as a string and force bool to determine if it should
// remove the image even if being used by stopped containers
func (i *LibpodAPI) RemoveImage(call ioprojectatomicpodman.VarlinkCall, name string, force bool) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(name)
}
if err := newImage.Remove(force); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyRemoveImage()
}
// SearchImage searches all registries configured in /etc/containers/registries.conf for an image
// Requires an image name and a search limit as int
func (i *LibpodAPI) SearchImage(call ioprojectatomicpodman.VarlinkCall, name string, limit int64) error {
sc := image.GetSystemContext("", "", false)
registries, err := sysreg.GetRegistries()
if err != nil {
return call.ReplyErrorOccurred(fmt.Sprintf("unable to get system registries: %q", err))
}
var imageResults []ioprojectatomicpodman.ImageSearch
for _, reg := range registries {
results, err := docker.SearchRegistry(getContext(), sc, reg, name, int(limit))
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
for _, result := range results {
i := ioprojectatomicpodman.ImageSearch{
Description: result.Description,
Is_official: result.IsOfficial,
Is_automated: result.IsAutomated,
Name: result.Name,
Star_count: int64(result.StarCount),
}
imageResults = append(imageResults, i)
}
}
return call.ReplySearchImage(imageResults)
}
// DeleteUnusedImages deletes any images that do not have containers associated with it.
// TODO Filters are not implemented
func (i *LibpodAPI) DeleteUnusedImages(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) DeleteUnusedImages(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("DeleteUnusedImages") runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
images, err := runtime.ImageRuntime().GetImages()
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
var deletedImages []string
for _, img := range images {
containers, err := img.Containers()
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
if len(containers) == 0 {
if err := img.Remove(false); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
deletedImages = append(deletedImages, img.ID())
}
}
return call.ReplyDeleteUnusedImages(deletedImages)
} }
// CreateFromContainer ... // CreateFromContainer ...
// TODO This must wait until buildah is properly vendored into libpod
func (i *LibpodAPI) CreateFromContainer(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) CreateFromContainer(call ioprojectatomicpodman.VarlinkCall) error {
return call.ReplyMethodNotImplemented("CreateFromContainer") return call.ReplyMethodNotImplemented("CreateFromContainer")
} }
// ImportImage ... // ImportImage imports an image from a tarball to the image store
func (i *LibpodAPI) ImportImage(call ioprojectatomicpodman.VarlinkCall) error { func (i *LibpodAPI) ImportImage(call ioprojectatomicpodman.VarlinkCall, source, reference, message string, changes []string) error {
return call.ReplyMethodNotImplemented("ImportImage") runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
configChanges, err := util.GetImageConfig(changes)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
history := []v1.History{
{Comment: message},
}
config := v1.Image{
Config: configChanges,
History: history,
}
newImage, err := runtime.ImageRuntime().Import(getContext(), source, reference, nil, image.SigningOptions{}, config)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyImportImage(newImage.ID())
} }
// ExportImage ... // ExportImage exports an image to the provided destination
func (i *LibpodAPI) ExportImage(call ioprojectatomicpodman.VarlinkCall) error { // destination must have the transport type!!
return call.ReplyMethodNotImplemented("ExportImage") func (i *LibpodAPI) ExportImage(call ioprojectatomicpodman.VarlinkCall, name, destination string, compress bool) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().NewFromLocal(name)
if err != nil {
return call.ReplyImageNotFound(name)
}
if err := newImage.PushImage(getContext(), destination, "", "", "", nil, compress, image.SigningOptions{}, &image.DockerRegistryOptions{}); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyExportImage()
} }
// PullImage ... // PullImage pulls an image from a registry to the image store.
func (i *LibpodAPI) PullImage(call ioprojectatomicpodman.VarlinkCall) error { // TODO This implementation is incomplete
return call.ReplyMethodNotImplemented("PullImage") func (i *LibpodAPI) PullImage(call ioprojectatomicpodman.VarlinkCall, name string) error {
runtime, err := libpodruntime.GetRuntime(i.Cli)
if err != nil {
return call.ReplyRuntimeError(err.Error())
}
newImage, err := runtime.ImageRuntime().New(getContext(), name, "", "", nil, &image.DockerRegistryOptions{}, image.SigningOptions{}, true, false)
if err != nil {
return call.ReplyErrorOccurred(fmt.Sprintf("unable to pull %s", name))
}
return call.ReplyPullImage(newImage.ID())
} }

View File

@ -1,7 +1,7 @@
package varlinkapi package varlinkapi
import ( import (
"github.com/projectatomic/libpod/cmd/podman/ioprojectatomicpodman" ioprojectatomicpodman "github.com/projectatomic/libpod/cmd/podman/varlink"
"github.com/projectatomic/libpod/libpod" "github.com/projectatomic/libpod/libpod"
) )

10
pkg/varlinkapi/util.go Normal file
View File

@ -0,0 +1,10 @@
package varlinkapi
import (
"context"
)
// getContext returns a non-nil, empty context
func getContext() context.Context {
return context.TODO()
}

View File

@ -1,9 +0,0 @@
from varlink import (Client, VarlinkError)
import json
address = "unix:/run/podman/io.projectatomic.podman"
with Client(address=address) as client:
podman = client.open('io.projectatomic.podman')
response = podman.GetVersion()
print(json.dumps(response, indent=4, separators=(',', ': ')))