mirror of
https://github.com/containers/podman.git
synced 2025-06-06 15:00:40 +08:00
podman-remote inspect
base enablement of the inspect command. Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
36
API.md
36
API.md
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
50
libpod/adapter/containers_remote.go
Normal file
50
libpod/adapter/containers_remote.go
Normal 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())
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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{
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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")
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user