Add first version of createPodSandbox

Signed-off-by: Haiyan Meng <hmeng@redhat.com>
This commit is contained in:
Haiyan Meng 2016-07-19 21:30:05 -04:00 committed by Mrunal Patel
parent 0766dfecfe
commit 819d76b6fd
7 changed files with 361 additions and 23 deletions

2
Godeps/Godeps.json generated
View file

@ -277,7 +277,7 @@
},
{
"ImportPath": "github.com/opencontainers/ocitools/generate",
"Rev": "cc6b67605256c65ba19da6a201e3b0f264b8ba40"
"Rev": "3c4fc86f2c260090282737419c83c43c47630df8"
},
{
"ImportPath": "github.com/opencontainers/runc/libcontainer/user",

View file

@ -1,6 +1,7 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net"
@ -30,6 +31,39 @@ func getClientConnection() (*grpc.ClientConn, error) {
return conn, nil
}
func loadPodSandboxConfig(path string) (*pb.PodSandboxConfig, error) {
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil, fmt.Errorf("pod sandbox config at %s not found", path)
}
return nil, err
}
defer f.Close()
var config pb.PodSandboxConfig
if err := json.NewDecoder(f).Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
// CreatePodSandbox sends a CreatePodSandboxRequest to the server, and parses
// the returned CreatePodSandboxResponse.
func CreatePodSandbox(client pb.RuntimeServiceClient, path string) error {
config, err := loadPodSandboxConfig(path)
if err != nil {
return err
}
r, err := client.CreatePodSandbox(context.Background(), &pb.CreatePodSandboxRequest{Config: config})
if err != nil {
return err
}
fmt.Println(r)
return nil
}
// Version sends a VersionRequest to the server, and parses the returned VersionResponse.
func Version(client pb.RuntimeServiceClient, version string) error {
r, err := client.Version(context.Background(), &pb.VersionRequest{Version: &version})
@ -47,6 +81,7 @@ func main() {
app.Commands = []cli.Command{
runtimeVersionCommand,
createPodSandboxCommand,
pullImageCommand,
}
@ -105,3 +140,31 @@ var runtimeVersionCommand = cli.Command{
return nil
},
}
var createPodSandboxCommand = cli.Command{
Name: "createpodsandbox",
Usage: "create a pod sandbox",
Flags: []cli.Flag{
cli.StringFlag{
Name: "config",
Value: "config.json",
Usage: "the path of a pod sandbox config file",
},
},
Action: func(context *cli.Context) error {
// Set up a connection to the server.
conn, err := getClientConnection()
if err != nil {
return fmt.Errorf("Failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewRuntimeServiceClient(conn)
// Test RuntimeServiceClient.CreatePodSandbox
err = CreatePodSandbox(client, context.String("config"))
if err != nil {
return fmt.Errorf("Creating the pod sandbox failed: %v", err)
}
return nil
},
}

View file

@ -0,0 +1,54 @@
{
"name": "podsandbox1",
"hostname": "ocic_host",
"log_directory": ".",
"dns_options": {
"servers": [
"server1.redhat.com",
"server2.redhat.com"
],
"searches": [
"8.8.8.8"
]
},
"port_mappings": [
{
"name": "port_map1",
"protocol": 1,
"container_port": 80,
"host_port": 4888,
"host_ip": "192.168.0.33"
},
{
"name": "port_map2",
"protocol": 2,
"container_port": 81,
"host_port": 4889,
"host_ip": "192.168.0.33"
}
],
"resources": {
"cpu": {
"limits": 50000000,
"requests": 20000000
},
"memory": {
"limits": 500000000000,
"requests": 200000000000
}
},
"lables": {
"group": "test"
},
"annotations": {
"owner": "hmeng"
},
"linux": {
"cgroup_parent": "/sys/fs/cgroup/test",
"namespace_options": {
"host_network": true,
"host_pid": true,
"host_ipc": true
}
}
}

View file

@ -7,6 +7,7 @@ import (
"github.com/kubernetes/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
"github.com/mrunalp/ocid/server"
"github.com/urfave/cli"
"google.golang.org/grpc"
)
@ -15,22 +16,45 @@ const (
)
func main() {
// Remove the socket if it already exists
if _, err := os.Stat(unixDomainSocket); err == nil {
if err := os.Remove(unixDomainSocket); err != nil {
app := cli.NewApp()
app.Name = "ocic"
app.Usage = "client for ocid"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "sandboxdir",
Value: "/var/lib/ocid/sandbox",
Usage: "ocid pod sandbox dir",
},
}
app.Action = func(c *cli.Context) error {
// Remove the socket if it already exists
if _, err := os.Stat(unixDomainSocket); err == nil {
if err := os.Remove(unixDomainSocket); err != nil {
log.Fatal(err)
}
}
lis, err := net.Listen("unix", unixDomainSocket)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
sandboxDir := c.String("sandboxdir")
service, err := server.New("", sandboxDir)
if err != nil {
log.Fatal(err)
}
runtime.RegisterRuntimeServiceServer(s, service)
runtime.RegisterImageServiceServer(s, service)
s.Serve(lis)
return nil
}
lis, err := net.Listen("unix", unixDomainSocket)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
service, err := server.New("")
if err != nil {
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
runtime.RegisterRuntimeServiceServer(s, service)
runtime.RegisterImageServiceServer(s, service)
s.Serve(lis)
}

View file

@ -1,6 +1,9 @@
package server
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
pb "github.com/kubernetes/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
@ -37,16 +40,124 @@ func (s *Server) Version(ctx context.Context, req *pb.VersionRequest) (*pb.Versi
func (s *Server) CreatePodSandbox(ctx context.Context, req *pb.CreatePodSandboxRequest) (*pb.CreatePodSandboxResponse, error) {
var err error
// TODO: Parametrize as a global argument to ocid
ocidSandboxDir := "/var/lib/ocid/sandbox"
podSandboxDir := filepath.Join(ocidSandboxDir, req.GetConfig().GetName())
if err := os.MkdirAll(s.sandboxDir, 0755); err != nil {
return nil, err
}
// process req.Name
name := req.GetConfig().GetName()
var podSandboxDir string
if name == "" {
podSandboxDir, err := ioutil.TempDir(s.sandboxDir, "")
if err != nil {
return nil, err
}
name = filepath.Base(podSandboxDir)
} else {
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
}
}
// creates a spec Generator with the default spec.
g := generate.New()
// TODO: Customize the config per the settings in the req
err = g.SaveToFile(filepath.Join(podSandboxDir, "config.json"))
// process req.Hostname
hostname := req.GetConfig().GetHostname()
if hostname != "" {
g.SetHostname(hostname)
}
return nil, err
// process req.LogDirectory
logDir := req.GetConfig().GetLogDirectory()
if logDir == "" {
logDir = fmt.Sprintf("/var/log/ocid/pods/%s", name)
}
// TODO: construct /etc/resolv.conf based on dnsOpts.
dnsOpts := req.GetConfig().GetDnsOptions()
fmt.Println(dnsOpts)
// TODO: the unit of cpu here is cores. How to map it into specs.Spec.Linux.Resouces.CPU?
cpu := req.GetConfig().GetResources().GetCpu()
if cpu != nil {
limits := cpu.GetLimits()
requests := cpu.GetRequests()
fmt.Println(limits)
fmt.Println(requests)
}
memory := req.GetConfig().GetResources().GetMemory()
if memory != nil {
// limits sets specs.Spec.Linux.Resouces.Memory.Limit
limits := memory.GetLimits()
if limits != 0 {
g.SetLinuxResourcesMemoryLimit(uint64(limits))
}
// requests sets specs.Spec.Linux.Resouces.Memory.Reservation
requests := memory.GetRequests()
if requests != 0 {
g.SetLinuxResourcesMemoryReservation(uint64(requests))
}
}
labels := req.GetConfig().GetLabels()
s.sandboxes = append(s.sandboxes, &sandbox{
name: name,
logDir: logDir,
labels: labels,
})
annotations := req.GetConfig().GetAnnotations()
for k, v := range annotations {
err := g.AddAnnotation(fmt.Sprintf("%s=%s", k, v))
if err != nil {
return nil, err
}
}
// TODO: double check cgroupParent.
cgroupParent := req.GetConfig().GetLinux().GetCgroupParent()
if cgroupParent != "" {
g.SetLinuxCgroupsPath(cgroupParent)
}
// set up namespaces
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostNetwork() == false {
err := g.AddOrReplaceLinuxNamespace("network", "")
if err != nil {
return nil, err
}
}
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostPid() == false {
err := g.AddOrReplaceLinuxNamespace("pid", "")
if err != nil {
return nil, err
}
}
if req.GetConfig().GetLinux().GetNamespaceOptions().GetHostIpc() == false {
err := g.AddOrReplaceLinuxNamespace("ipc", "")
if err != nil {
return nil, err
}
}
err = g.SaveToFile(filepath.Join(podSandboxDir, "config.json"))
if err != nil {
return nil, err
}
return &pb.CreatePodSandboxResponse{PodSandboxId: &name}, nil
}
// StopPodSandbox stops the sandbox. If there are any running containers in the

View file

@ -6,16 +6,19 @@ const (
// Server implements the RuntimeService and ImageService
type Server struct {
runtime ociRuntime
runtime ociRuntime
sandboxDir string
sandboxes []*sandbox
}
// New creates a new Server with options provided
func New(runtimePath string) (*Server, error) {
func New(runtimePath, sandboxDir string) (*Server, error) {
// TODO(runcom): runtimePath arg is unused but it might be useful
// if we're willing to open the doors to other runtimes in the future.
r := &runcRuntime{}
return &Server{
runtime: r,
runtime: r,
sandboxDir: sandboxDir,
}, nil
}
@ -50,3 +53,9 @@ func (r *runcRuntime) Version() (string, error) {
}
return runtimeVersion, nil
}
type sandbox struct {
name string
logDir string
labels map[string]string
}

View file

@ -342,6 +342,83 @@ func (g Generator) SetLinuxMountLabel(label string) {
g.spec.Linux.MountLabel = label
}
// SetLinuxResourcesCPUShares sets g.spec.Linux.Resources.CPU.Shares.
func (g Generator) SetLinuxResourcesCPUShares(shares uint64) {
g.spec.Linux.Resources.CPU.Shares = &shares
}
// SetLinuxResourcesCPUQuota sets g.spec.Linux.Resources.CPU.Quota.
func (g Generator) SetLinuxResourcesCPUQuota(quota uint64) {
g.spec.Linux.Resources.CPU.Quota = &quota
}
// SetLinuxResourcesCPUPeriod sets g.spec.Linux.Resources.CPU.Period.
func (g Generator) SetLinuxResourcesCPUPeriod(period uint64) {
g.spec.Linux.Resources.CPU.Period = &period
}
// SetLinuxResourcesCPURealtimeRuntime sets g.spec.Linux.Resources.CPU.RealtimeRuntime.
func (g Generator) SetLinuxResourcesCPURealtimeRuntime(time uint64) {
g.spec.Linux.Resources.CPU.RealtimeRuntime = &time
}
// SetLinuxResourcesCPURealtimePeriod sets g.spec.Linux.Resources.CPU.RealtimePeriod.
func (g Generator) SetLinuxResourcesCPURealtimePeriod(period uint64) {
g.spec.Linux.Resources.CPU.RealtimePeriod = &period
}
// SetLinuxResourcesCPUCpus sets g.spec.Linux.Resources.CPU.Cpus.
func (g Generator) SetLinuxResourcesCPUCpus(cpus string) {
g.spec.Linux.Resources.CPU.Cpus = &cpus
}
// SetLinuxResourcesCPUMems sets g.spec.Linux.Resources.CPU.Mems.
func (g Generator) SetLinuxResourcesCPUMems(mems string) {
g.spec.Linux.Resources.CPU.Mems = &mems
}
// SetLinuxResourcesMemoryLimit sets g.spec.Linux.Resources.Memory.Limit.
func (g Generator) SetLinuxResourcesMemoryLimit(limit uint64) {
if g.spec.Linux == nil {
g.spec.Linux = &rspec.Linux{}
}
if g.spec.Linux.Resources == nil {
g.spec.Linux.Resources = &rspec.Resources{}
}
if g.spec.Linux.Resources.Memory == nil {
g.spec.Linux.Resources.Memory = &rspec.Memory{}
}
g.spec.Linux.Resources.Memory.Limit = &limit
}
// SetLinuxResourcesMemoryReservation sets g.spec.Linux.Resources.Memory.Reservation.
func (g Generator) SetLinuxResourcesMemoryReservation(reservation uint64) {
g.spec.Linux.Resources.Memory.Reservation = &reservation
}
// SetLinuxResourcesMemorySwap sets g.spec.Linux.Resources.Memory.Swap.
func (g Generator) SetLinuxResourcesMemorySwap(swap uint64) {
g.spec.Linux.Resources.Memory.Swap = &swap
}
// SetLinuxResourcesMemoryKernel sets g.spec.Linux.Resources.Memory.Kernel.
func (g Generator) SetLinuxResourcesMemoryKernel(kernel uint64) {
g.spec.Linux.Resources.Memory.Kernel = &kernel
}
// SetLinuxResourcesMemoryKernelTCP sets g.spec.Linux.Resources.Memory.KernelTCP.
func (g Generator) SetLinuxResourcesMemoryKernelTCP(kernelTCP uint64) {
g.spec.Linux.Resources.Memory.KernelTCP = &kernelTCP
}
// SetLinuxResourcesMemorySwappiness sets g.spec.Linux.Resources.Memory.Swappiness.
func (g Generator) SetLinuxResourcesMemorySwappiness(swappiness uint64) {
g.spec.Linux.Resources.Memory.Swappiness = &swappiness
}
// ClearLinuxSysctl clears g.spec.Linux.Sysctl.
func (g Generator) ClearLinuxSysctl() {
g.spec.Linux.Sysctl = make(map[string]string)