podman-remote inspect

base enablement of the inspect command.

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2019-01-17 08:43:34 -06:00
parent f897cccbde
commit eadaa5fb42
20 changed files with 344 additions and 111 deletions

36
API.md
View File

@ -9,14 +9,22 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) string](#Commit)
[func ContainerArtifacts(name: string, artifactName: string) string](#ContainerArtifacts)
[func ContainerCheckpoint(name: string, keep: bool, leaveRunning: bool, tcpEstablished: bool) string](#ContainerCheckpoint)
[func ContainerConfig(name: string) string](#ContainerConfig)
[func ContainerExists(name: string) int](#ContainerExists)
[func ContainerInspectData(name: string) string](#ContainerInspectData)
[func ContainerRestore(name: string, keep: bool, tcpEstablished: bool) string](#ContainerRestore)
[func ContainerRunlabel(runlabel: Runlabel) ](#ContainerRunlabel)
[func ContainerStateData(name: string) string](#ContainerStateData)
[func CreateContainer(create: Create) string](#CreateContainer)
[func CreateImage() NotImplemented](#CreateImage)
@ -239,12 +247,24 @@ attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, ONBUILD, STOPSIGNAL, USER, VOL
container while it is being committed, pass a _true_ bool for the pause argument. If the container cannot
be found by the ID or name provided, a (ContainerNotFound)[#ContainerNotFound] error will be returned; otherwise,
the resulting image's ID will be returned as a string.
### <a name="ContainerArtifacts"></a>func ContainerArtifacts
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerArtifacts(name: [string](https://godoc.org/builtin#string), artifactName: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
ContainerArtifacts returns a container's artifacts in string form. This call is for
development of Podman only and generally should not be used.
### <a name="ContainerCheckpoint"></a>func ContainerCheckpoint
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerCheckpoint(name: [string](https://godoc.org/builtin#string), keep: [bool](https://godoc.org/builtin#bool), leaveRunning: [bool](https://godoc.org/builtin#bool), tcpEstablished: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)</div>
ContainerCheckPoint performs a checkpopint on a container by its name or full/partial container
ID. On successful checkpoint, the id of the checkpointed container is returned.
### <a name="ContainerConfig"></a>func ContainerConfig
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerConfig(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
ContainerConfig returns a container's config in string form. This call is for
development of Podman only and generally should not be used.
### <a name="ContainerExists"></a>func ContainerExists
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -258,6 +278,12 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ContainerExists '{"name":
"exists": 0
}
~~~
### <a name="ContainerInspectData"></a>func ContainerInspectData
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerInspectData(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
ContainerInspectData returns a container's inspect data in string form. This call is for
development of Podman only and generally should not be used.
### <a name="ContainerRestore"></a>func ContainerRestore
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -270,6 +296,12 @@ of the container's ID.
method ContainerRunlabel(runlabel: [Runlabel](#Runlabel)) </div>
ContainerRunlabel runs executes a command as described by a given container image label.
### <a name="ContainerStateData"></a>func ContainerStateData
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerStateData(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
ContainerStateData returns a container's state config in string form. This call is for
development of Podman only and generally should not be used.
### <a name="CreateContainer"></a>func CreateContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -1373,6 +1405,8 @@ virtualSize [int](https://godoc.org/builtin#int)
containers [int](https://godoc.org/builtin#int)
labels [map[string]](#map[string])
isParent [bool](https://godoc.org/builtin#bool)
### <a name="ImageSearch"></a>type ImageSearch
ImageSearch is the returned structure for SearchImage. It is returned
@ -1460,7 +1494,7 @@ graph_status [InfoGraphStatus](#InfoGraphStatus)
run_root [string](https://godoc.org/builtin#string)
### <a name="ListContainerData"></a>type ListContainerData
ListContainer is the returned struct for an individual container
ListContainerData is the returned struct for an individual container
id [string](https://godoc.org/builtin#string)

View File

@ -2,12 +2,13 @@ package main
import (
"context"
"encoding/json"
"strings"
"github.com/containers/libpod/cmd/podman/formats"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/adapter"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/urfave/cli"
@ -63,7 +64,7 @@ func inspectCmd(c *cli.Context) error {
return err
}
runtime, err := libpodruntime.GetRuntime(c)
runtime, err := adapter.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
@ -104,7 +105,7 @@ func inspectCmd(c *cli.Context) error {
}
// func iterateInput iterates the images|containers the user has requested and returns the inspect data and error
func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *libpod.Runtime, inspectType string) ([]interface{}, error) {
func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *adapter.LocalRuntime, inspectType string) ([]interface{}, error) {
var (
data interface{}
inspectedItems []interface{}
@ -124,13 +125,18 @@ func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *l
inspectError = errors.Wrapf(err, "error getting libpod container inspect data %s", ctr.ID())
break
}
data, err = shared.GetCtrInspectInfo(ctr, libpodInspectData)
artifact, err := getArtifact(ctr)
if inspectError != nil {
inspectError = err
break
}
data, err = shared.GetCtrInspectInfo(ctr.Config(), libpodInspectData, artifact)
if err != nil {
inspectError = errors.Wrapf(err, "error parsing container data %q", ctr.ID())
break
}
case inspectTypeImage:
image, err := runtime.ImageRuntime().NewFromLocal(input)
image, err := runtime.NewImageFromLocal(input)
if err != nil {
inspectError = errors.Wrapf(err, "error getting image %q", input)
break
@ -143,7 +149,7 @@ func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *l
case inspectAll:
ctr, err := runtime.LookupContainer(input)
if err != nil {
image, err := runtime.ImageRuntime().NewFromLocal(input)
image, err := runtime.NewImageFromLocal(input)
if err != nil {
inspectError = errors.Wrapf(err, "error getting image %q", input)
break
@ -159,7 +165,12 @@ func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *l
inspectError = errors.Wrapf(err, "error getting libpod container inspect data %s", ctr.ID())
break
}
data, err = shared.GetCtrInspectInfo(ctr, libpodInspectData)
artifact, inspectError := getArtifact(ctr)
if inspectError != nil {
inspectError = err
break
}
data, err = shared.GetCtrInspectInfo(ctr.Config(), libpodInspectData, artifact)
if err != nil {
inspectError = errors.Wrapf(err, "error parsing container data %s", ctr.ID())
break
@ -172,3 +183,15 @@ func iterateInput(ctx context.Context, c *cli.Context, args []string, runtime *l
}
return inspectedItems, inspectError
}
func getArtifact(ctr *adapter.Container) (*cc.CreateConfig, error) {
var createArtifact cc.CreateConfig
artifact, err := ctr.GetArtifact("create-config")
if err != nil {
return nil, err
}
if err := json.Unmarshal(artifact, &createArtifact); err != nil {
return nil, err
}
return &createArtifact, nil
}

View File

@ -2,7 +2,6 @@ package shared
import (
"context"
"encoding/json"
"fmt"
"github.com/google/shlex"
"io"
@ -446,8 +445,7 @@ func getStrFromSquareBrackets(cmd string) string {
// GetCtrInspectInfo takes container inspect data and collects all its info into a ContainerData
// structure for inspection related methods
func GetCtrInspectInfo(ctr *libpod.Container, ctrInspectData *inspect.ContainerInspectData) (*inspect.ContainerData, error) {
config := ctr.Config()
func GetCtrInspectInfo(config *libpod.ContainerConfig, ctrInspectData *inspect.ContainerInspectData, createArtifact *cc.CreateConfig) (*inspect.ContainerData, error) {
spec := config.Spec
cpus, mems, period, quota, realtimePeriod, realtimeRuntime, shares := getCPUInfo(spec)
@ -456,16 +454,6 @@ func GetCtrInspectInfo(ctr *libpod.Container, ctrInspectData *inspect.ContainerI
pidsLimit := getPidsInfo(spec)
cgroup := getCgroup(spec)
var createArtifact cc.CreateConfig
artifact, err := ctr.GetArtifact("create-config")
if err == nil {
if err := json.Unmarshal(artifact, &createArtifact); err != nil {
return nil, err
}
} else {
logrus.Errorf("couldn't get some inspect information, error getting artifact %q: %v", ctr.ID(), err)
}
data := &inspect.ContainerData{
ctrInspectData,
&inspect.HostConfig{
@ -493,7 +481,7 @@ func GetCtrInspectInfo(ctr *libpod.Container, ctrInspectData *inspect.ContainerI
PidsLimit: pidsLimit,
Privileged: config.Privileged,
ReadonlyRootfs: spec.Root.Readonly,
Runtime: ctr.RuntimeName(),
Runtime: config.OCIRuntime,
NetworkMode: string(createArtifact.NetMode),
IpcMode: string(createArtifact.IpcMode),
Cgroup: cgroup,

View File

@ -1035,6 +1035,22 @@ method GenerateKubeService() -> (notimplemented: NotImplemented)
# like that created by GenerateKube. See also [GenerateKube](GenerateKube).
method ReplayKube() -> (notimplemented: NotImplemented)
# ContainerConfig returns a container's config in string form. This call is for
# development of Podman only and generally should not be used.
method ContainerConfig(name: string) -> (config: string)
# ContainerArtifacts returns a container's artifacts in string form. This call is for
# development of Podman only and generally should not be used.
method ContainerArtifacts(name: string, artifactName: string) -> (config: string)
# ContainerInspectData returns a container's inspect data in string form. This call is for
# development of Podman only and generally should not be used.
method ContainerInspectData(name: string) -> (config: string)
# ContainerStateData returns a container's state config in string form. This call is for
# development of Podman only and generally should not be used.
method ContainerStateData(name: string) -> (config: string)
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
error ImageNotFound (name: string)

View File

@ -0,0 +1,50 @@
// +build remoteclient
package adapter
import (
"encoding/json"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/inspect"
)
// Inspect returns an inspect struct from varlink
func (c *Container) Inspect(size bool) (*inspect.ContainerInspectData, error) {
reply, err := iopodman.ContainerInspectData().Call(c.Runtime.Conn, c.ID())
if err != nil {
return nil, err
}
data := inspect.ContainerInspectData{}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
return nil, err
}
return &data, err
}
// ID returns the ID of the container
func (c *Container) ID() string {
return c.config.ID
}
// GetArtifact returns a container's artifacts
func (c *Container) GetArtifact(name string) ([]byte, error) {
var data []byte
reply, err := iopodman.ContainerArtifacts().Call(c.Runtime.Conn, c.ID(), name)
if err != nil {
return nil, err
}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
return nil, err
}
return data, err
}
// Config returns a container's Config ... same as ctr.Config()
func (c *Container) Config() *libpod.ContainerConfig {
if c.config != nil {
return c.config
}
return c.Runtime.Config(c.ID())
}

View File

@ -3,15 +3,22 @@
package adapter
import (
"github.com/containers/libpod/libpod"
"context"
"encoding/json"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/pkg/inspect"
)
// Images returns information for the host system and its components
func (r RemoteRuntime) Images() ([]libpod.InfoData, error) {
conn, err := r.Connect()
// Inspect returns returns an ImageData struct from over a varlink connection
func (i *ContainerImage) Inspect(ctx context.Context) (*inspect.ImageData, error) {
reply, err := iopodman.InspectImage().Call(i.Runtime.Conn, i.ID())
if err != nil {
return nil, err
}
_ = conn
return nil, nil
data := inspect.ImageData{}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
return nil, err
}
return &data, nil
}

View File

@ -4,15 +4,18 @@ package adapter
import (
"context"
"encoding/json"
"fmt"
"io"
"strings"
"time"
"github.com/containers/image/types"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/image"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
"github.com/varlink/go/varlink"
)
@ -80,21 +83,9 @@ type Container struct {
// remoteContainer ....
type remoteContainer struct {
ID string
Image string
ImageID string
Command []string
Created time.Time
RunningFor string
Status string
//Ports []ocicni.PortMapping
RootFsSize int64
RWSize int64
Names string
Labels []map[string]string
// Mounts []string
// ContainerRunning bool
//Namespaces []LinuxNameSpace
Runtime *LocalRuntime
config *libpod.ContainerConfig
state *libpod.ContainerState
}
// GetImages returns a slice of containerimages over a varlink connection
@ -272,39 +263,60 @@ func (ci *ContainerImage) History(ctx context.Context) ([]*image.History, error)
// LookupContainer gets basic information about container over a varlink
// connection and then translates it to a *Container
func (r *RemoteRuntime) LookupContainer(idOrName string) (*Container, error) {
container, err := iopodman.GetContainer().Call(r.Conn, idOrName)
func (r *LocalRuntime) LookupContainer(idOrName string) (*Container, error) {
state, err := r.ContainerState(idOrName)
if err != nil {
return nil, err
}
return listContainerDataToContainer(container)
config := r.Config(idOrName)
if err != nil {
return nil, err
}
rc := remoteContainer{
r,
config,
state,
}
c := Container{
rc,
}
return &c, nil
}
// listContainerDataToContainer takes a varlink listcontainerData struct and makes
// an "adapted" Container
func listContainerDataToContainer(listData iopodman.ListContainerData) (*Container, error) {
created, err := splitStringDate(listData.Createdat)
func (r *LocalRuntime) GetLatestContainer() (*Container, error) {
return nil, libpod.ErrNotImplemented
}
// ContainerState returns the "state" of the container.
func (r *LocalRuntime) ContainerState(name string) (*libpod.ContainerState, error) { //no-lint
reply, err := iopodman.ContainerStateData().Call(r.Conn, name)
if err != nil {
return nil, err
}
rc := remoteContainer{
// TODO commented out attributes will be populated when podman-remote ps
// is implemented. They are not needed yet for basic container operations.
ID: listData.Id,
Image: listData.Image,
ImageID: listData.Imageid,
Command: listData.Command,
Created: created,
RunningFor: listData.Runningfor,
Status: listData.Status,
//ports:
RootFsSize: listData.Rootfssize,
RWSize: listData.Rwsize,
Names: listData.Names,
//Labels:
//Mounts
//ContainerRunning:
//namespaces:
data := libpod.ContainerState{}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
return nil, err
}
return &Container{rc}, nil
return &data, err
}
// Config returns a container config
func (r *LocalRuntime) Config(name string) *libpod.ContainerConfig {
// TODO the Spec being returned is not populated. Matt and I could not figure out why. Will defer
// further looking into it for after devconf.
// The libpod function for this has no errors so we are kind of in a tough
// spot here. Logging the errors for now.
reply, err := iopodman.ContainerConfig().Call(r.Conn, name)
if err != nil {
logrus.Error("call to container.config failed")
}
data := libpod.ContainerConfig{}
if err := json.Unmarshal([]byte(reply), &data); err != nil {
logrus.Error("failed to unmarshal container inspect data")
}
return &data
}

View File

@ -205,7 +205,7 @@ func (s *BoltState) Refresh() error {
return errors.Wrapf(ErrInternal, "container %s missing state in DB", string(id))
}
state := new(containerState)
state := new(ContainerState)
if err := json.Unmarshal(stateBytes, state); err != nil {
return errors.Wrapf(err, "error unmarshalling state for container %s", string(id))
@ -325,7 +325,7 @@ func (s *BoltState) Container(id string) (*Container, error) {
ctr := new(Container)
ctr.config = new(ContainerConfig)
ctr.state = new(containerState)
ctr.state = new(ContainerState)
db, err := s.getDBCon()
if err != nil {
@ -361,7 +361,7 @@ func (s *BoltState) LookupContainer(idOrName string) (*Container, error) {
ctr := new(Container)
ctr.config = new(ContainerConfig)
ctr.state = new(containerState)
ctr.state = new(ContainerState)
db, err := s.getDBCon()
if err != nil {
@ -542,7 +542,7 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
return errors.Wrapf(ErrNSMismatch, "container %s is in namespace %q, does not match our namespace %q", ctr.ID(), ctr.config.Namespace, s.namespace)
}
newState := new(containerState)
newState := new(ContainerState)
netNSPath := ""
ctrID := []byte(ctr.ID())
@ -754,7 +754,7 @@ func (s *BoltState) AllContainers() ([]*Container, error) {
ctr := new(Container)
ctr.config = new(ContainerConfig)
ctr.state = new(containerState)
ctr.state = new(ContainerState)
if err := s.getContainerFromDB(id, ctr, ctrBucket); err != nil {
// If the error is a namespace mismatch, we can
@ -1140,7 +1140,7 @@ func (s *BoltState) PodContainers(pod *Pod) ([]*Container, error) {
err = podCtrs.ForEach(func(id, val []byte) error {
newCtr := new(Container)
newCtr.config = new(ContainerConfig)
newCtr.state = new(containerState)
newCtr.state = new(ContainerState)
ctrs = append(ctrs, newCtr)
return s.getContainerFromDB(id, newCtr, ctrBkt)

View File

@ -8,7 +8,7 @@ import (
// replaceNetNS handle network namespace transitions after updating a
// container's state.
func replaceNetNS(netNSPath string, ctr *Container, newState *containerState) error {
func replaceNetNS(netNSPath string, ctr *Container, newState *ContainerState) error {
if netNSPath != "" {
// Check if the container's old state has a good netns
if ctr.state.NetNS != nil && netNSPath == ctr.state.NetNS.Path() {

View File

@ -3,7 +3,7 @@
package libpod
// replaceNetNS is exclusive to the Linux platform and is a no-op elsewhere
func replaceNetNS(netNSPath string, ctr *Container, newState *containerState) error {
func replaceNetNS(netNSPath string, ctr *Container, newState *ContainerState) error {
return nil
}

View File

@ -48,7 +48,7 @@ func getTestContainer(id, name string, manager lock.Manager) (*Container, error)
},
},
},
state: &containerState{
state: &ContainerState{
State: ContainerStateRunning,
ConfigPath: "/does/not/exist/specs/" + id,
RunDir: "/does/not/exist/tmp/",
@ -166,10 +166,10 @@ func testContainersEqual(t *testing.T, a, b *Container, allowedEmpty bool) {
aConfig := new(ContainerConfig)
bConfig := new(ContainerConfig)
aState := new(containerState)
bState := new(containerState)
aState := new(ContainerState)
bState := new(ContainerState)
blankState := new(containerState)
blankState := new(ContainerState)
assert.Equal(t, a.valid, b.valid)

View File

@ -116,7 +116,7 @@ func (ns LinuxNS) String() string {
type Container struct {
config *ContainerConfig
state *containerState
state *ContainerState
// Batched indicates that a container has been locked as part of a
// Batch() operation
@ -136,10 +136,10 @@ type Container struct {
requestedIP net.IP
}
// containerState contains the current state of the container
// ContainerState contains the current state of the container
// It is stored on disk in a tmpfs and recreated on reboot
// easyjson:json
type containerState struct {
type ContainerState struct {
// The current state of the running container
State ContainerStatus `json:"state"`
// The path to the JSON OCI runtime spec for this container
@ -1063,3 +1063,18 @@ func networkDisabled(c *Container) (bool, error) {
}
return false, nil
}
// ContainerState returns containerstate struct
func (c *Container) ContainerState() (*ContainerState, error) {
if !c.batched {
c.lock.Lock()
defer c.lock.Unlock()
if err := c.syncContainer(); err != nil {
return nil, err
}
}
returnConfig := new(ContainerState)
deepcopier.Copy(c.state).To(returnConfig)
return c.state, nil
}

View File

@ -388,7 +388,7 @@ func (c *Container) teardownStorage() error {
// Reset resets state fields to default values
// It is performed before a refresh and clears the state after a reboot
// It does not save the results - assumes the database will do that for us
func resetState(state *containerState) error {
func resetState(state *ContainerState) error {
state.PID = 0
state.Mountpoint = ""
state.Mounted = false

View File

@ -37,7 +37,7 @@ func TestPostDeleteHooks(t *testing.T) {
},
StaticDir: dir, // not the bundle, but good enough for this test
},
state: &containerState{
state: &ContainerState{
ExtensionStageHooks: map[string][]rspec.Hook{
"poststop": {
rspec.Hook{

View File

@ -48,7 +48,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
ctr := new(Container)
ctr.config = new(ContainerConfig)
ctr.state = new(containerState)
ctr.state = new(ContainerState)
ctr.config.ID = stringid.GenerateNonCryptoID()

View File

@ -12,6 +12,7 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/storage/pkg/archive"
"github.com/pkg/errors"
)
@ -68,7 +69,12 @@ func (i *LibpodAPI) InspectContainer(call iopodman.VarlinkCall, name string) err
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
data, err := shared.GetCtrInspectInfo(ctr, inspectInfo)
artifact, err := getArtifact(ctr)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
data, err := shared.GetCtrInspectInfo(ctr.Config(), inspectInfo, artifact)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
@ -462,3 +468,81 @@ func (i *LibpodAPI) ContainerRestore(call iopodman.VarlinkCall, name string, kee
}
return call.ReplyContainerRestore(ctr.ID())
}
func getArtifact(ctr *libpod.Container) (*cc.CreateConfig, error) {
var createArtifact cc.CreateConfig
artifact, err := ctr.GetArtifact("create-config")
if err != nil {
return nil, err
}
if err := json.Unmarshal(artifact, &createArtifact); err != nil {
return nil, err
}
return &createArtifact, nil
}
// ContainerConfig returns just the container.config struct
func (i *LibpodAPI) ContainerConfig(call iopodman.VarlinkCall, name string) error {
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
config := ctr.Config()
b, err := json.Marshal(config)
if err != nil {
return call.ReplyErrorOccurred("unable to serialize container config")
}
return call.ReplyContainerConfig(string(b))
}
// ContainerArtifacts returns an untouched container's artifact in string format
func (i *LibpodAPI) ContainerArtifacts(call iopodman.VarlinkCall, name, artifactName string) error {
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
artifacts, err := ctr.GetArtifact(artifactName)
if err != nil {
return call.ReplyErrorOccurred("unable to get container artifacts")
}
b, err := json.Marshal(artifacts)
if err != nil {
return call.ReplyErrorOccurred("unable to serialize container artifacts")
}
return call.ReplyContainerArtifacts(string(b))
}
// ContainerInspectData returns the inspect data of a container in string format
func (i *LibpodAPI) ContainerInspectData(call iopodman.VarlinkCall, name string) error {
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
data, err := ctr.Inspect(true)
if err != nil {
return call.ReplyErrorOccurred("unable to inspect container")
}
b, err := json.Marshal(data)
if err != nil {
return call.ReplyErrorOccurred("unable to serialize container inspect data")
}
return call.ReplyContainerInspectData(string(b))
}
// ContainerStateData returns a container's state data in string format
func (i *LibpodAPI) ContainerStateData(call iopodman.VarlinkCall, name string) error {
ctr, err := i.Runtime.LookupContainer(name)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
data, err := ctr.ContainerState()
if err != nil {
return call.ReplyErrorOccurred("unable to obtain container state")
}
b, err := json.Marshal(data)
if err != nil {
return call.ReplyErrorOccurred("unable to serialize container inspect data")
}
return call.ReplyContainerStateData(string(b))
}

View File

@ -1,17 +1,19 @@
package integration
import (
"encoding/json"
"fmt"
. "github.com/containers/libpod/test/utils"
"os"
"os/exec"
"github.com/containers/storage/pkg/reexec"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"path/filepath"
"strings"
"testing"
"github.com/containers/libpod/pkg/inspect"
. "github.com/containers/libpod/test/utils"
"github.com/containers/storage/pkg/reexec"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var (
@ -227,3 +229,12 @@ func (p *PodmanTestIntegration) CreateArtifact(image string) error {
}
return nil
}
// InspectImageJSON takes the session output of an inspect
// image and returns json
func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
var i []inspect.ImageData
err := json.Unmarshal(s.Out.Contents(), &i)
Expect(err).To(BeNil())
return i
}

View File

@ -1,5 +1,3 @@
// +build !remoteclient
package integration
import (
@ -45,6 +43,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect bogus container", func() {
SkipIfRemote()
session := podmanTest.Podman([]string{"inspect", "foobar4321"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
@ -68,6 +67,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect container with size", func() {
SkipIfRemote()
_, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
@ -79,6 +79,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect container and image", func() {
SkipIfRemote()
ls, ec, _ := podmanTest.RunLsContainer("")
Expect(ec).To(Equal(0))
cid := ls.OutputToString()
@ -90,6 +91,7 @@ var _ = Describe("Podman inspect", func() {
})
It("podman inspect -l with additional input should fail", func() {
SkipIfRemote()
result := podmanTest.Podman([]string{"inspect", "-l", "1234foobar"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(125))

View File

@ -55,10 +55,10 @@ func (p *PodmanTestIntegration) RunLsContainer(name string) (*PodmanSessionInteg
// InspectImageJSON takes the session output of an inspect
// image and returns json
func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
// TODO
return nil
}
//func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
// // TODO
// return nil
//}
func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() {
defaultFile := filepath.Join(INTEGRATION_ROOT, "test/registries.conf")

View File

@ -118,15 +118,6 @@ func (s *PodmanSessionIntegration) InspectPodToJSON() libpod.PodInspect {
return i
}
// InspectImageJSON takes the session output of an inspect
// image and returns json
func (s *PodmanSessionIntegration) InspectImageJSON() []inspect.ImageData {
var i []inspect.ImageData
err := json.Unmarshal(s.Out.Contents(), &i)
Expect(err).To(BeNil())
return i
}
// CreatePod creates a pod with no infra container
// it optionally takes a pod name
func (p *PodmanTestIntegration) CreatePod(name string) (*PodmanSessionIntegration, int, string) {