summaryrefslogtreecommitdiff
path: root/libkpod
diff options
context:
space:
mode:
Diffstat (limited to 'libkpod')
-rw-r--r--libkpod/config.go5
-rw-r--r--libkpod/container.go157
-rw-r--r--libkpod/container_server.go775
-rw-r--r--libkpod/kill.go45
-rw-r--r--libkpod/rename.go114
-rw-r--r--libkpod/sandbox/sandbox.go484
-rw-r--r--libkpod/stats.go111
-rw-r--r--libkpod/stop.go36
-rw-r--r--libkpod/wait.go42
9 files changed, 2 insertions, 1767 deletions
diff --git a/libkpod/config.go b/libkpod/config.go
index 84d3ce897..b95ff18ca 100644
--- a/libkpod/config.go
+++ b/libkpod/config.go
@@ -6,7 +6,6 @@ import (
"github.com/BurntSushi/toml"
"github.com/opencontainers/selinux/go-selinux"
- "github.com/projectatomic/libpod/oci"
)
// Default paths if none are specified
@@ -21,9 +20,9 @@ const (
apparmorProfileName = "crio-default"
cniConfigDir = "/etc/cni/net.d/"
cniBinDir = "/opt/cni/bin/"
- cgroupManager = oci.CgroupfsCgroupsManager
+ cgroupManager = "" //oci.CgroupfsCgroupsManager
lockPath = "/run/crio.lock"
- containerExitsDir = oci.ContainerExitsDir
+ containerExitsDir = "" //oci.ContainerExitsDir
)
// Config represents the entire set of configuration values that can be set for
diff --git a/libkpod/container.go b/libkpod/container.go
deleted file mode 100644
index e0ff348d0..000000000
--- a/libkpod/container.go
+++ /dev/null
@@ -1,157 +0,0 @@
-package libkpod
-
-import (
- "fmt"
-
- cstorage "github.com/containers/storage"
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/libkpod/sandbox"
- "github.com/projectatomic/libpod/oci"
- "github.com/projectatomic/libpod/pkg/registrar"
-)
-
-// 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)
-}
diff --git a/libkpod/container_server.go b/libkpod/container_server.go
deleted file mode 100644
index 8e0e09978..000000000
--- a/libkpod/container_server.go
+++ /dev/null
@@ -1,775 +0,0 @@
-package libkpod
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "path/filepath"
- "sync"
- "time"
-
- "github.com/containers/image/types"
- cstorage "github.com/containers/storage"
- "github.com/docker/docker/pkg/ioutils"
- "github.com/docker/docker/pkg/truncindex"
- "github.com/opencontainers/runc/libcontainer"
- rspec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/opencontainers/selinux/go-selinux"
- "github.com/opencontainers/selinux/go-selinux/label"
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/libkpod/sandbox"
- "github.com/projectatomic/libpod/oci"
- "github.com/projectatomic/libpod/pkg/annotations"
- "github.com/projectatomic/libpod/pkg/registrar"
- "github.com/projectatomic/libpod/pkg/storage"
- "github.com/sirupsen/logrus"
- pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
-)
-
-// ContainerServer implements the ImageServer
-type ContainerServer struct {
- runtime *oci.Runtime
- store cstorage.Store
- storageImageServer storage.ImageServer
- storageRuntimeServer storage.RuntimeServer
- updateLock sync.RWMutex
- ctrNameIndex *registrar.Registrar
- ctrIDIndex *truncindex.TruncIndex
- podNameIndex *registrar.Registrar
- podIDIndex *truncindex.TruncIndex
- hooks map[string]HookParams
-
- imageContext *types.SystemContext
- stateLock sync.Locker
- state *containerServerState
- config *Config
-}
-
-// Runtime returns the oci runtime for the ContainerServer
-func (c *ContainerServer) Runtime() *oci.Runtime {
- return c.runtime
-}
-
-// Hooks returns the oci hooks for the ContainerServer
-func (c *ContainerServer) Hooks() map[string]HookParams {
- return c.hooks
-}
-
-// Store returns the Store for the ContainerServer
-func (c *ContainerServer) Store() cstorage.Store {
- return c.store
-}
-
-// StorageImageServer returns the ImageServer for the ContainerServer
-func (c *ContainerServer) StorageImageServer() storage.ImageServer {
- return c.storageImageServer
-}
-
-// CtrNameIndex returns the Registrar for the ContainerServer
-func (c *ContainerServer) CtrNameIndex() *registrar.Registrar {
- return c.ctrNameIndex
-}
-
-// CtrIDIndex returns the TruncIndex for the ContainerServer
-func (c *ContainerServer) CtrIDIndex() *truncindex.TruncIndex {
- return c.ctrIDIndex
-}
-
-// PodNameIndex returns the index of pod names
-func (c *ContainerServer) PodNameIndex() *registrar.Registrar {
- return c.podNameIndex
-}
-
-// PodIDIndex returns the index of pod IDs
-func (c *ContainerServer) PodIDIndex() *truncindex.TruncIndex {
- return c.podIDIndex
-}
-
-// ImageContext returns the SystemContext for the ContainerServer
-func (c *ContainerServer) ImageContext() *types.SystemContext {
- return c.imageContext
-}
-
-// Config gets the configuration for the ContainerServer
-func (c *ContainerServer) Config() *Config {
- return c.config
-}
-
-// StorageRuntimeServer gets the runtime server for the ContainerServer
-func (c *ContainerServer) StorageRuntimeServer() storage.RuntimeServer {
- return c.storageRuntimeServer
-}
-
-// New creates a new ContainerServer with options provided
-func New(config *Config) (*ContainerServer, error) {
- store, err := cstorage.GetStore(cstorage.StoreOptions{
- RunRoot: config.RunRoot,
- GraphRoot: config.Root,
- GraphDriverName: config.Storage,
- GraphDriverOptions: config.StorageOptions,
- })
- if err != nil {
- return nil, err
- }
-
- imageService, err := storage.GetImageService(store, config.DefaultTransport, config.InsecureRegistries, config.Registries)
- if err != nil {
- return nil, err
- }
-
- storageRuntimeService := storage.GetRuntimeService(imageService, config.PauseImage)
- if err != nil {
- return nil, err
- }
-
- runtime, err := oci.New(config.Runtime, config.RuntimeUntrustedWorkload, config.DefaultWorkloadTrust, config.Conmon, config.ConmonEnv, config.CgroupManager, config.ContainerExitsDir, config.LogSizeMax, config.NoPivot)
- if err != nil {
- return nil, err
- }
-
- var lock sync.Locker
- if config.FileLocking {
- fileLock, err := cstorage.GetLockfile(lockPath)
- if err != nil {
- return nil, fmt.Errorf("error obtaining lockfile: %v", err)
- }
- lock = fileLock
- } else {
- lock = new(sync.Mutex)
- }
-
- hooks := make(map[string]HookParams)
- // If hooks directory is set in config use it
- if config.HooksDirPath != "" {
- if err := readHooks(config.HooksDirPath, hooks); err != nil {
- return nil, err
- }
- // If user overrode default hooks, this means it is in a test, so don't
- // use OverrideHooksDirPath
- if config.HooksDirPath == DefaultHooksDirPath {
- if err := readHooks(OverrideHooksDirPath, hooks); err != nil {
- return nil, err
- }
- }
- }
-
- return &ContainerServer{
- runtime: runtime,
- store: store,
- storageImageServer: imageService,
- storageRuntimeServer: storageRuntimeService,
- ctrNameIndex: registrar.NewRegistrar(),
- ctrIDIndex: truncindex.NewTruncIndex([]string{}),
- podNameIndex: registrar.NewRegistrar(),
- podIDIndex: truncindex.NewTruncIndex([]string{}),
- imageContext: &types.SystemContext{SignaturePolicyPath: config.SignaturePolicyPath},
- hooks: hooks,
- stateLock: lock,
- state: &containerServerState{
- containers: oci.NewMemoryStore(),
- infraContainers: oci.NewMemoryStore(),
- sandboxes: make(map[string]*sandbox.Sandbox),
- processLevels: make(map[string]int),
- },
- config: config,
- }, nil
-}
-
-// Update makes changes to the server's state (lists of pods and containers) to
-// reflect the list of pods and containers that are stored on disk, possibly
-// having been modified by other parties
-func (c *ContainerServer) Update() error {
- c.updateLock.Lock()
- defer c.updateLock.Unlock()
-
- containers, err := c.store.Containers()
- if err != nil && !os.IsNotExist(errors.Cause(err)) {
- logrus.Warnf("could not read containers and sandboxes: %v", err)
- return err
- }
- newPods := map[string]*storage.RuntimeContainerMetadata{}
- oldPods := map[string]string{}
- removedPods := map[string]string{}
- newPodContainers := map[string]*storage.RuntimeContainerMetadata{}
- oldPodContainers := map[string]string{}
- removedPodContainers := map[string]string{}
- for _, container := range containers {
- if c.HasSandbox(container.ID) {
- // FIXME: do we need to reload/update any info about the sandbox?
- oldPods[container.ID] = container.ID
- oldPodContainers[container.ID] = container.ID
- continue
- }
- if c.GetContainer(container.ID) != nil {
- // FIXME: do we need to reload/update any info about the container?
- oldPodContainers[container.ID] = container.ID
- continue
- }
- // not previously known, so figure out what it is
- metadata, err2 := c.storageRuntimeServer.GetContainerMetadata(container.ID)
- if err2 != nil {
- logrus.Errorf("error parsing metadata for %s: %v, ignoring", container.ID, err2)
- continue
- }
- if metadata.Pod {
- newPods[container.ID] = &metadata
- } else {
- newPodContainers[container.ID] = &metadata
- }
- }
- c.ctrIDIndex.Iterate(func(id string) {
- if _, ok := oldPodContainers[id]; !ok {
- // this container's ID wasn't in the updated list -> removed
- removedPodContainers[id] = id
- } else {
- ctr := c.GetContainer(id)
- if ctr != nil {
- // if the container exists, update its state
- c.ContainerStateFromDisk(c.GetContainer(id))
- }
- }
- })
- for removedPodContainer := range removedPodContainers {
- // forget this container
- ctr := c.GetContainer(removedPodContainer)
- if ctr == nil {
- logrus.Warnf("bad state when getting container removed %+v", removedPodContainer)
- continue
- }
- c.ReleaseContainerName(ctr.Name())
- c.RemoveContainer(ctr)
- if err = c.ctrIDIndex.Delete(ctr.ID()); err != nil {
- return err
- }
- logrus.Debugf("forgetting removed pod container %s", ctr.ID())
- }
- c.PodIDIndex().Iterate(func(id string) {
- if _, ok := oldPods[id]; !ok {
- // this pod's ID wasn't in the updated list -> removed
- removedPods[id] = id
- }
- })
- for removedPod := range removedPods {
- // forget this pod
- sb := c.GetSandbox(removedPod)
- if sb == nil {
- logrus.Warnf("bad state when getting pod to remove %+v", removedPod)
- continue
- }
- podInfraContainer := sb.InfraContainer()
- c.ReleaseContainerName(podInfraContainer.Name())
- c.RemoveContainer(podInfraContainer)
- if err = c.ctrIDIndex.Delete(podInfraContainer.ID()); err != nil {
- return err
- }
- sb.RemoveInfraContainer()
- c.ReleasePodName(sb.Name())
- c.RemoveSandbox(sb.ID())
- if err = c.podIDIndex.Delete(sb.ID()); err != nil {
- return err
- }
- logrus.Debugf("forgetting removed pod %s", sb.ID())
- }
- for sandboxID := range newPods {
- // load this pod
- if err = c.LoadSandbox(sandboxID); err != nil {
- logrus.Warnf("could not load new pod sandbox %s: %v, ignoring", sandboxID, err)
- } else {
- logrus.Debugf("loaded new pod sandbox %s", sandboxID, err)
- }
- }
- for containerID := range newPodContainers {
- // load this container
- if err = c.LoadContainer(containerID); err != nil {
- logrus.Warnf("could not load new sandbox container %s: %v, ignoring", containerID, err)
- } else {
- logrus.Debugf("loaded new pod container %s", containerID, err)
- }
- }
- return nil
-}
-
-// LoadSandbox loads a sandbox from the disk into the sandbox store
-func (c *ContainerServer) LoadSandbox(id string) error {
- config, err := c.store.FromContainerDirectory(id, "config.json")
- if err != nil {
- return err
- }
- var m rspec.Spec
- if err = json.Unmarshal(config, &m); err != nil {
- return err
- }
- labels := make(map[string]string)
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Labels]), &labels); err != nil {
- return err
- }
- name := m.Annotations[annotations.Name]
- name, err = c.ReservePodName(id, name)
- if err != nil {
- return err
- }
- defer func() {
- if err != nil {
- c.ReleasePodName(name)
- }
- }()
- var metadata pb.PodSandboxMetadata
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Metadata]), &metadata); err != nil {
- return err
- }
-
- ip := m.Annotations[annotations.IP]
-
- processLabel, mountLabel, err := label.InitLabels(label.DupSecOpt(m.Process.SelinuxLabel))
- if err != nil {
- return err
- }
-
- kubeAnnotations := make(map[string]string)
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Annotations]), &kubeAnnotations); err != nil {
- return err
- }
-
- privileged := isTrue(m.Annotations[annotations.PrivilegedRuntime])
- trusted := isTrue(m.Annotations[annotations.TrustedSandbox])
-
- sb, err := sandbox.New(id, name, m.Annotations[annotations.KubeName], filepath.Dir(m.Annotations[annotations.LogPath]), "", labels, kubeAnnotations, processLabel, mountLabel, &metadata, m.Annotations[annotations.ShmPath], "", privileged, trusted, m.Annotations[annotations.ResolvPath], "", nil)
- if err != nil {
- return err
- }
- sb.AddHostnamePath(m.Annotations[annotations.HostnamePath])
- sb.AddIP(ip)
-
- // We add a netNS only if we can load a permanent one.
- // Otherwise, the sandbox will live in the host namespace.
- netNsPath, err := configNetNsPath(m)
- if err == nil {
- nsErr := sb.NetNsJoin(netNsPath, sb.Name())
- // If we can't load the networking namespace
- // because it's closed, we just set the sb netns
- // pointer to nil. Otherwise we return an error.
- if nsErr != nil && nsErr != sandbox.ErrClosedNetNS {
- return nsErr
- }
- }
-
- c.AddSandbox(sb)
-
- defer func() {
- if err != nil {
- c.RemoveSandbox(sb.ID())
- }
- }()
-
- sandboxPath, err := c.store.ContainerRunDirectory(id)
- if err != nil {
- return err
- }
-
- sandboxDir, err := c.store.ContainerDirectory(id)
- if err != nil {
- return err
- }
-
- cname, err := c.ReserveContainerName(m.Annotations[annotations.ContainerID], m.Annotations[annotations.ContainerName])
- if err != nil {
- return err
- }
- defer func() {
- if err != nil {
- c.ReleaseContainerName(cname)
- }
- }()
-
- created, err := time.Parse(time.RFC3339Nano, m.Annotations[annotations.Created])
- if err != nil {
- return err
- }
-
- scontainer, err := oci.NewContainer(m.Annotations[annotations.ContainerID], cname, sandboxPath, m.Annotations[annotations.LogPath], sb.NetNs(), labels, m.Annotations, kubeAnnotations, "", "", "", nil, id, false, false, false, privileged, trusted, sandboxDir, created, m.Annotations["org.opencontainers.image.stopSignal"])
- if err != nil {
- return err
- }
- scontainer.SetSpec(&m)
- scontainer.SetMountPoint(m.Annotations[annotations.MountPoint])
-
- if m.Annotations[annotations.Volumes] != "" {
- containerVolumes := []oci.ContainerVolume{}
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Volumes]), &containerVolumes); err != nil {
- return fmt.Errorf("failed to unmarshal container volumes: %v", err)
- }
- if containerVolumes != nil {
- for _, cv := range containerVolumes {
- scontainer.AddVolume(cv)
- }
- }
- }
-
- c.ContainerStateFromDisk(scontainer)
-
- if err = label.ReserveLabel(processLabel); err != nil {
- return err
- }
- sb.SetInfraContainer(scontainer)
- if err = c.ctrIDIndex.Add(scontainer.ID()); err != nil {
- return err
- }
- if err = c.podIDIndex.Add(id); err != nil {
- return err
- }
- return nil
-}
-
-func configNetNsPath(spec rspec.Spec) (string, error) {
- for _, ns := range spec.Linux.Namespaces {
- if ns.Type != rspec.NetworkNamespace {
- continue
- }
-
- if ns.Path == "" {
- return "", fmt.Errorf("empty networking namespace")
- }
-
- return ns.Path, nil
- }
-
- return "", fmt.Errorf("missing networking namespace")
-}
-
-// LoadContainer loads a container from the disk into the container store
-func (c *ContainerServer) LoadContainer(id string) error {
- config, err := c.store.FromContainerDirectory(id, "config.json")
- if err != nil {
- return err
- }
- var m rspec.Spec
- if err = json.Unmarshal(config, &m); err != nil {
- return err
- }
- labels := make(map[string]string)
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Labels]), &labels); err != nil {
- return err
- }
- name := m.Annotations[annotations.Name]
- name, err = c.ReserveContainerName(id, name)
- if err != nil {
- return err
- }
-
- defer func() {
- if err != nil {
- c.ReleaseContainerName(name)
- }
- }()
-
- var metadata pb.ContainerMetadata
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Metadata]), &metadata); err != nil {
- return err
- }
- sb := c.GetSandbox(m.Annotations[annotations.SandboxID])
- if sb == nil {
- return fmt.Errorf("could not get sandbox with id %s, skipping", m.Annotations[annotations.SandboxID])
- }
-
- tty := isTrue(m.Annotations[annotations.TTY])
- stdin := isTrue(m.Annotations[annotations.Stdin])
- stdinOnce := isTrue(m.Annotations[annotations.StdinOnce])
-
- containerPath, err := c.store.ContainerRunDirectory(id)
- if err != nil {
- return err
- }
-
- containerDir, err := c.store.ContainerDirectory(id)
- if err != nil {
- return err
- }
-
- img, ok := m.Annotations[annotations.Image]
- if !ok {
- img = ""
- }
-
- imgName, ok := m.Annotations[annotations.ImageName]
- if !ok {
- imgName = ""
- }
-
- imgRef, ok := m.Annotations[annotations.ImageRef]
- if !ok {
- imgRef = ""
- }
-
- kubeAnnotations := make(map[string]string)
- if err = json.Unmarshal([]byte(m.Annotations[annotations.Annotations]), &kubeAnnotations); err != nil {
- return err
- }
-
- created, err := time.Parse(time.RFC3339Nano, m.Annotations[annotations.Created])
- if err != nil {
- return err
- }
-
- ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations[annotations.LogPath], sb.NetNs(), labels, m.Annotations, kubeAnnotations, img, imgName, imgRef, &metadata, sb.ID(), tty, stdin, stdinOnce, sb.Privileged(), sb.Trusted(), containerDir, created, m.Annotations["org.opencontainers.image.stopSignal"])
- if err != nil {
- return err
- }
- ctr.SetSpec(&m)
- ctr.SetMountPoint(m.Annotations[annotations.MountPoint])
-
- c.ContainerStateFromDisk(ctr)
-
- c.AddContainer(ctr)
- return c.ctrIDIndex.Add(id)
-}
-
-func isTrue(annotaton string) bool {
- return annotaton == "true"
-}
-
-// ContainerStateFromDisk retrieves information on the state of a running container
-// from the disk
-func (c *ContainerServer) ContainerStateFromDisk(ctr *oci.Container) error {
- if err := ctr.FromDisk(); err != nil {
- return err
- }
- // ignore errors, this is a best effort to have up-to-date info about
- // a given container before its state gets stored
- c.runtime.UpdateStatus(ctr)
-
- return nil
-}
-
-// ContainerStateToDisk writes the container's state information to a JSON file
-// on disk
-func (c *ContainerServer) ContainerStateToDisk(ctr *oci.Container) error {
- // ignore errors, this is a best effort to have up-to-date info about
- // a given container before its state gets stored
- c.Runtime().UpdateStatus(ctr)
-
- jsonSource, err := ioutils.NewAtomicFileWriter(ctr.StatePath(), 0644)
- if err != nil {
- return err
- }
- defer jsonSource.Close()
- enc := json.NewEncoder(jsonSource)
- return enc.Encode(c.runtime.ContainerStatus(ctr))
-}
-
-// ReserveContainerName holds a name for a container that is being created
-func (c *ContainerServer) ReserveContainerName(id, name string) (string, error) {
- if err := c.ctrNameIndex.Reserve(name, id); err != nil {
- if err == registrar.ErrNameReserved {
- id, err := c.ctrNameIndex.Get(name)
- if err != nil {
- logrus.Warnf("conflict, ctr name %q already reserved", name)
- return "", err
- }
- return "", fmt.Errorf("conflict, name %q already reserved for ctr %q", name, id)
- }
- return "", fmt.Errorf("error reserving ctr name %s", name)
- }
- return name, nil
-}
-
-// ReleaseContainerName releases a container name from the index so that it can
-// be used by other containers
-func (c *ContainerServer) ReleaseContainerName(name string) {
- c.ctrNameIndex.Release(name)
-}
-
-// ReservePodName holds a name for a pod that is being created
-func (c *ContainerServer) ReservePodName(id, name string) (string, error) {
- if err := c.podNameIndex.Reserve(name, id); err != nil {
- if err == registrar.ErrNameReserved {
- id, err := c.podNameIndex.Get(name)
- if err != nil {
- logrus.Warnf("conflict, pod name %q already reserved", name)
- return "", err
- }
- return "", fmt.Errorf("conflict, name %q already reserved for pod %q", name, id)
- }
- return "", fmt.Errorf("error reserving pod name %q", name)
- }
- return name, nil
-}
-
-// ReleasePodName releases a pod name from the index so it can be used by other
-// pods
-func (c *ContainerServer) ReleasePodName(name string) {
- c.podNameIndex.Release(name)
-}
-
-// Shutdown attempts to shut down the server's storage cleanly
-func (c *ContainerServer) Shutdown() error {
- _, err := c.store.Shutdown(false)
- if err != nil && errors.Cause(err) != cstorage.ErrLayerUsedByContainer {
- return err
- }
- return nil
-}
-
-type containerServerState struct {
- containers oci.ContainerStorer
- infraContainers oci.ContainerStorer
- sandboxes map[string]*sandbox.Sandbox
- // processLevels The number of sandboxes using the same SELinux MCS level. Need to release MCS Level, when count reaches 0
- processLevels map[string]int
-}
-
-// AddContainer adds a container to the container state store
-func (c *ContainerServer) AddContainer(ctr *oci.Container) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- sandbox := c.state.sandboxes[ctr.Sandbox()]
- sandbox.AddContainer(ctr)
- c.state.containers.Add(ctr.ID(), ctr)
-}
-
-// AddInfraContainer adds a container to the container state store
-func (c *ContainerServer) AddInfraContainer(ctr *oci.Container) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- c.state.infraContainers.Add(ctr.ID(), ctr)
-}
-
-// GetContainer returns a container by its ID
-func (c *ContainerServer) GetContainer(id string) *oci.Container {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- return c.state.containers.Get(id)
-}
-
-// GetInfraContainer returns a container by its ID
-func (c *ContainerServer) GetInfraContainer(id string) *oci.Container {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- return c.state.infraContainers.Get(id)
-}
-
-// HasContainer checks if a container exists in the state
-func (c *ContainerServer) HasContainer(id string) bool {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- ctr := c.state.containers.Get(id)
- return ctr != nil
-}
-
-// RemoveContainer removes a container from the container state store
-func (c *ContainerServer) RemoveContainer(ctr *oci.Container) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- sbID := ctr.Sandbox()
- sb := c.state.sandboxes[sbID]
- sb.RemoveContainer(ctr)
- c.state.containers.Delete(ctr.ID())
-}
-
-// RemoveInfraContainer removes a container from the container state store
-func (c *ContainerServer) RemoveInfraContainer(ctr *oci.Container) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- c.state.infraContainers.Delete(ctr.ID())
-}
-
-// listContainers returns a list of all containers stored by the server state
-func (c *ContainerServer) listContainers() []*oci.Container {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- return c.state.containers.List()
-}
-
-// ListContainers returns a list of all containers stored by the server state
-// that match the given filter function
-func (c *ContainerServer) ListContainers(filters ...func(*oci.Container) bool) ([]*oci.Container, error) {
- containers := c.listContainers()
- if len(filters) == 0 {
- return containers, nil
- }
- filteredContainers := make([]*oci.Container, 0, len(containers))
- for _, container := range containers {
- for _, filter := range filters {
- if filter(container) {
- filteredContainers = append(filteredContainers, container)
- }
- }
- }
- return filteredContainers, nil
-}
-
-// AddSandbox adds a sandbox to the sandbox state store
-func (c *ContainerServer) AddSandbox(sb *sandbox.Sandbox) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- c.state.sandboxes[sb.ID()] = sb
- c.state.processLevels[selinux.NewContext(sb.ProcessLabel())["level"]]++
-}
-
-// GetSandbox returns a sandbox by its ID
-func (c *ContainerServer) GetSandbox(id string) *sandbox.Sandbox {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- return c.state.sandboxes[id]
-}
-
-// GetSandboxContainer returns a sandbox's infra container
-func (c *ContainerServer) GetSandboxContainer(id string) *oci.Container {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- sb, ok := c.state.sandboxes[id]
- if !ok {
- return nil
- }
- return sb.InfraContainer()
-}
-
-// HasSandbox checks if a sandbox exists in the state
-func (c *ContainerServer) HasSandbox(id string) bool {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- _, ok := c.state.sandboxes[id]
- return ok
-}
-
-// RemoveSandbox removes a sandbox from the state store
-func (c *ContainerServer) RemoveSandbox(id string) {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- processLabel := c.state.sandboxes[id].ProcessLabel()
- delete(c.state.sandboxes, id)
- level := selinux.NewContext(processLabel)["level"]
- c.state.processLevels[level]--
- if c.state.processLevels[level] == 0 {
- label.ReleaseLabel(processLabel)
- delete(c.state.processLevels, level)
- }
-}
-
-// ListSandboxes lists all sandboxes in the state store
-func (c *ContainerServer) ListSandboxes() []*sandbox.Sandbox {
- c.stateLock.Lock()
- defer c.stateLock.Unlock()
- sbArray := make([]*sandbox.Sandbox, 0, len(c.state.sandboxes))
- for _, sb := range c.state.sandboxes {
- sbArray = append(sbArray, sb)
- }
-
- return sbArray
-}
-
-// LibcontainerStats gets the stats for the container with the given id from runc/libcontainer
-func (c *ContainerServer) LibcontainerStats(ctr *oci.Container) (*libcontainer.Stats, error) {
- // TODO: make this not hardcoded
- // was: c.runtime.Path(ociContainer) but that returns /usr/bin/runc - how do we get /run/runc?
- // runroot is /var/run/runc
- // Hardcoding probably breaks ClearContainers compatibility
- factory, err := loadFactory("/run/runc")
- if err != nil {
- return nil, err
- }
- container, err := factory.Load(ctr.ID())
- if err != nil {
- return nil, err
- }
- return container.Stats()
-}
diff --git a/libkpod/kill.go b/libkpod/kill.go
deleted file mode 100644
index 74c525818..000000000
--- a/libkpod/kill.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package libkpod
-
-import (
- "github.com/docker/docker/pkg/signal"
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/oci"
- "github.com/projectatomic/libpod/utils"
- "os"
- "syscall"
-)
-
-// Reverse lookup signal string from its map
-func findStringInSignalMap(killSignal syscall.Signal) (string, error) {
- for k, v := range signal.SignalMap {
- if v == killSignal {
- return k, nil
- }
- }
- return "", errors.Errorf("unable to convert signal to string")
-
-}
-
-// ContainerKill sends the user provided signal to the containers primary process.
-func (c *ContainerServer) ContainerKill(container string, killSignal syscall.Signal) (string, error) { // nolint
- ctr, err := c.LookupContainer(container)
- if err != nil {
- return "", errors.Wrapf(err, "failed to find container %s", container)
- }
- c.runtime.UpdateStatus(ctr)
- cStatus := c.runtime.ContainerStatus(ctr)
-
- // If the container is not running, error and move on.
- if cStatus.Status != oci.ContainerStateRunning {
- return "", errors.Errorf("cannot kill container %s: it is not running", container)
- }
- signalString, err := findStringInSignalMap(killSignal)
- if err != nil {
- return "", err
- }
- if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, c.runtime.Path(ctr), "kill", ctr.ID(), signalString); err != nil {
- return "", err
- }
- c.ContainerStateToDisk(ctr)
- return ctr.ID(), nil
-}
diff --git a/libkpod/rename.go b/libkpod/rename.go
deleted file mode 100644
index cdb2bfc04..000000000
--- a/libkpod/rename.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package libkpod
-
-import (
- "encoding/json"
- "path/filepath"
-
- "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
-
- "github.com/docker/docker/pkg/ioutils"
- "github.com/opencontainers/runtime-tools/generate"
- "github.com/projectatomic/libpod/oci"
- "github.com/projectatomic/libpod/pkg/annotations"
-)
-
-const configFile = "config.json"
-
-// ContainerRename renames the given container
-func (c *ContainerServer) ContainerRename(container, name string) error {
- ctr, err := c.LookupContainer(container)
- if err != nil {
- return err
- }
-
- oldName := ctr.Name()
- _, err = c.ReserveContainerName(ctr.ID(), name)
- if err != nil {
- return err
- }
- defer func() {
- if err != nil {
- c.ReleaseContainerName(name)
- } else {
- c.ReleaseContainerName(oldName)
- }
- }()
-
- // Update state.json
- if err = c.updateStateName(ctr, name); err != nil {
- return err
- }
-
- // Update config.json
- configRuntimePath := filepath.Join(ctr.BundlePath(), configFile)
- if err = updateConfigName(configRuntimePath, name); err != nil {
- return err
- }
- configStoragePath := filepath.Join(ctr.Dir(), configFile)
- if err = updateConfigName(configStoragePath, name); err != nil {
- return err
- }
-
- // Update containers.json
- if err = c.store.SetNames(ctr.ID(), []string{name}); err != nil {
- return err
- }
- return nil
-}
-
-func updateConfigName(configPath, name string) error {
- specgen, err := generate.NewFromFile(configPath)
- if err != nil {
- return err
- }
- specgen.AddAnnotation(annotations.Name, name)
- specgen.AddAnnotation(annotations.Metadata, updateMetadata(specgen.Spec().Annotations, name))
-
- return specgen.SaveToFile(configPath, generate.ExportOptions{})
-}
-
-func (c *ContainerServer) updateStateName(ctr *oci.Container, name string) error {
- ctr.State().Annotations[annotations.Name] = name
- ctr.State().Annotations[annotations.Metadata] = updateMetadata(ctr.State().Annotations, name)
- // This is taken directly from c.ContainerStateToDisk(), which can't be used because of the call to UpdateStatus() in the first line
- jsonSource, err := ioutils.NewAtomicFileWriter(ctr.StatePath(), 0644)
- if err != nil {
- return err
- }
- defer jsonSource.Close()
- enc := json.NewEncoder(jsonSource)
- return enc.Encode(c.runtime.ContainerStatus(ctr))
-}
-
-// Attempts to update a metadata annotation
-func updateMetadata(specAnnotations map[string]string, name string) string {
- oldMetadata := specAnnotations[annotations.Metadata]
- containerType := specAnnotations[annotations.ContainerType]
- if containerType == "container" {
- metadata := runtime.ContainerMetadata{}
- err := json.Unmarshal([]byte(oldMetadata), metadata)
- if err != nil {
- return oldMetadata
- }
- metadata.Name = name
- m, err := json.Marshal(metadata)
- if err != nil {
- return oldMetadata
- }
- return string(m)
- } else if containerType == "sandbox" {
- metadata := runtime.PodSandboxMetadata{}
- err := json.Unmarshal([]byte(oldMetadata), metadata)
- if err != nil {
- return oldMetadata
- }
- metadata.Name = name
- m, err := json.Marshal(metadata)
- if err != nil {
- return oldMetadata
- }
- return string(m)
- } else {
- return specAnnotations[annotations.Metadata]
- }
-}
diff --git a/libkpod/sandbox/sandbox.go b/libkpod/sandbox/sandbox.go
deleted file mode 100644
index a61c5a4f7..000000000
--- a/libkpod/sandbox/sandbox.go
+++ /dev/null
@@ -1,484 +0,0 @@
-package sandbox
-
-import (
- "crypto/rand"
- "errors"
- "fmt"
- "os"
- "path/filepath"
- "sync"
-
- "github.com/containernetworking/plugins/pkg/ns"
- "github.com/docker/docker/pkg/mount"
- "github.com/docker/docker/pkg/symlink"
- "github.com/projectatomic/libpod/oci"
- "github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
- "k8s.io/apimachinery/pkg/fields"
- pb "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
- "k8s.io/kubernetes/pkg/kubelet/network/hostport"
-)
-
-// NetNs handles data pertaining a network namespace
-type NetNs struct {
- sync.Mutex
- ns ns.NetNS
- symlink *os.File
- closed bool
- restored bool
-}
-
-func (ns *NetNs) symlinkCreate(name string) error {
- b := make([]byte, 4)
- _, randErr := rand.Reader.Read(b)
- if randErr != nil {
- return randErr
- }
-
- nsName := fmt.Sprintf("%s-%x", name, b)
- symlinkPath := filepath.Join(NsRunDir, nsName)
-
- if err := os.Symlink(ns.ns.Path(), symlinkPath); err != nil {
- return err
- }
-
- fd, err := os.Open(symlinkPath)
- if err != nil {
- if removeErr := os.RemoveAll(symlinkPath); removeErr != nil {
- return removeErr
- }
-
- return err
- }
-
- ns.symlink = fd
-
- return nil
-}
-
-func (ns *NetNs) symlinkRemove() error {
- if err := ns.symlink.Close(); err != nil {
- return err
- }
-
- return os.RemoveAll(ns.symlink.Name())
-}
-
-func isSymbolicLink(path string) (bool, error) {
- fi, err := os.Lstat(path)
- if err != nil {
- return false, err
- }
-
- return fi.Mode()&os.ModeSymlink == os.ModeSymlink, nil
-}
-
-// NetNsGet returns the NetNs associated with the given nspath and name
-func NetNsGet(nspath, name string) (*NetNs, error) {
- if err := ns.IsNSorErr(nspath); err != nil {
- return nil, ErrClosedNetNS
- }
-
- symlink, symlinkErr := isSymbolicLink(nspath)
- if symlinkErr != nil {
- return nil, symlinkErr
- }
-
- var resolvedNsPath string
- if symlink {
- path, err := os.Readlink(nspath)
- if err != nil {
- return nil, err
- }
- resolvedNsPath = path
- } else {
- resolvedNsPath = nspath
- }
-
- netNS, err := ns.GetNS(resolvedNsPath)
- if err != nil {
- return nil, err
- }
-
- netNs := &NetNs{ns: netNS, closed: false, restored: true}
-
- if symlink {
- fd, err := os.Open(nspath)
- if err != nil {
- return nil, err
- }
-
- netNs.symlink = fd
- } else {
- if err := netNs.symlinkCreate(name); err != nil {
- return nil, err
- }
- }
-
- return netNs, nil
-}
-
-// HostNetNsPath returns the current network namespace for the host
-func HostNetNsPath() (string, error) {
- netNS, err := ns.GetCurrentNS()
- if err != nil {
- return "", err
- }
-
- defer netNS.Close()
- return netNS.Path(), nil
-}
-
-// Sandbox contains data surrounding kubernetes sandboxes on the server
-type Sandbox struct {
- id string
- namespace string
- // OCI pod name (eg "<namespace>-<name>-<attempt>")
- name string
- // Kubernetes pod name (eg, "<name>")
- kubeName string
- logDir string
- labels fields.Set
- annotations map[string]string
- infraContainer *oci.Container
- containers oci.ContainerStorer
- processLabel string
- mountLabel string
- netns *NetNs
- metadata *pb.PodSandboxMetadata
- shmPath string
- cgroupParent string
- privileged bool
- trusted bool
- resolvPath string
- hostnamePath string
- hostname string
- portMappings []*hostport.PortMapping
- stopped bool
- // ipv4 or ipv6 cache
- ip string
-}
-
-const (
- // DefaultShmSize is the default shm size
- DefaultShmSize = 64 * 1024 * 1024
- // NsRunDir is the default directory in which running network namespaces
- // are stored
- NsRunDir = "/var/run/netns"
- // PodInfraCommand is the default command when starting a pod infrastructure
- // container
- PodInfraCommand = "/pause"
-)
-
-var (
- // ErrIDEmpty is the erro returned when the id of the sandbox is empty
- ErrIDEmpty = errors.New("PodSandboxId should not be empty")
- // ErrClosedNetNS is the error returned when the network namespace of the
- // sandbox is closed
- ErrClosedNetNS = errors.New("PodSandbox networking namespace is closed")
-)
-
-// New creates and populates a new pod sandbox
-// New sandboxes have no containers, no infra container, and no network namespaces associated with them
-// An infra container must be attached before the sandbox is added to the state
-func New(id, namespace, name, kubeName, logDir string, labels, annotations map[string]string, processLabel, mountLabel string, metadata *pb.PodSandboxMetadata, shmPath, cgroupParent string, privileged, trusted bool, resolvPath, hostname string, portMappings []*hostport.PortMapping) (*Sandbox, error) {
- sb := new(Sandbox)
- sb.id = id
- sb.namespace = namespace
- sb.name = name
- sb.kubeName = kubeName
- sb.logDir = logDir
- sb.labels = labels
- sb.annotations = annotations
- sb.containers = oci.NewMemoryStore()
- sb.processLabel = processLabel
- sb.mountLabel = mountLabel
- sb.metadata = metadata
- sb.shmPath = shmPath
- sb.cgroupParent = cgroupParent
- sb.privileged = privileged
- sb.trusted = trusted
- sb.resolvPath = resolvPath
- sb.hostname = hostname
- sb.portMappings = portMappings
-
- return sb, nil
-}
-
-// AddIP stores the ip in the sandbox
-func (s *Sandbox) AddIP(ip string) {
- s.ip = ip
-}
-
-// IP returns the ip of the sandbox
-func (s *Sandbox) IP() string {
- return s.ip
-}
-
-// ID returns the id of the sandbox
-func (s *Sandbox) ID() string {
- return s.id
-}
-
-// Namespace returns the namespace for the sandbox
-func (s *Sandbox) Namespace() string {
- return s.namespace
-}
-
-// Name returns the name of the sandbox
-func (s *Sandbox) Name() string {
- return s.name
-}
-
-// KubeName returns the kubernetes name for the sandbox
-func (s *Sandbox) KubeName() string {
- return s.kubeName
-}
-
-// LogDir returns the location of the logging directory for the sandbox
-func (s *Sandbox) LogDir() string {
- return s.logDir
-}
-
-// Labels returns the labels associated with the sandbox
-func (s *Sandbox) Labels() fields.Set {
- return s.labels
-}
-
-// Annotations returns a list of annotations for the sandbox
-func (s *Sandbox) Annotations() map[string]string {
- return s.annotations
-}
-
-// InfraContainer returns the infrastructure container for the sandbox
-func (s *Sandbox) InfraContainer() *oci.Container {
- return s.infraContainer
-}
-
-// Containers returns the ContainerStorer that contains information on all
-// of the containers in the sandbox
-func (s *Sandbox) Containers() oci.ContainerStorer {
- return s.containers
-}
-
-// ProcessLabel returns the process label for the sandbox
-func (s *Sandbox) ProcessLabel() string {
- return s.processLabel
-}
-
-// MountLabel returns the mount label for the sandbox
-func (s *Sandbox) MountLabel() string {
- return s.mountLabel
-}
-
-// Metadata returns a set of metadata about the sandbox
-func (s *Sandbox) Metadata() *pb.PodSandboxMetadata {
- return s.metadata
-}
-
-// ShmPath returns the shm path of the sandbox
-func (s *Sandbox) ShmPath() string {
- return s.shmPath
-}
-
-// CgroupParent returns the cgroup parent of the sandbox
-func (s *Sandbox) CgroupParent() string {
- return s.cgroupParent
-}
-
-// Privileged returns whether or not the containers in the sandbox are
-// privileged containers
-func (s *Sandbox) Privileged() bool {
- return s.privileged
-}
-
-// Trusted returns whether or not the containers in the sandbox are trusted
-func (s *Sandbox) Trusted() bool {
- return s.trusted
-}
-
-// ResolvPath returns the resolv path for the sandbox
-func (s *Sandbox) ResolvPath() string {
- return s.resolvPath
-}
-
-// AddHostnamePath adds the hostname path to the sandbox
-func (s *Sandbox) AddHostnamePath(hostname string) {
- s.hostnamePath = hostname
-}
-
-// HostnamePath retrieves the hostname path from a sandbox
-func (s *Sandbox) HostnamePath() string {
- return s.hostnamePath
-}
-
-// Hostname returns the hsotname of the sandbox
-func (s *Sandbox) Hostname() string {
- return s.hostname
-}
-
-// PortMappings returns a list of port mappings between the host and the sandbox
-func (s *Sandbox) PortMappings() []*hostport.PortMapping {
- return s.portMappings
-}
-
-// AddContainer adds a container to the sandbox
-func (s *Sandbox) AddContainer(c *oci.Container) {
- s.containers.Add(c.Name(), c)
-}
-
-// GetContainer retrieves a container from the sandbox
-func (s *Sandbox) GetContainer(name string) *oci.Container {
- return s.containers.Get(name)
-}
-
-// RemoveContainer deletes a container from the sandbox
-func (s *Sandbox) RemoveContainer(c *oci.Container) {
- s.containers.Delete(c.Name())
-}
-
-// SetInfraContainer sets the infrastructure container of a sandbox
-// Attempts to set the infrastructure container after one is already present will throw an error
-func (s *Sandbox) SetInfraContainer(infraCtr *oci.Container) error {
- if s.infraContainer != nil {
- return fmt.Errorf("sandbox already has an infra container")
- } else if infraCtr == nil {
- return fmt.Errorf("must provide non-nil infra container")
- }
-
- s.infraContainer = infraCtr
-
- return nil
-}
-
-// RemoveInfraContainer removes the infrastructure container of a sandbox
-func (s *Sandbox) RemoveInfraContainer() {
- s.infraContainer = nil
-}
-
-// NetNs retrieves the network namespace of the sandbox
-// If the sandbox uses the host namespace, nil is returned
-func (s *Sandbox) NetNs() ns.NetNS {
- if s.netns == nil {
- return nil
- }
-
- return s.netns.ns
-}
-
-// NetNsPath returns the path to the network namespace of the sandbox.
-// If the sandbox uses the host namespace, nil is returned
-func (s *Sandbox) NetNsPath() string {
- if s.netns == nil {
- return ""
- }
-
- return s.netns.symlink.Name()
-}
-
-// NetNsCreate creates a new network namespace for the sandbox
-func (s *Sandbox) NetNsCreate() error {
- if s.netns != nil {
- return fmt.Errorf("net NS already created")
- }
-
- netNS, err := ns.NewNS()
- if err != nil {
- return err
- }
-
- s.netns = &NetNs{
- ns: netNS,
- closed: false,
- }
-
- if err := s.netns.symlinkCreate(s.name); err != nil {
- logrus.Warnf("Could not create nentns symlink %v", err)
-
- if err1 := s.netns.ns.Close(); err1 != nil {
- return err1
- }
-
- return err
- }
-
- return nil
-}
-
-// SetStopped sets the sandbox state to stopped.
-// This should be set after a stop operation succeeds
-// so that subsequent stops can return fast.
-func (s *Sandbox) SetStopped() {
- s.stopped = true
-}
-
-// Stopped returns whether the sandbox state has been
-// set to stopped.
-func (s *Sandbox) Stopped() bool {
- return s.stopped
-}
-
-// NetNsJoin attempts to join the sandbox to an existing network namespace
-// This will fail if the sandbox is already part of a network namespace
-func (s *Sandbox) NetNsJoin(nspath, name string) error {
- if s.netns != nil {
- return fmt.Errorf("sandbox already has a network namespace, cannot join another")
- }
-
- netNS, err := NetNsGet(nspath, name)
- if err != nil {
- return err
- }
-
- s.netns = netNS
-
- return nil
-}
-
-// NetNsRemove removes the network namespace associated with the sandbox
-func (s *Sandbox) NetNsRemove() error {
- if s.netns == nil {
- logrus.Warn("no networking namespace")
- return nil
- }
-
- s.netns.Lock()
- defer s.netns.Unlock()
-
- if s.netns.closed {
- // netNsRemove() can be called multiple
- // times without returning an error.
- return nil
- }
-
- if err := s.netns.symlinkRemove(); err != nil {
- return err
- }
-
- if err := s.netns.ns.Close(); err != nil {
- return err
- }
-
- if s.netns.restored {
- // we got namespaces in the form of
- // /var/run/netns/cni-0d08effa-06eb-a963-f51a-e2b0eceffc5d
- // but /var/run on most system is symlinked to /run so we first resolve
- // the symlink and then try and see if it's mounted
- fp, err := symlink.FollowSymlinkInScope(s.netns.ns.Path(), "/")
- if err != nil {
- return err
- }
- if mounted, err := mount.Mounted(fp); err == nil && mounted {
- if err := unix.Unmount(fp, unix.MNT_DETACH); err != nil {
- return err
- }
- }
-
- if err := os.RemoveAll(s.netns.ns.Path()); err != nil {
- return err
- }
- }
-
- s.netns.closed = true
- return nil
-}
diff --git a/libkpod/stats.go b/libkpod/stats.go
deleted file mode 100644
index 8e74577d4..000000000
--- a/libkpod/stats.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package libkpod
-
-import (
- "path/filepath"
- "syscall"
- "time"
-
- "strings"
-
- "github.com/opencontainers/runc/libcontainer"
- "github.com/projectatomic/libpod/oci"
-)
-
-// ContainerStats contains the statistics information for a running container
-type ContainerStats struct {
- Container string
- CPU float64
- cpuNano uint64
- systemNano uint64
- MemUsage uint64
- MemLimit uint64
- MemPerc float64
- NetInput uint64
- NetOutput uint64
- BlockInput uint64
- BlockOutput uint64
- PIDs uint64
-}
-
-// GetContainerStats gets the running stats for a given container
-func (c *ContainerServer) GetContainerStats(ctr *oci.Container, previousStats *ContainerStats) (*ContainerStats, error) {
- previousCPU := previousStats.cpuNano
- previousSystem := previousStats.systemNano
- libcontainerStats, err := c.LibcontainerStats(ctr)
- if err != nil {
- return nil, err
- }
- cgroupStats := libcontainerStats.CgroupStats
- stats := new(ContainerStats)
- stats.Container = ctr.ID()
- stats.CPU = calculateCPUPercent(libcontainerStats, previousCPU, previousSystem)
- stats.MemUsage = cgroupStats.MemoryStats.Usage.Usage
- stats.MemLimit = getMemLimit(cgroupStats.MemoryStats.Usage.Limit)
- stats.MemPerc = float64(stats.MemUsage) / float64(stats.MemLimit)
- stats.PIDs = cgroupStats.PidsStats.Current
- stats.BlockInput, stats.BlockOutput = calculateBlockIO(libcontainerStats)
- stats.NetInput, stats.NetOutput = getContainerNetIO(libcontainerStats)
-
- return stats, nil
-}
-
-func loadFactory(root string) (libcontainer.Factory, error) {
- abs, err := filepath.Abs(root)
- if err != nil {
- return nil, err
- }
- cgroupManager := libcontainer.Cgroupfs
- return libcontainer.New(abs, cgroupManager, libcontainer.CriuPath(""))
-}
-
-// getMemory limit returns the memory limit for a given cgroup
-// If the configured memory limit is larger than the total memory on the sys, the
-// physical system memory size is returned
-func getMemLimit(cgroupLimit uint64) uint64 {
- si := &syscall.Sysinfo_t{}
- err := syscall.Sysinfo(si)
- if err != nil {
- return cgroupLimit
- }
-
- physicalLimit := uint64(si.Totalram)
- if cgroupLimit > physicalLimit {
- return physicalLimit
- }
- return cgroupLimit
-}
-
-// Returns the total number of bytes transmitted and received for the given container stats
-func getContainerNetIO(stats *libcontainer.Stats) (received uint64, transmitted uint64) {
- for _, iface := range stats.Interfaces {
- received += iface.RxBytes
- transmitted += iface.TxBytes
- }
- return
-}
-
-func calculateCPUPercent(stats *libcontainer.Stats, previousCPU, previousSystem uint64) float64 {
- var (
- cpuPercent = 0.0
- cpuDelta = float64(stats.CgroupStats.CpuStats.CpuUsage.TotalUsage - previousCPU)
- systemDelta = float64(uint64(time.Now().UnixNano()) - previousSystem)
- )
- if systemDelta > 0.0 && cpuDelta > 0.0 {
- // gets a ratio of container cpu usage total, multiplies it by the number of cores (4 cores running
- // at 100% utilization should be 400% utilization), and multiplies that by 100 to get a percentage
- cpuPercent = (cpuDelta / systemDelta) * float64(len(stats.CgroupStats.CpuStats.CpuUsage.PercpuUsage)) * 100
- }
- return cpuPercent
-}
-
-func calculateBlockIO(stats *libcontainer.Stats) (read uint64, write uint64) {
- for _, blkIOEntry := range stats.CgroupStats.BlkioStats.IoServiceBytesRecursive {
- switch strings.ToLower(blkIOEntry.Op) {
- case "read":
- read += blkIOEntry.Value
- case "write":
- write += blkIOEntry.Value
- }
- }
- return
-}
diff --git a/libkpod/stop.go b/libkpod/stop.go
deleted file mode 100644
index 4ce7db740..000000000
--- a/libkpod/stop.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package libkpod
-
-import (
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/oci"
- "golang.org/x/net/context"
-)
-
-// ContainerStop stops a running container with a grace period (i.e., timeout).
-func (c *ContainerServer) ContainerStop(ctx context.Context, container string, timeout int64) (string, error) {
- ctr, err := c.LookupContainer(container)
- if err != nil {
- return "", errors.Wrapf(err, "failed to find container %s", container)
- }
- ctrID := ctr.ID()
-
- cStatus := c.runtime.ContainerStatus(ctr)
- switch cStatus.Status {
-
- case oci.ContainerStatePaused:
- return "", errors.Errorf("cannot stop paused container %s", ctrID)
- default:
- if cStatus.Status != oci.ContainerStateStopped {
- if err := c.runtime.StopContainer(ctx, ctr, timeout); err != nil {
- return "", errors.Wrapf(err, "failed to stop container %s", ctrID)
- }
- if err := c.storageRuntimeServer.StopContainer(ctrID); err != nil {
- return "", errors.Wrapf(err, "failed to unmount container %s", ctrID)
- }
- }
- }
-
- c.ContainerStateToDisk(ctr)
-
- return ctrID, nil
-}
diff --git a/libkpod/wait.go b/libkpod/wait.go
deleted file mode 100644
index e972a0ba0..000000000
--- a/libkpod/wait.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package libkpod
-
-import (
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/oci"
- "k8s.io/apimachinery/pkg/util/wait"
-)
-
-func isStopped(c *ContainerServer, ctr *oci.Container) bool {
- c.runtime.UpdateStatus(ctr)
- cStatus := c.runtime.ContainerStatus(ctr)
- if cStatus.Status == oci.ContainerStateStopped {
- return true
- }
- return false
-}
-
-// ContainerWait stops a running container with a grace period (i.e., timeout).
-func (c *ContainerServer) ContainerWait(container string) (int32, error) {
- ctr, err := c.LookupContainer(container)
- if err != nil {
- return 0, errors.Wrapf(err, "failed to find container %s", container)
- }
-
- err = wait.PollImmediateInfinite(1,
- func() (bool, error) {
- if !isStopped(c, ctr) {
- return false, nil
- } else { // nolint
- return true, nil // nolint
- } // nolint
-
- },
- )
-
- if err != nil {
- return 0, err
- }
- exitCode := ctr.State().ExitCode
- c.ContainerStateToDisk(ctr)
- return exitCode, nil
-}