func StopContainer(podID, containerID string) (VCContainer, error) {
	if podID == "" {
		return nil, errNeedPodID
	}
	if containerID == "" {
		return nil, errNeedContainerID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	c, err := fetchContainer(p, containerID)
	if err != nil {
		return nil, err
	}
	err = c.stop()
	if err != nil {
		c.delete()
		return nil, err
	}
	return c, nil
}
StopContainer is the virtcontainers container stopping entry point.
StopContainer stops an already running container.
package virtcontainers
import (
	"os"
	"runtime"
	"syscall"
	"github.com/sirupsen/logrus"
)
func init() {
	runtime.LockOSThread()
}
var virtLog = logrus.FieldLogger(logrus.New())
func SetLogger(logger logrus.FieldLogger) {
	virtLog = logger.WithField("source", "virtcontainers")
}
func CreatePod(podConfig PodConfig) (VCPod, error) {
	return createPodFromConfig(podConfig)
}
func createPodFromConfig(podConfig PodConfig) (*Pod, error) {
	p, err := createPod(podConfig)
	if err != nil {
		return nil, err
	}
	err = p.storePod()
	if err != nil {
		return nil, err
	}
	netNsPath, netNsCreated, err := p.network.init(p.config.NetworkConfig)
	if err != nil {
		return nil, err
	}
	err = p.network.run(netNsPath, func() error {
		return p.config.Hooks.preStartHooks()
	})
	if err != nil {
		return nil, err
	}
	networkNS, err := p.network.add(*p, p.config.NetworkConfig, netNsPath, netNsCreated)
	if err != nil {
		return nil, err
	}
	err = p.storage.storePodNetwork(p.id, networkNS)
	if err != nil {
		return nil, err
	}
	err = p.startVM(netNsPath)
	if err != nil {
		return nil, err
	}
	err = p.startProxy()
	if err != nil {
		return nil, err
	}
	if err := p.startShims(); err != nil {
		return nil, err
	}
	return p, nil
}
func DeletePod(podID string) (VCPod, error) {
	if podID == "" {
		return nil, errNeedPodID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	networkNS, err := p.storage.fetchPodNetwork(podID)
	if err != nil {
		return nil, err
	}
	if err := p.stopShims(); err != nil {
		return nil, err
	}
	err = p.stopVM()
	if err != nil {
		return nil, err
	}
	if networkNS.NetNsCreated {
		if err := p.network.remove(*p, networkNS); err != nil {
			return nil, err
		}
	}
	err = p.delete()
	if err != nil {
		return nil, err
	}
	if err := p.config.Hooks.postStopHooks(); err != nil {
		return nil, err
	}
	return p, nil
}
func StartPod(podID string) (VCPod, error) {
	if podID == "" {
		return nil, errNeedPodID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	return startPod(p)
}
func startPod(p *Pod) (*Pod, error) {
	err := p.start()
	if err != nil {
		return nil, err
	}
	if err := p.config.Hooks.postStartHooks(); err != nil {
		return nil, err
	}
	return p, nil
}
func StopPod(podID string) (VCPod, error) {
	if podID == "" {
		return nil, errNeedPod
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	err = p.stop()
	if err != nil {
		p.delete()
		return nil, err
	}
	return p, nil
}
func RunPod(podConfig PodConfig) (VCPod, error) {
	p, err := createPodFromConfig(podConfig)
	if err != nil {
		return nil, err
	}
	lockFile, err := rwLockPod(p.id)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	return startPod(p)
}
func ListPod() ([]PodStatus, error) {
	dir, err := os.Open(configStoragePath)
	if err != nil {
		if os.IsNotExist(err) {
			return []PodStatus{}, nil
		}
		return []PodStatus{}, err
	}
	defer dir.Close()
	podsID, err := dir.Readdirnames(0)
	if err != nil {
		return []PodStatus{}, err
	}
	var podStatusList []PodStatus
	for _, podID := range podsID {
		podStatus, err := StatusPod(podID)
		if err != nil {
			continue
		}
		podStatusList = append(podStatusList, podStatus)
	}
	return podStatusList, nil
}
func StatusPod(podID string) (PodStatus, error) {
	if podID == "" {
		return PodStatus{}, errNeedPodID
	}
	lockFile, err := rLockPod(podID)
	if err != nil {
		return PodStatus{}, err
	}
	pod, err := fetchPod(podID)
	if err != nil {
		unlockPod(lockFile)
		return PodStatus{}, err
	}
	defer pod.wg.Wait()
	defer unlockPod(lockFile)
	var contStatusList []ContainerStatus
	for _, container := range pod.containers {
		contStatus, err := statusContainer(pod, container.id)
		if err != nil {
			return PodStatus{}, err
		}
		contStatusList = append(contStatusList, contStatus)
	}
	podStatus := PodStatus{
		ID:               pod.id,
		State:            pod.state,
		Hypervisor:       pod.config.HypervisorType,
		HypervisorConfig: pod.config.HypervisorConfig,
		Agent:            pod.config.AgentType,
		ContainersStatus: contStatusList,
		Annotations:      pod.config.Annotations,
	}
	return podStatus, nil
}
func CreateContainer(podID string, containerConfig ContainerConfig) (VCPod, VCContainer, error) {
	if podID == "" {
		return nil, nil, errNeedPodID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, nil, err
	}
	c, err := createContainer(p, containerConfig)
	if err != nil {
		return nil, nil, err
	}
	err = c.storeContainer()
	if err != nil {
		return nil, nil, err
	}
	p.config.Containers = append(p.config.Containers, containerConfig)
	err = p.storage.storePodResource(podID, configFileType, *(p.config))
	if err != nil {
		return nil, nil, err
	}
	return p, c, nil
}
func DeleteContainer(podID, containerID string) (VCContainer, error) {
	if podID == "" {
		return nil, errNeedPodID
	}
	if containerID == "" {
		return nil, errNeedContainerID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	c, err := fetchContainer(p, containerID)
	if err != nil {
		return nil, err
	}
	err = c.delete()
	if err != nil {
		return nil, err
	}
	for idx, contConfig := range p.config.Containers {
		if contConfig.ID == containerID {
			p.config.Containers = append(p.config.Containers[:idx], p.config.Containers[idx+1:]...)
			break
		}
	}
	err = p.storage.storePodResource(podID, configFileType, *(p.config))
	if err != nil {
		return nil, err
	}
	return c, nil
}
func StartContainer(podID, containerID string) (VCContainer, error) {
	if podID == "" {
		return nil, errNeedPodID
	}
	if containerID == "" {
		return nil, errNeedContainerID
	}
	lockFile, err := rwLockPod(podID)
	if err != nil {
		return nil, err
	}
	defer unlockPod(lockFile)
	p, err := fetchPod(podID)
	if err != nil {
		return nil, err
	}
	c, err := fetchContainer(p, containerID)
	if err != nil {
		return nil, err
	}
	err = c.start()
	if err != nil {
		c.delete()
		return nil, err
	}
	return c, nil
}