diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
---|---|---|
committer | Matthew Heon <matthew.heon@gmail.com> | 2017-11-01 11:24:59 -0400 |
commit | a031b83a09a8628435317a03f199cdc18b78262f (patch) | |
tree | bc017a96769ce6de33745b8b0b1304ccf38e9df0 /libkpod/container.go | |
parent | 2b74391cd5281f6fdf391ff8ad50fd1490f6bf89 (diff) | |
download | podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.gz podman-a031b83a09a8628435317a03f199cdc18b78262f.tar.bz2 podman-a031b83a09a8628435317a03f199cdc18b78262f.zip |
Initial checkin from CRI-O repo
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Diffstat (limited to 'libkpod/container.go')
-rw-r--r-- | libkpod/container.go | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/libkpod/container.go b/libkpod/container.go new file mode 100644 index 000000000..7835952d2 --- /dev/null +++ b/libkpod/container.go @@ -0,0 +1,157 @@ +package libkpod + +import ( + "fmt" + + cstorage "github.com/containers/storage" + "github.com/kubernetes-incubator/cri-o/libkpod/sandbox" + "github.com/kubernetes-incubator/cri-o/oci" + "github.com/kubernetes-incubator/cri-o/pkg/registrar" + "github.com/pkg/errors" +) + +// GetStorageContainer searches for a container with the given name or ID in the given store +func (c *ContainerServer) GetStorageContainer(container string) (*cstorage.Container, error) { + ociCtr, err := c.LookupContainer(container) + if err != nil { + return nil, err + } + return c.store.Container(ociCtr.ID()) +} + +// GetContainerTopLayerID gets the ID of the top layer of the given container +func (c *ContainerServer) GetContainerTopLayerID(containerID string) (string, error) { + ctr, err := c.GetStorageContainer(containerID) + if err != nil { + return "", err + } + return ctr.LayerID, nil +} + +// GetContainerRwSize Gets the size of the mutable top layer of the container +func (c *ContainerServer) GetContainerRwSize(containerID string) (int64, error) { + container, err := c.store.Container(containerID) + if err != nil { + return 0, err + } + + // Get the size of the top layer by calculating the size of the diff + // between the layer and its parent. The top layer of a container is + // the only RW layer, all others are immutable + layer, err := c.store.Layer(container.LayerID) + if err != nil { + return 0, err + } + return c.store.DiffSize(layer.Parent, layer.ID) +} + +// GetContainerRootFsSize gets the size of the container's root filesystem +// A container FS is split into two parts. The first is the top layer, a +// mutable layer, and the rest is the RootFS: the set of immutable layers +// that make up the image on which the container is based +func (c *ContainerServer) GetContainerRootFsSize(containerID string) (int64, error) { + container, err := c.store.Container(containerID) + if err != nil { + return 0, err + } + + // Ignore the size of the top layer. The top layer is a mutable RW layer + // and is not considered a part of the rootfs + rwLayer, err := c.store.Layer(container.LayerID) + if err != nil { + return 0, err + } + layer, err := c.store.Layer(rwLayer.Parent) + if err != nil { + return 0, err + } + + size := int64(0) + for layer.Parent != "" { + layerSize, err := c.store.DiffSize(layer.Parent, layer.ID) + if err != nil { + return size, errors.Wrapf(err, "getting diffsize of layer %q and its parent %q", layer.ID, layer.Parent) + } + size += layerSize + layer, err = c.store.Layer(layer.Parent) + if err != nil { + return 0, err + } + } + // Get the size of the last layer. Has to be outside of the loop + // because the parent of the last layer is "", andlstore.Get("") + // will return an error + layerSize, err := c.store.DiffSize(layer.Parent, layer.ID) + return size + layerSize, err +} + +// GetContainerFromRequest gets an oci container matching the specified full or partial id +func (c *ContainerServer) GetContainerFromRequest(cid string) (*oci.Container, error) { + if cid == "" { + return nil, fmt.Errorf("container ID should not be empty") + } + + containerID, err := c.ctrIDIndex.Get(cid) + if err != nil { + return nil, fmt.Errorf("container with ID starting with %s not found: %v", cid, err) + } + + ctr := c.GetContainer(containerID) + if ctr == nil { + return nil, fmt.Errorf("specified container not found: %s", containerID) + } + return ctr, nil +} + +func (c *ContainerServer) getSandboxFromRequest(pid string) (*sandbox.Sandbox, error) { + if pid == "" { + return nil, fmt.Errorf("pod ID should not be empty") + } + + podID, err := c.podIDIndex.Get(pid) + if err != nil { + return nil, fmt.Errorf("pod with ID starting with %s not found: %v", pid, err) + } + + sb := c.GetSandbox(podID) + if sb == nil { + return nil, fmt.Errorf("specified pod not found: %s", podID) + } + return sb, nil +} + +// LookupContainer returns the container with the given name or full or partial id +func (c *ContainerServer) LookupContainer(idOrName string) (*oci.Container, error) { + if idOrName == "" { + return nil, fmt.Errorf("container ID or name should not be empty") + } + + ctrID, err := c.ctrNameIndex.Get(idOrName) + if err != nil { + if err == registrar.ErrNameNotReserved { + ctrID = idOrName + } else { + return nil, err + } + } + + return c.GetContainerFromRequest(ctrID) +} + +// LookupSandbox returns the pod sandbox with the given name or full or partial id +func (c *ContainerServer) LookupSandbox(idOrName string) (*sandbox.Sandbox, error) { + if idOrName == "" { + return nil, fmt.Errorf("container ID or name should not be empty") + } + + podID, err := c.podNameIndex.Get(idOrName) + if err != nil { + if err == registrar.ErrNameNotReserved { + podID = idOrName + } else { + return nil, err + } + } + + return c.getSandboxFromRequest(podID) +} |