2017-11-30 15:46:11 +00:00
|
|
|
package lib
|
2017-07-22 02:07:40 +00:00
|
|
|
|
|
|
|
import (
|
2017-07-31 23:23:20 +00:00
|
|
|
"fmt"
|
|
|
|
|
2017-07-22 02:07:40 +00:00
|
|
|
cstorage "github.com/containers/storage"
|
2017-11-30 15:46:11 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/lib/sandbox"
|
2017-07-31 23:23:20 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/oci"
|
2017-08-05 11:40:46 +00:00
|
|
|
"github.com/kubernetes-incubator/cri-o/pkg/registrar"
|
2017-07-23 23:01:37 +00:00
|
|
|
"github.com/pkg/errors"
|
2017-07-22 02:07:40 +00:00
|
|
|
)
|
|
|
|
|
2017-08-01 15:28:50 +00:00
|
|
|
// 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())
|
2017-07-22 02:07:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetContainerTopLayerID gets the ID of the top layer of the given container
|
2017-08-01 15:28:50 +00:00
|
|
|
func (c *ContainerServer) GetContainerTopLayerID(containerID string) (string, error) {
|
|
|
|
ctr, err := c.GetStorageContainer(containerID)
|
2017-07-22 02:07:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return ctr.LayerID, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetContainerRwSize Gets the size of the mutable top layer of the container
|
2017-08-01 15:28:50 +00:00
|
|
|
func (c *ContainerServer) GetContainerRwSize(containerID string) (int64, error) {
|
|
|
|
container, err := c.store.Container(containerID)
|
2017-07-22 02:07:40 +00:00
|
|
|
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
|
2017-08-01 15:28:50 +00:00
|
|
|
layer, err := c.store.Layer(container.LayerID)
|
2017-07-22 02:07:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
2017-08-01 15:28:50 +00:00
|
|
|
return c.store.DiffSize(layer.Parent, layer.ID)
|
2017-07-22 02:07:40 +00:00
|
|
|
}
|
2017-07-23 23:01:37 +00:00
|
|
|
|
|
|
|
// 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
|
2017-08-01 15:28:50 +00:00
|
|
|
func (c *ContainerServer) GetContainerRootFsSize(containerID string) (int64, error) {
|
|
|
|
container, err := c.store.Container(containerID)
|
2017-07-23 23:01:37 +00:00
|
|
|
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
|
2017-08-01 15:28:50 +00:00
|
|
|
rwLayer, err := c.store.Layer(container.LayerID)
|
2017-07-23 23:01:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
2017-08-01 15:28:50 +00:00
|
|
|
layer, err := c.store.Layer(rwLayer.Parent)
|
2017-07-23 23:01:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
size := int64(0)
|
|
|
|
for layer.Parent != "" {
|
2017-08-01 15:28:50 +00:00
|
|
|
layerSize, err := c.store.DiffSize(layer.Parent, layer.ID)
|
2017-07-23 23:01:37 +00:00
|
|
|
if err != nil {
|
|
|
|
return size, errors.Wrapf(err, "getting diffsize of layer %q and its parent %q", layer.ID, layer.Parent)
|
|
|
|
}
|
|
|
|
size += layerSize
|
2017-08-01 15:28:50 +00:00
|
|
|
layer, err = c.store.Layer(layer.Parent)
|
2017-07-23 23:01:37 +00:00
|
|
|
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
|
2017-08-01 15:28:50 +00:00
|
|
|
layerSize, err := c.store.DiffSize(layer.Parent, layer.ID)
|
2017-07-23 23:01:37 +00:00
|
|
|
return size + layerSize, err
|
|
|
|
}
|
2017-07-31 23:23:20 +00:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|