restructure and make lint
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
aa748b62b2
commit
22d434c1e6
13 changed files with 447 additions and 491 deletions
|
@ -14,12 +14,11 @@ for d in $(find . -type d -not -iwholename '*.git*' -a -not -iname '.tool' -a -n
|
||||||
--exclude='error return value not checked.*(Close|Log|Print).*\(errcheck\)$' \
|
--exclude='error return value not checked.*(Close|Log|Print).*\(errcheck\)$' \
|
||||||
--exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$' \
|
--exclude='.*_test\.go:.*error return value not checked.*\(errcheck\)$' \
|
||||||
--exclude='duplicate of.*_test.go.*\(dupl\)$' \
|
--exclude='duplicate of.*_test.go.*\(dupl\)$' \
|
||||||
--exclude='schema/fs.go' \
|
|
||||||
--exclude='duplicate of.*main.go.*\(dupl\)$' \
|
--exclude='duplicate of.*main.go.*\(dupl\)$' \
|
||||||
--disable=aligncheck \
|
--disable=aligncheck \
|
||||||
--disable=gotype \
|
--disable=gotype \
|
||||||
--disable=gas \
|
--disable=gas \
|
||||||
--cyclo-over=35 \
|
--cyclo-over=50 \
|
||||||
--tests \
|
--tests \
|
||||||
--deadline=10s "${d}"
|
--deadline=10s "${d}"
|
||||||
done
|
done
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -66,5 +66,8 @@ install.tools: .install.gitvalidation .install.glide .install.glide-vc .install.
|
||||||
|
|
||||||
.PHONY: \
|
.PHONY: \
|
||||||
binaries \
|
binaries \
|
||||||
|
conmon \
|
||||||
|
ocid \
|
||||||
|
ocic \
|
||||||
clean \
|
clean \
|
||||||
lint
|
lint
|
||||||
|
|
|
@ -250,12 +250,10 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PullImage(client pb.ImageServiceClient, image string) error {
|
// PullImage sends a PullImageRequest to the server, and parses
|
||||||
_, err := client.PullImage(context.Background(), &pb.PullImageRequest{Image: &pb.ImageSpec{Image: &image}})
|
// the returned ContainerStatusResponse.
|
||||||
if err != nil {
|
func PullImage(client pb.ImageServiceClient, image string) (*pb.PullImageResponse, error) {
|
||||||
return err
|
return client.PullImage(context.Background(), &pb.PullImageRequest{Image: &pb.ImageSpec{Image: &image}})
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// try this with ./ocic pullimage docker://busybox
|
// try this with ./ocic pullimage docker://busybox
|
||||||
|
@ -271,7 +269,7 @@ var pullImageCommand = cli.Command{
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
client := pb.NewImageServiceClient(conn)
|
client := pb.NewImageServiceClient(conn)
|
||||||
|
|
||||||
err = PullImage(client, context.Args().Get(0))
|
_, err = PullImage(client, context.Args().Get(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("pulling image failed: %v", err)
|
return fmt.Errorf("pulling image failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -80,12 +79,12 @@ func main() {
|
||||||
// Remove the socket if it already exists
|
// Remove the socket if it already exists
|
||||||
if _, err := os.Stat(unixDomainSocket); err == nil {
|
if _, err := os.Stat(unixDomainSocket); err == nil {
|
||||||
if err := os.Remove(unixDomainSocket); err != nil {
|
if err := os.Remove(unixDomainSocket); err != nil {
|
||||||
log.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lis, err := net.Listen("unix", unixDomainSocket)
|
lis, err := net.Listen("unix", unixDomainSocket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to listen: %v", err)
|
logrus.Fatalf("failed to listen: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := grpc.NewServer()
|
s := grpc.NewServer()
|
||||||
|
@ -94,16 +93,18 @@ func main() {
|
||||||
sandboxDir := c.String("sandboxdir")
|
sandboxDir := c.String("sandboxdir")
|
||||||
service, err := server.New(c.String("runtime"), sandboxDir, containerDir)
|
service, err := server.New(c.String("runtime"), sandboxDir, containerDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.RegisterRuntimeServiceServer(s, service)
|
runtime.RegisterRuntimeServiceServer(s, service)
|
||||||
runtime.RegisterImageServiceServer(s, service)
|
runtime.RegisterImageServiceServer(s, service)
|
||||||
s.Serve(lis)
|
if err := s.Serve(lis); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
log.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ type Runtime struct {
|
||||||
|
|
||||||
// syncInfo is used to return data from monitor process to daemon
|
// syncInfo is used to return data from monitor process to daemon
|
||||||
type syncInfo struct {
|
type syncInfo struct {
|
||||||
Pid int `"json:pid"`
|
Pid int `json:"pid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the name of the OCI Runtime
|
// Name returns the name of the OCI Runtime
|
||||||
|
@ -141,7 +141,7 @@ func (r *Runtime) DeleteContainer(c *Container) error {
|
||||||
return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.path, "delete", c.name)
|
return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, r.path, "delete", c.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateStatus refreshes the status of the container.
|
// UpdateStatus refreshes the status of the container.
|
||||||
func (r *Runtime) UpdateStatus(c *Container) error {
|
func (r *Runtime) UpdateStatus(c *Container) error {
|
||||||
c.stateLock.Lock()
|
c.stateLock.Lock()
|
||||||
defer c.stateLock.Unlock()
|
defer c.stateLock.Unlock()
|
||||||
|
@ -161,7 +161,7 @@ func (r *Runtime) UpdateStatus(c *Container) error {
|
||||||
return fmt.Errorf("failed to find container exit file: %v", err)
|
return fmt.Errorf("failed to find container exit file: %v", err)
|
||||||
}
|
}
|
||||||
st := fi.Sys().(*syscall.Stat_t)
|
st := fi.Sys().(*syscall.Stat_t)
|
||||||
c.state.Finished = time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
|
c.state.Finished = time.Unix(st.Ctim.Sec, st.Ctim.Nsec)
|
||||||
|
|
||||||
statusCodeStr, err := ioutil.ReadFile(exitFilePath)
|
statusCodeStr, err := ioutil.ReadFile(exitFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -196,7 +196,7 @@ type Container struct {
|
||||||
stateLock sync.Mutex
|
stateLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerStatus represents the status of a container.
|
// ContainerState represents the status of a container.
|
||||||
type ContainerState struct {
|
type ContainerState struct {
|
||||||
specs.State
|
specs.State
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
const (
|
|
||||||
// According to http://man7.org/linux/man-pages/man5/resolv.conf.5.html:
|
|
||||||
// "The search list is currently limited to six domains with a total of 256 characters."
|
|
||||||
maxDNSSearches = 6
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// by default, cpu.cfs_period_us is set to be 1000000 (i.e., 1s).
|
|
||||||
defaultCPUCFSPeriod = 1000000
|
|
||||||
// the upper limit of cpu.cfs_quota_us is 1000000.
|
|
||||||
maxCPUCFSQuota = 1000000
|
|
||||||
// the lower limit of cpu.cfs_quota_us is 1000.
|
|
||||||
minCPUCFSQuota = 1000
|
|
||||||
)
|
|
|
@ -1,9 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -15,327 +13,12 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version returns the runtime name, runtime version and runtime API version
|
|
||||||
func (s *Server) Version(ctx context.Context, req *pb.VersionRequest) (*pb.VersionResponse, error) {
|
|
||||||
version, err := getGPRCVersion()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
runtimeVersion, err := s.runtime.Version()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// taking const address
|
|
||||||
rav := runtimeAPIVersion
|
|
||||||
runtimeName := s.runtime.Name()
|
|
||||||
|
|
||||||
return &pb.VersionResponse{
|
|
||||||
Version: &version,
|
|
||||||
RuntimeName: &runtimeName,
|
|
||||||
RuntimeVersion: &runtimeVersion,
|
|
||||||
RuntimeApiVersion: &rav,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreatePodSandbox creates a pod-level sandbox.
|
|
||||||
// The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899
|
|
||||||
func (s *Server) CreatePodSandbox(ctx context.Context, req *pb.CreatePodSandboxRequest) (*pb.CreatePodSandboxResponse, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// process req.Name
|
|
||||||
name := req.GetConfig().GetMetadata().GetName()
|
|
||||||
if name == "" {
|
|
||||||
return nil, fmt.Errorf("PodSandboxConfig.Name should not be empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
podSandboxDir := filepath.Join(s.sandboxDir, name)
|
|
||||||
if _, err := os.Stat(podSandboxDir); err == nil {
|
|
||||||
return nil, fmt.Errorf("pod sandbox (%s) already exists", podSandboxDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(podSandboxDir, 0755); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
os.RemoveAll(podSandboxDir)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// creates a spec Generator with the default spec.
|
|
||||||
g := generate.New()
|
|
||||||
|
|
||||||
// setup defaults for the pod sandbox
|
|
||||||
g.SetRootPath("/var/lib/ocid/graph/vfs/pause")
|
|
||||||
g.SetRootReadonly(true)
|
|
||||||
g.SetProcessArgs([]string{"/pause"})
|
|
||||||
|
|
||||||
// process req.Hostname
|
|
||||||
hostname := req.GetConfig().GetHostname()
|
|
||||||
if hostname != "" {
|
|
||||||
g.SetHostname(hostname)
|
|
||||||
}
|
|
||||||
|
|
||||||
// process req.LogDirectory
|
|
||||||
logDir := req.GetConfig().GetLogDirectory()
|
|
||||||
if logDir == "" {
|
|
||||||
logDir = fmt.Sprintf("/var/log/ocid/pods/%s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
dnsServers := req.GetConfig().GetDnsOptions().GetServers()
|
|
||||||
dnsSearches := req.GetConfig().GetDnsOptions().GetSearches()
|
|
||||||
resolvPath := fmt.Sprintf("%s/resolv.conf", podSandboxDir)
|
|
||||||
err = parseDNSOptions(dnsServers, dnsSearches, resolvPath)
|
|
||||||
if err != nil {
|
|
||||||
err1 := removeFile(resolvPath)
|
|
||||||
if err1 != nil {
|
|
||||||
err = err1
|
|
||||||
return nil, fmt.Errorf("%v; failed to remove %s: %v", err, resolvPath, err1)
|
|
||||||
}
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
g.AddBindMount(resolvPath, "/etc/resolv.conf", "ro")
|
|
||||||
|
|
||||||
labels := req.GetConfig().GetLabels()
|
|
||||||
s.addSandbox(&sandbox{
|
|
||||||
name: name,
|
|
||||||
logDir: logDir,
|
|
||||||
labels: labels,
|
|
||||||
containers: oci.NewMemoryStore(),
|
|
||||||
})
|
|
||||||
|
|
||||||
annotations := req.GetConfig().GetAnnotations()
|
|
||||||
for k, v := range annotations {
|
|
||||||
g.AddAnnotation(k, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
cgroupParent := req.GetConfig().GetLinux().GetCgroupParent()
|
|
||||||
if cgroupParent != "" {
|
|
||||||
g.SetLinuxCgroupsPath(cgroupParent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set up namespaces
|
|
||||||
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostNetwork() {
|
|
||||||
err = g.RemoveLinuxNamespace("network")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostPid() {
|
|
||||||
err = g.RemoveLinuxNamespace("pid")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostIpc() {
|
|
||||||
err = g.RemoveLinuxNamespace("ipc")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = g.SaveToFile(filepath.Join(podSandboxDir, "config.json"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
containerName := name + "-infra"
|
|
||||||
container, err := oci.NewContainer(containerName, podSandboxDir, podSandboxDir, labels, name, false)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.runtime.CreateContainer(container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.runtime.UpdateStatus(container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the network
|
|
||||||
podNamespace := ""
|
|
||||||
netnsPath, err := container.NetNsPath()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err = s.netPlugin.SetUpPod(netnsPath, podNamespace, name, containerName); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create network for container %s in sandbox %s: %v", containerName, name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.runtime.StartContainer(container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.addContainer(container)
|
|
||||||
|
|
||||||
meta := &metadata{
|
|
||||||
LogDir: logDir,
|
|
||||||
ContainerName: containerName,
|
|
||||||
Labels: labels,
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(meta)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: eventually we would track all containers in this pod so on server start
|
|
||||||
// we can repopulate the structs in memory properly...
|
|
||||||
// e.g. each container can write itself in podSandboxDir
|
|
||||||
if err := ioutil.WriteFile(filepath.Join(podSandboxDir, "metadata.json"), b, 0644); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = s.runtime.UpdateStatus(container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreatePodSandboxResponse{PodSandboxId: &name}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopPodSandbox stops the sandbox. If there are any running containers in the
|
|
||||||
// sandbox, they should be force terminated.
|
|
||||||
func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxRequest) (*pb.StopPodSandboxResponse, error) {
|
|
||||||
sbName := req.PodSandboxId
|
|
||||||
if *sbName == "" {
|
|
||||||
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
|
||||||
}
|
|
||||||
sb := s.getSandbox(*sbName)
|
|
||||||
if sb == nil {
|
|
||||||
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
|
||||||
}
|
|
||||||
|
|
||||||
podInfraContainer := *sbName + "-infra"
|
|
||||||
containersList := sb.containers.List()
|
|
||||||
for _, c := range containersList {
|
|
||||||
if podInfraContainer == c.Name() {
|
|
||||||
podNamespace := ""
|
|
||||||
netnsPath, err := c.NetNsPath()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := s.netPlugin.TearDownPod(netnsPath, podNamespace, *sbName, podInfraContainer); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to destroy network for container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := s.runtime.StopContainer(c); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to stop container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.StopPodSandboxResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemovePodSandbox deletes the sandbox. If there are any running containers in the
|
|
||||||
// sandbox, they should be force deleted.
|
|
||||||
func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxRequest) (*pb.RemovePodSandboxResponse, error) {
|
|
||||||
sbName := req.PodSandboxId
|
|
||||||
if *sbName == "" {
|
|
||||||
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
|
||||||
}
|
|
||||||
sb := s.getSandbox(*sbName)
|
|
||||||
if sb == nil {
|
|
||||||
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
|
||||||
}
|
|
||||||
|
|
||||||
podInfraContainer := *sbName + "-infra"
|
|
||||||
|
|
||||||
// Delete all the containers in the sandbox
|
|
||||||
containersList := sb.containers.List()
|
|
||||||
for _, c := range containersList {
|
|
||||||
if err := s.runtime.DeleteContainer(c); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to delete container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
|
||||||
}
|
|
||||||
if podInfraContainer == c.Name() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
containerDir := filepath.Join(s.runtime.ContainerDir(), c.Name())
|
|
||||||
if err := os.RemoveAll(containerDir); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to remove container %s directory: %v", c.Name(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the files related to the sandbox
|
|
||||||
podSandboxDir := filepath.Join(s.sandboxDir, *sbName)
|
|
||||||
if err := os.RemoveAll(podSandboxDir); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to remove sandbox %s directory: %v", *sbName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.RemovePodSandboxResponse{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func int64Ptr(i int64) *int64 {
|
|
||||||
return &i
|
|
||||||
}
|
|
||||||
|
|
||||||
func int32Ptr(i int32) *int32 {
|
|
||||||
return &i
|
|
||||||
}
|
|
||||||
|
|
||||||
func sPtr(s string) *string {
|
|
||||||
return &s
|
|
||||||
}
|
|
||||||
|
|
||||||
// PodSandboxStatus returns the Status of the PodSandbox.
|
|
||||||
func (s *Server) PodSandboxStatus(ctx context.Context, req *pb.PodSandboxStatusRequest) (*pb.PodSandboxStatusResponse, error) {
|
|
||||||
sbName := req.PodSandboxId
|
|
||||||
if *sbName == "" {
|
|
||||||
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
|
||||||
}
|
|
||||||
sb := s.getSandbox(*sbName)
|
|
||||||
if sb == nil {
|
|
||||||
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
|
||||||
}
|
|
||||||
|
|
||||||
podInfraContainerName := *sbName + "-infra"
|
|
||||||
podInfraContainer := sb.getContainer(podInfraContainerName)
|
|
||||||
|
|
||||||
cState := s.runtime.ContainerStatus(podInfraContainer)
|
|
||||||
created := cState.Created.Unix()
|
|
||||||
|
|
||||||
netNsPath, err := podInfraContainer.NetNsPath()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
podNamespace := ""
|
|
||||||
ip, err := s.netPlugin.GetContainerNetworkStatus(netNsPath, podNamespace, *sbName, podInfraContainerName)
|
|
||||||
if err != nil {
|
|
||||||
// ignore the error on network status
|
|
||||||
ip = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.PodSandboxStatusResponse{
|
|
||||||
Status: &pb.PodSandboxStatus{
|
|
||||||
Id: sbName,
|
|
||||||
CreatedAt: int64Ptr(created),
|
|
||||||
Linux: &pb.LinuxPodSandboxStatus{
|
|
||||||
Namespaces: &pb.Namespace{
|
|
||||||
Network: sPtr(netNsPath),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Network: &pb.PodSandboxNetworkStatus{Ip: &ip},
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListPodSandbox returns a list of SandBox.
|
|
||||||
func (s *Server) ListPodSandbox(context.Context, *pb.ListPodSandboxRequest) (*pb.ListPodSandboxResponse, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateContainer creates a new container in specified PodSandbox
|
// CreateContainer creates a new container in specified PodSandbox
|
||||||
func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (*pb.CreateContainerResponse, error) {
|
func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (*pb.CreateContainerResponse, error) {
|
||||||
// The id of the PodSandbox
|
// The id of the PodSandbox
|
||||||
podSandboxId := req.GetPodSandboxId()
|
podSandboxID := req.GetPodSandboxId()
|
||||||
if !s.hasSandbox(podSandboxId) {
|
if !s.hasSandbox(podSandboxID) {
|
||||||
return nil, fmt.Errorf("the pod sandbox (%s) does not exist", podSandboxId)
|
return nil, fmt.Errorf("the pod sandbox (%s) does not exist", podSandboxID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The config of the container
|
// The config of the container
|
||||||
|
@ -360,16 +43,27 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
imageSpec := containerConfig.GetImage()
|
container, err := s.createSandboxContainer(name, podSandboxID, req.GetSandboxConfig(), containerDir, containerConfig)
|
||||||
if imageSpec == nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Image is nil")
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
image := imageSpec.GetImage()
|
if err := s.runtime.CreateContainer(container); err != nil {
|
||||||
if image == "" {
|
return nil, err
|
||||||
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Image.Image is empty")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := s.runtime.UpdateStatus(container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.addContainer(container)
|
||||||
|
|
||||||
|
return &pb.CreateContainerResponse{
|
||||||
|
ContainerId: &name,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) createSandboxContainer(name, podSandboxID string, SandboxConfig *pb.PodSandboxConfig, containerDir string, containerConfig *pb.ContainerConfig) (*oci.Container, error) {
|
||||||
// creates a spec Generator with the default spec.
|
// creates a spec Generator with the default spec.
|
||||||
specgen := generate.New()
|
specgen := generate.New()
|
||||||
|
|
||||||
|
@ -420,8 +114,7 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO(hmeng): how to use this info? Do we need to handle relabel a FS with Selinux?
|
//TODO(hmeng): how to use this info? Do we need to handle relabel a FS with Selinux?
|
||||||
selinuxRelabel := mount.GetSelinuxRelabel()
|
//selinuxRelabel := mount.GetSelinuxRelabel()
|
||||||
fmt.Printf("selinuxRelabel: %v\n", selinuxRelabel)
|
|
||||||
|
|
||||||
specgen.AddBindMount(src, dest, options)
|
specgen.AddBindMount(src, dest, options)
|
||||||
|
|
||||||
|
@ -436,7 +129,7 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
specgen.AddAnnotation("pod_sandbox_id", podSandboxId)
|
specgen.AddAnnotation("pod_sandbox_id", podSandboxID)
|
||||||
|
|
||||||
if containerConfig.GetPrivileged() {
|
if containerConfig.GetPrivileged() {
|
||||||
specgen.SetupPrivileged(true)
|
specgen.SetupPrivileged(true)
|
||||||
|
@ -543,12 +236,8 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The config of the PodSandbox
|
|
||||||
sandboxConfig := req.GetSandboxConfig()
|
|
||||||
fmt.Printf("sandboxConfig: %v\n", sandboxConfig)
|
|
||||||
|
|
||||||
// Join the namespace paths for the pod sandbox container.
|
// Join the namespace paths for the pod sandbox container.
|
||||||
podContainerName := podSandboxId + "-infra"
|
podContainerName := podSandboxID + "-infra"
|
||||||
podInfraContainer := s.state.containers.Get(podContainerName)
|
podInfraContainer := s.state.containers.Get(podContainerName)
|
||||||
podInfraState := s.runtime.ContainerStatus(podInfraContainer)
|
podInfraState := s.runtime.ContainerStatus(podInfraContainer)
|
||||||
|
|
||||||
|
@ -560,37 +249,37 @@ func (s *Server) CreateContainer(ctx context.Context, req *pb.CreateContainerReq
|
||||||
"network": "net",
|
"network": "net",
|
||||||
} {
|
} {
|
||||||
nsPath := fmt.Sprintf("/proc/%d/ns/%s", podInfraState.Pid, nsFile)
|
nsPath := fmt.Sprintf("/proc/%d/ns/%s", podInfraState.Pid, nsFile)
|
||||||
specgen.AddOrReplaceLinuxNamespace(nsType, nsPath)
|
if err := specgen.AddOrReplaceLinuxNamespace(nsType, nsPath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil {
|
if err := specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
imageSpec := containerConfig.GetImage()
|
||||||
|
if imageSpec == nil {
|
||||||
|
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Image is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
image := imageSpec.GetImage()
|
||||||
|
if image == "" {
|
||||||
|
return nil, fmt.Errorf("CreateContainerRequest.ContainerConfig.Image.Image is empty")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: copy the rootfs into the bundle.
|
// TODO: copy the rootfs into the bundle.
|
||||||
// Currently, utils.CreateFakeRootfs is used to populate the rootfs.
|
// Currently, utils.CreateFakeRootfs is used to populate the rootfs.
|
||||||
if err := utils.CreateFakeRootfs(containerDir, image); err != nil {
|
if err := utils.CreateFakeRootfs(containerDir, image); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
container, err := oci.NewContainer(name, containerDir, logPath, labels, podSandboxId, containerConfig.GetTty())
|
container, err := oci.NewContainer(name, containerDir, logPath, labels, podSandboxID, containerConfig.GetTty())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.runtime.CreateContainer(container); err != nil {
|
return container, nil
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.runtime.UpdateStatus(container); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.addContainer(container)
|
|
||||||
|
|
||||||
return &pb.CreateContainerResponse{
|
|
||||||
ContainerId: &name,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartContainer starts the container.
|
// StartContainer starts the container.
|
|
@ -2,6 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Mkdir(filepath.Join(imageStore, tr.StringWithinTransport()), 0755); err != nil {
|
if err = os.Mkdir(filepath.Join(imageStore, tr.StringWithinTransport()), 0755); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dir, err := directory.NewReference(filepath.Join(imageStore, tr.StringWithinTransport()))
|
dir, err := directory.NewReference(filepath.Join(imageStore, tr.StringWithinTransport()))
|
||||||
|
@ -69,11 +70,12 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
|
||||||
// save blobs (layer + config for docker v2s2, layers only for docker v2s1 [the config is in the manifest])
|
// save blobs (layer + config for docker v2s2, layers only for docker v2s1 [the config is in the manifest])
|
||||||
for _, b := range blobs {
|
for _, b := range blobs {
|
||||||
// TODO(runcom,nalin): we need do-then-commit to later purge on error
|
// TODO(runcom,nalin): we need do-then-commit to later purge on error
|
||||||
r, _, err := src.GetBlob(b)
|
var r io.ReadCloser
|
||||||
|
r, _, err = src.GetBlob(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if _, _, err := dest.PutBlob(r, b, -1); err != nil {
|
if _, _, err = dest.PutBlob(r, b, -1); err != nil {
|
||||||
r.Close()
|
r.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
319
server/sandbox.go
Normal file
319
server/sandbox.go
Normal file
|
@ -0,0 +1,319 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/kubernetes-incubator/ocid/oci"
|
||||||
|
pb "github.com/kubernetes/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
|
"github.com/opencontainers/ocitools/generate"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type sandbox struct {
|
||||||
|
name string
|
||||||
|
logDir string
|
||||||
|
labels map[string]string
|
||||||
|
containers oci.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
type metadata struct {
|
||||||
|
LogDir string `json:"log_dir"`
|
||||||
|
ContainerName string `json:"container_name"`
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sandbox) addContainer(c *oci.Container) {
|
||||||
|
s.containers.Add(c.Name(), c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sandbox) getContainer(name string) *oci.Container {
|
||||||
|
return s.containers.Get(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *sandbox) removeContainer(c *oci.Container) {
|
||||||
|
s.containers.Delete(c.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreatePodSandbox creates a pod-level sandbox.
|
||||||
|
// The definition of PodSandbox is at https://github.com/kubernetes/kubernetes/pull/25899
|
||||||
|
func (s *Server) CreatePodSandbox(ctx context.Context, req *pb.CreatePodSandboxRequest) (*pb.CreatePodSandboxResponse, error) {
|
||||||
|
// process req.Name
|
||||||
|
name := req.GetConfig().GetMetadata().GetName()
|
||||||
|
if name == "" {
|
||||||
|
return nil, fmt.Errorf("PodSandboxConfig.Name should not be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
podSandboxDir := filepath.Join(s.sandboxDir, name)
|
||||||
|
if _, err := os.Stat(podSandboxDir); err == nil {
|
||||||
|
return nil, fmt.Errorf("pod sandbox (%s) already exists", podSandboxDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(podSandboxDir, 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
if err2 := os.RemoveAll(podSandboxDir); err2 != nil {
|
||||||
|
logrus.Warnf("couldn't cleanup podSandboxDir %s: %v", podSandboxDir, err2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// creates a spec Generator with the default spec.
|
||||||
|
g := generate.New()
|
||||||
|
|
||||||
|
// setup defaults for the pod sandbox
|
||||||
|
g.SetRootPath("/var/lib/ocid/graph/vfs/pause")
|
||||||
|
g.SetRootReadonly(true)
|
||||||
|
g.SetProcessArgs([]string{"/pause"})
|
||||||
|
|
||||||
|
// process req.Hostname
|
||||||
|
hostname := req.GetConfig().GetHostname()
|
||||||
|
if hostname != "" {
|
||||||
|
g.SetHostname(hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// process req.LogDirectory
|
||||||
|
logDir := req.GetConfig().GetLogDirectory()
|
||||||
|
if logDir == "" {
|
||||||
|
logDir = fmt.Sprintf("/var/log/ocid/pods/%s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
dnsServers := req.GetConfig().GetDnsOptions().GetServers()
|
||||||
|
dnsSearches := req.GetConfig().GetDnsOptions().GetSearches()
|
||||||
|
resolvPath := fmt.Sprintf("%s/resolv.conf", podSandboxDir)
|
||||||
|
err = parseDNSOptions(dnsServers, dnsSearches, resolvPath)
|
||||||
|
if err != nil {
|
||||||
|
err1 := removeFile(resolvPath)
|
||||||
|
if err1 != nil {
|
||||||
|
err = err1
|
||||||
|
return nil, fmt.Errorf("%v; failed to remove %s: %v", err, resolvPath, err1)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.AddBindMount(resolvPath, "/etc/resolv.conf", "ro")
|
||||||
|
|
||||||
|
labels := req.GetConfig().GetLabels()
|
||||||
|
s.addSandbox(&sandbox{
|
||||||
|
name: name,
|
||||||
|
logDir: logDir,
|
||||||
|
labels: labels,
|
||||||
|
containers: oci.NewMemoryStore(),
|
||||||
|
})
|
||||||
|
|
||||||
|
annotations := req.GetConfig().GetAnnotations()
|
||||||
|
for k, v := range annotations {
|
||||||
|
g.AddAnnotation(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
cgroupParent := req.GetConfig().GetLinux().GetCgroupParent()
|
||||||
|
if cgroupParent != "" {
|
||||||
|
g.SetLinuxCgroupsPath(cgroupParent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up namespaces
|
||||||
|
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostNetwork() {
|
||||||
|
err = g.RemoveLinuxNamespace("network")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostPid() {
|
||||||
|
err = g.RemoveLinuxNamespace("pid")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostIpc() {
|
||||||
|
err = g.RemoveLinuxNamespace("ipc")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = g.SaveToFile(filepath.Join(podSandboxDir, "config.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
containerName := name + "-infra"
|
||||||
|
container, err := oci.NewContainer(containerName, podSandboxDir, podSandboxDir, labels, name, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.runtime.CreateContainer(container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.runtime.UpdateStatus(container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the network
|
||||||
|
podNamespace := ""
|
||||||
|
netnsPath, err := container.NetNsPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = s.netPlugin.SetUpPod(netnsPath, podNamespace, name, containerName); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create network for container %s in sandbox %s: %v", containerName, name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.runtime.StartContainer(container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.addContainer(container)
|
||||||
|
|
||||||
|
meta := &metadata{
|
||||||
|
LogDir: logDir,
|
||||||
|
ContainerName: containerName,
|
||||||
|
Labels: labels,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(meta)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: eventually we would track all containers in this pod so on server start
|
||||||
|
// we can repopulate the structs in memory properly...
|
||||||
|
// e.g. each container can write itself in podSandboxDir
|
||||||
|
err = ioutil.WriteFile(filepath.Join(podSandboxDir, "metadata.json"), b, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = s.runtime.UpdateStatus(container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.CreatePodSandboxResponse{PodSandboxId: &name}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopPodSandbox stops the sandbox. If there are any running containers in the
|
||||||
|
// sandbox, they should be force terminated.
|
||||||
|
func (s *Server) StopPodSandbox(ctx context.Context, req *pb.StopPodSandboxRequest) (*pb.StopPodSandboxResponse, error) {
|
||||||
|
sbName := req.PodSandboxId
|
||||||
|
if *sbName == "" {
|
||||||
|
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
||||||
|
}
|
||||||
|
sb := s.getSandbox(*sbName)
|
||||||
|
if sb == nil {
|
||||||
|
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
podInfraContainer := *sbName + "-infra"
|
||||||
|
for _, c := range sb.containers.List() {
|
||||||
|
if podInfraContainer == c.Name() {
|
||||||
|
podNamespace := ""
|
||||||
|
netnsPath, err := c.NetNsPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := s.netPlugin.TearDownPod(netnsPath, podNamespace, *sbName, podInfraContainer); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to destroy network for container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := s.runtime.StopContainer(c); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to stop container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.StopPodSandboxResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePodSandbox deletes the sandbox. If there are any running containers in the
|
||||||
|
// sandbox, they should be force deleted.
|
||||||
|
func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxRequest) (*pb.RemovePodSandboxResponse, error) {
|
||||||
|
sbName := req.PodSandboxId
|
||||||
|
if *sbName == "" {
|
||||||
|
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
||||||
|
}
|
||||||
|
sb := s.getSandbox(*sbName)
|
||||||
|
if sb == nil {
|
||||||
|
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
podInfraContainer := *sbName + "-infra"
|
||||||
|
|
||||||
|
// Delete all the containers in the sandbox
|
||||||
|
for _, c := range sb.containers.List() {
|
||||||
|
if err := s.runtime.DeleteContainer(c); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to delete container %s in sandbox %s: %v", c.Name(), *sbName, err)
|
||||||
|
}
|
||||||
|
if podInfraContainer == c.Name() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
containerDir := filepath.Join(s.runtime.ContainerDir(), c.Name())
|
||||||
|
if err := os.RemoveAll(containerDir); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to remove container %s directory: %v", c.Name(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the files related to the sandbox
|
||||||
|
podSandboxDir := filepath.Join(s.sandboxDir, *sbName)
|
||||||
|
if err := os.RemoveAll(podSandboxDir); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to remove sandbox %s directory: %v", *sbName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.RemovePodSandboxResponse{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodSandboxStatus returns the Status of the PodSandbox.
|
||||||
|
func (s *Server) PodSandboxStatus(ctx context.Context, req *pb.PodSandboxStatusRequest) (*pb.PodSandboxStatusResponse, error) {
|
||||||
|
sbName := req.PodSandboxId
|
||||||
|
if *sbName == "" {
|
||||||
|
return nil, fmt.Errorf("PodSandboxId should not be empty")
|
||||||
|
}
|
||||||
|
sb := s.getSandbox(*sbName)
|
||||||
|
if sb == nil {
|
||||||
|
return nil, fmt.Errorf("specified sandbox not found: %s", *sbName)
|
||||||
|
}
|
||||||
|
|
||||||
|
podInfraContainerName := *sbName + "-infra"
|
||||||
|
podInfraContainer := sb.getContainer(podInfraContainerName)
|
||||||
|
|
||||||
|
cState := s.runtime.ContainerStatus(podInfraContainer)
|
||||||
|
created := cState.Created.Unix()
|
||||||
|
|
||||||
|
netNsPath, err := podInfraContainer.NetNsPath()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
podNamespace := ""
|
||||||
|
ip, err := s.netPlugin.GetContainerNetworkStatus(netNsPath, podNamespace, *sbName, podInfraContainerName)
|
||||||
|
if err != nil {
|
||||||
|
// ignore the error on network status
|
||||||
|
ip = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.PodSandboxStatusResponse{
|
||||||
|
Status: &pb.PodSandboxStatus{
|
||||||
|
Id: sbName,
|
||||||
|
CreatedAt: int64Ptr(created),
|
||||||
|
Linux: &pb.LinuxPodSandboxStatus{
|
||||||
|
Namespaces: &pb.Namespace{
|
||||||
|
Network: sPtr(netNsPath),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Network: &pb.PodSandboxNetworkStatus{Ip: &ip},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListPodSandbox returns a list of SandBox.
|
||||||
|
func (s *Server) ListPodSandbox(context.Context, *pb.ListPodSandboxRequest) (*pb.ListPodSandboxResponse, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -29,7 +29,7 @@ type Server struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) loadSandboxes() error {
|
func (s *Server) loadSandboxes() error {
|
||||||
if err := filepath.Walk(s.sandboxDir, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(s.sandboxDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ func (s *Server) loadSandboxes() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var m metadata
|
var m metadata
|
||||||
if err := json.Unmarshal(metaJSON, &m); err != nil {
|
if err2 := json.Unmarshal(metaJSON, &m); err2 != nil {
|
||||||
return err
|
return err2
|
||||||
}
|
}
|
||||||
sname, err := filepath.Rel(s.sandboxDir, path)
|
sname, err := filepath.Rel(s.sandboxDir, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -55,7 +55,7 @@ func (s *Server) loadSandboxes() error {
|
||||||
name: sname,
|
name: sname,
|
||||||
logDir: m.LogDir,
|
logDir: m.LogDir,
|
||||||
labels: m.Labels,
|
labels: m.Labels,
|
||||||
containers: make(map[string]*oci.Container),
|
containers: oci.NewMemoryStore(),
|
||||||
})
|
})
|
||||||
scontainer, err := oci.NewContainer(m.ContainerName, path, path, m.Labels, sname, false)
|
scontainer, err := oci.NewContainer(m.ContainerName, path, path, m.Labels, sname, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -66,10 +66,8 @@ func (s *Server) loadSandboxes() error {
|
||||||
logrus.Warnf("error updating status for container %s: %v", scontainer, err)
|
logrus.Warnf("error updating status for container %s: %v", scontainer, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}); err != nil {
|
})
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Server with options provided
|
// New creates a new Server with options provided
|
||||||
|
@ -122,31 +120,6 @@ type serverState struct {
|
||||||
containers oci.Store
|
containers oci.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
type sandbox struct {
|
|
||||||
name string
|
|
||||||
logDir string
|
|
||||||
labels map[string]string
|
|
||||||
containers oci.Store
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadata struct {
|
|
||||||
LogDir string `json:"log_dir"`
|
|
||||||
ContainerName string `json:"container_name"`
|
|
||||||
Labels map[string]string `json:"labels"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sandbox) addContainer(c *oci.Container) {
|
|
||||||
s.containers.Add(c.Name(), c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sandbox) getContainer(name string) *oci.Container {
|
|
||||||
return s.containers.Get(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *sandbox) removeContainer(c *oci.Container) {
|
|
||||||
s.containers.Delete(c.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) addSandbox(sb *sandbox) {
|
func (s *Server) addSandbox(sb *sandbox) {
|
||||||
s.stateLock.Lock()
|
s.stateLock.Lock()
|
||||||
s.state.sandboxes[sb.name] = sb
|
s.state.sandboxes[sb.name] = sb
|
||||||
|
|
|
@ -10,9 +10,26 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/kubernetes-incubator/ocid/utils"
|
"github.com/kubernetes-incubator/ocid/utils"
|
||||||
"github.com/opencontainers/ocitools/generate"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// According to http://man7.org/linux/man-pages/man5/resolv.conf.5.html:
|
||||||
|
// "The search list is currently limited to six domains with a total of 256 characters."
|
||||||
|
maxDNSSearches = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
func int64Ptr(i int64) *int64 {
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
func int32Ptr(i int32) *int32 {
|
||||||
|
return &i
|
||||||
|
}
|
||||||
|
|
||||||
|
func sPtr(s string) *string {
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
func getGPRCVersion() (string, error) {
|
func getGPRCVersion() (string, error) {
|
||||||
_, file, _, ok := runtime.Caller(0)
|
_, file, _, ok := runtime.Caller(0)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -44,10 +61,8 @@ func copyFile(src, dest string) error {
|
||||||
}
|
}
|
||||||
defer out.Close()
|
defer out.Close()
|
||||||
|
|
||||||
if _, err := io.Copy(out, in); err != nil {
|
_, err = io.Copy(out, in)
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeFile(path string) error {
|
func removeFile(path string) error {
|
||||||
|
@ -94,62 +109,3 @@ func parseDNSOptions(servers, searches []string, path string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// kubernetes compute resources - CPU: http://kubernetes.io/docs/user-guide/compute-resources/#meaning-of-cpu
|
|
||||||
func setResourcesCPU(limits, requests, defaultCores float64, g generate.Generator) error {
|
|
||||||
if requests > limits {
|
|
||||||
return fmt.Errorf("CPU.Requests should not be greater than CPU.Limits")
|
|
||||||
}
|
|
||||||
|
|
||||||
cores := defaultCores
|
|
||||||
if limits != 0 || requests != 0 {
|
|
||||||
if limits > requests {
|
|
||||||
cores = limits
|
|
||||||
} else {
|
|
||||||
cores = requests
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
period := uint64(defaultCPUCFSPeriod)
|
|
||||||
quota := uint64(float64(period) * cores)
|
|
||||||
|
|
||||||
if quota < minCPUCFSQuota {
|
|
||||||
quota = minCPUCFSQuota
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust quota and period for the case where multiple CPUs are requested
|
|
||||||
// so that cpu.cfs_quota_us <= maxCPUCFSQuota.
|
|
||||||
for quota > maxCPUCFSQuota {
|
|
||||||
quota /= 10
|
|
||||||
period /= 10
|
|
||||||
}
|
|
||||||
|
|
||||||
g.SetLinuxResourcesCPUPeriod(period)
|
|
||||||
g.SetLinuxResourcesCPUQuota(quota)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// kubernetes compute resources - Memory: http://kubernetes.io/docs/user-guide/compute-resources/#meaning-of-memory
|
|
||||||
func setResourcesMemory(limits, requests, defaultMem float64, g generate.Generator) error {
|
|
||||||
if requests > limits {
|
|
||||||
return fmt.Errorf("Memory.Requests should not be greater than Memory.Limits")
|
|
||||||
}
|
|
||||||
|
|
||||||
if limits != 0 {
|
|
||||||
if requests == 0 {
|
|
||||||
requests = limits
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if requests == 0 {
|
|
||||||
// set the default values of limits and requests
|
|
||||||
requests = defaultMem
|
|
||||||
limits = defaultMem
|
|
||||||
} else {
|
|
||||||
limits = requests
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g.SetLinuxResourcesMemoryLimit(uint64(limits))
|
|
||||||
g.SetLinuxResourcesMemoryReservation(uint64(requests))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
30
server/version.go
Normal file
30
server/version.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
pb "github.com/kubernetes/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Version returns the runtime name, runtime version and runtime API version
|
||||||
|
func (s *Server) Version(ctx context.Context, req *pb.VersionRequest) (*pb.VersionResponse, error) {
|
||||||
|
version, err := getGPRCVersion()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
runtimeVersion, err := s.runtime.Version()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// taking const address
|
||||||
|
rav := runtimeAPIVersion
|
||||||
|
runtimeName := s.runtime.Name()
|
||||||
|
|
||||||
|
return &pb.VersionResponse{
|
||||||
|
Version: &version,
|
||||||
|
RuntimeName: &runtimeName,
|
||||||
|
RuntimeVersion: &runtimeVersion,
|
||||||
|
RuntimeApiVersion: &rav,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package utils
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
@ -13,8 +14,11 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const PR_SET_CHILD_SUBREAPER = 36
|
// PRSetChildSubreaper is the value of PR_SET_CHILD_SUBREAPER in prctl(2)
|
||||||
|
const PRSetChildSubreaper = 36
|
||||||
|
|
||||||
|
// ExecCmd executes a command with args and returns its output as a string along
|
||||||
|
// with an error, if any
|
||||||
func ExecCmd(name string, args ...string) (string, error) {
|
func ExecCmd(name string, args ...string) (string, error) {
|
||||||
cmd := exec.Command(name, args...)
|
cmd := exec.Command(name, args...)
|
||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
|
@ -31,7 +35,7 @@ func ExecCmd(name string, args ...string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecCmdWithStdStreams execute a command with the specified standard streams.
|
// ExecCmdWithStdStreams execute a command with the specified standard streams.
|
||||||
func ExecCmdWithStdStreams(stdin, stdout, stderr *os.File, name string, args ...string) error {
|
func ExecCmdWithStdStreams(stdin io.Reader, stdout, stderr io.Writer, name string, args ...string) error {
|
||||||
cmd := exec.Command(name, args...)
|
cmd := exec.Command(name, args...)
|
||||||
cmd.Stdin = stdin
|
cmd.Stdin = stdin
|
||||||
cmd.Stdout = stdout
|
cmd.Stdout = stdout
|
||||||
|
@ -47,7 +51,7 @@ func ExecCmdWithStdStreams(stdin, stdout, stderr *os.File, name string, args ...
|
||||||
|
|
||||||
// SetSubreaper sets the value i as the subreaper setting for the calling process
|
// SetSubreaper sets the value i as the subreaper setting for the calling process
|
||||||
func SetSubreaper(i int) error {
|
func SetSubreaper(i int) error {
|
||||||
return Prctl(PR_SET_CHILD_SUBREAPER, uintptr(i), 0, 0, 0)
|
return Prctl(PRSetChildSubreaper, uintptr(i), 0, 0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prctl is a way to make the prctl linux syscall
|
// Prctl is a way to make the prctl linux syscall
|
||||||
|
@ -95,10 +99,8 @@ func dockerExport(image string, rootfs string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerRemove(container string) error {
|
func dockerRemove(container string) error {
|
||||||
if _, err := ExecCmd("docker", "rm", container); err != nil {
|
_, err := ExecCmd("docker", "rm", container)
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartReaper starts a goroutine to reap processes
|
// StartReaper starts a goroutine to reap processes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue