diff options
author | baude <bbaude@redhat.com> | 2019-01-17 08:43:34 -0600 |
---|---|---|
committer | baude <bbaude@redhat.com> | 2019-01-18 15:43:11 -0600 |
commit | eadaa5fb420e3e8e6b0e277ac88cc528f9950ee4 (patch) | |
tree | a846f4b272229aaf51e4cca161bfe9b5268d7613 /libpod | |
parent | f897cccbdeb2c1e92b9a1b866128a67d5ccb957d (diff) | |
download | podman-eadaa5fb420e3e8e6b0e277ac88cc528f9950ee4.tar.gz podman-eadaa5fb420e3e8e6b0e277ac88cc528f9950ee4.tar.bz2 podman-eadaa5fb420e3e8e6b0e277ac88cc528f9950ee4.zip |
podman-remote inspect
base enablement of the inspect command.
Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/adapter/containers_remote.go | 50 | ||||
-rw-r--r-- | libpod/adapter/images_remote.go | 19 | ||||
-rw-r--r-- | libpod/adapter/runtime_remote.go | 98 | ||||
-rw-r--r-- | libpod/boltdb_state.go | 12 | ||||
-rw-r--r-- | libpod/boltdb_state_linux.go | 2 | ||||
-rw-r--r-- | libpod/boltdb_state_unsupported.go | 2 | ||||
-rw-r--r-- | libpod/common_test.go | 8 | ||||
-rw-r--r-- | libpod/container.go | 21 | ||||
-rw-r--r-- | libpod/container_internal.go | 2 | ||||
-rw-r--r-- | libpod/container_internal_test.go | 2 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 2 |
11 files changed, 151 insertions, 67 deletions
diff --git a/libpod/adapter/containers_remote.go b/libpod/adapter/containers_remote.go new file mode 100644 index 000000000..9623304e5 --- /dev/null +++ b/libpod/adapter/containers_remote.go @@ -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()) +} diff --git a/libpod/adapter/images_remote.go b/libpod/adapter/images_remote.go index 77b0629a7..e7b38dccc 100644 --- a/libpod/adapter/images_remote.go +++ b/libpod/adapter/images_remote.go @@ -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 } diff --git a/libpod/adapter/runtime_remote.go b/libpod/adapter/runtime_remote.go index 8ef8fe167..7189348bc 100644 --- a/libpod/adapter/runtime_remote.go +++ b/libpod/adapter/runtime_remote.go @@ -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 +} + +func (r *LocalRuntime) GetLatestContainer() (*Container, error) { + return nil, libpod.ErrNotImplemented } -// listContainerDataToContainer takes a varlink listcontainerData struct and makes -// an "adapted" Container -func listContainerDataToContainer(listData iopodman.ListContainerData) (*Container, error) { - created, err := splitStringDate(listData.Createdat) +// 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 + } diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index e7a07a9a8..5bc15dd7f 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -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) diff --git a/libpod/boltdb_state_linux.go b/libpod/boltdb_state_linux.go index d91f311e5..09a9be606 100644 --- a/libpod/boltdb_state_linux.go +++ b/libpod/boltdb_state_linux.go @@ -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() { diff --git a/libpod/boltdb_state_unsupported.go b/libpod/boltdb_state_unsupported.go index 64610d304..244dc51a0 100644 --- a/libpod/boltdb_state_unsupported.go +++ b/libpod/boltdb_state_unsupported.go @@ -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 } diff --git a/libpod/common_test.go b/libpod/common_test.go index 4af68a040..df730098e 100644 --- a/libpod/common_test.go +++ b/libpod/common_test.go @@ -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) diff --git a/libpod/container.go b/libpod/container.go index b5f6a29ba..b0589be3b 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -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 +} diff --git a/libpod/container_internal.go b/libpod/container_internal.go index ce8791f08..39c1501da 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -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 diff --git a/libpod/container_internal_test.go b/libpod/container_internal_test.go index 124f1d20e..f1e2b70a7 100644 --- a/libpod/container_internal_test.go +++ b/libpod/container_internal_test.go @@ -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{ diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index 68599fe6d..6d5ce5a7e 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -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() |