From e14e4576c919b2be1fa0d86bd69f64770ab3bb9c Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Wed, 9 Dec 2015 14:18:31 -0800 Subject: [PATCH] Prototype of grpc API Signed-off-by: Alexander Morozov --- api/grpc/gctr/container.go | 121 ++++++ api/grpc/gctr/main.go | 53 +++ api/grpc/server/server.go | 234 ++++++++++++ api/grpc/types/api.pb.go | 762 +++++++++++++++++++++++++++++++++++++ api/grpc/types/api.proto | 145 +++++++ containerd/main.go | 16 + 6 files changed, 1331 insertions(+) create mode 100644 api/grpc/gctr/container.go create mode 100644 api/grpc/gctr/main.go create mode 100644 api/grpc/server/server.go create mode 100644 api/grpc/types/api.pb.go create mode 100644 api/grpc/types/api.proto diff --git a/api/grpc/gctr/container.go b/api/grpc/gctr/container.go new file mode 100644 index 000000000..87b96503d --- /dev/null +++ b/api/grpc/gctr/container.go @@ -0,0 +1,121 @@ +package main + +import ( + "fmt" + "os" + "text/tabwriter" + + "google.golang.org/grpc" + + "github.com/Sirupsen/logrus" + "github.com/codegangsta/cli" + "github.com/docker/containerd/api/grpc/types" + netcontext "golang.org/x/net/context" +) + +// TODO: parse flags and pass opts +func getClient() types.APIClient { + conn, err := grpc.Dial("localhost:8888", grpc.WithInsecure()) + if err != nil { + fatal(err.Error(), 1) + } + return types.NewAPIClient(conn) +} + +var ContainersCommand = cli.Command{ + Name: "containers", + Usage: "interact with running containers", + Subcommands: []cli.Command{ + StartCommand, + ListCommand, + KillCommand, + }, + Action: listContainers, +} + +var ListCommand = cli.Command{ + Name: "list", + Usage: "list all running containers", + Action: listContainers, +} + +func listContainers(context *cli.Context) { + cli := getClient() + resp, err := cli.State(netcontext.Background(), &types.StateRequest{}) + if err != nil { + fatal(err.Error(), 1) + } + w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0) + fmt.Fprint(w, "ID\tPATH\tSTATUS\n") + for _, c := range resp.Containers { + fmt.Fprintf(w, "%s\t%s\t%s\n", c.Id, c.BundlePath, c.Status) + } + if err := w.Flush(); err != nil { + logrus.Fatal(err) + } +} + +var StartCommand = cli.Command{ + Name: "start", + Usage: "start a container", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Value: "", + Usage: "id of the container", + }, + cli.StringFlag{ + Name: "checkpoint,c", + Value: "", + Usage: "checkpoint to start the container from", + }, + }, + Action: func(context *cli.Context) { + path := context.Args().First() + if path == "" { + fatal("bundle path cannot be empty", 1) + } + id := context.String("id") + if id == "" { + fatal("container id cannot be empty", 1) + } + c := getClient() + if _, err := c.CreateContainer(netcontext.Background(), &types.CreateContainerRequest{ + Id: id, + BundlePath: path, + Checkpoint: context.String("checkpoint"), + }); err != nil { + fatal(err.Error(), 1) + } + }, +} + +var KillCommand = cli.Command{ + Name: "kill", + Usage: "send a signal to a container or it's processes", + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "pid,p", + Usage: "pid of the process to signal within the container", + }, + cli.IntFlag{ + Name: "signal,s", + Value: 15, + Usage: "signal to send to the container", + }, + }, + Action: func(context *cli.Context) { + id := context.Args().First() + if id == "" { + fatal("container id cannot be empty", 1) + } + c := getClient() + if _, err := c.Signal(netcontext.Background(), &types.SignalRequest{ + Id: id, + Pid: uint32(context.Int("pid")), + Signal: uint32(context.Int("signal")), + }); err != nil { + fatal(err.Error(), 1) + } + }, +} diff --git a/api/grpc/gctr/main.go b/api/grpc/gctr/main.go new file mode 100644 index 000000000..a189d2cf7 --- /dev/null +++ b/api/grpc/gctr/main.go @@ -0,0 +1,53 @@ +package main + +import ( + "fmt" + "os" + + "github.com/Sirupsen/logrus" + "github.com/codegangsta/cli" + "github.com/docker/containerd" +) + +const Usage = `High performance conatiner daemon controller` + +func main() { + app := cli.NewApp() + app.Name = "ctr" + app.Version = containerd.Version + app.Usage = Usage + app.Authors = []cli.Author{ + { + Name: "@crosbymichael", + Email: "crosbymichael@gmail.com", + }, + } + app.Flags = []cli.Flag{ + cli.BoolFlag{ + Name: "debug", + Usage: "enable debug output in the logs", + }, + cli.StringFlag{ + Name: "addr", + Value: "http://localhost:8888", + Usage: "address to the containerd api", + }, + } + app.Commands = []cli.Command{ + ContainersCommand, + } + app.Before = func(context *cli.Context) error { + if context.GlobalBool("debug") { + logrus.SetLevel(logrus.DebugLevel) + } + return nil + } + if err := app.Run(os.Args); err != nil { + logrus.Fatal(err) + } +} + +func fatal(err string, code int) { + fmt.Fprintf(os.Stderr, "[ctr] %s", err) + os.Exit(code) +} diff --git a/api/grpc/server/server.go b/api/grpc/server/server.go new file mode 100644 index 000000000..9ccca9220 --- /dev/null +++ b/api/grpc/server/server.go @@ -0,0 +1,234 @@ +package server + +import ( + "errors" + "syscall" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + + "github.com/Sirupsen/logrus" + "github.com/docker/containerd" + "github.com/docker/containerd/api/grpc/types" + "github.com/docker/containerd/runtime" + "github.com/opencontainers/specs" + "golang.org/x/net/context" +) + +type apiServer struct { + sv *containerd.Supervisor +} + +// NewServer returns grpc server instance +func NewServer(sv *containerd.Supervisor) types.APIServer { + return &apiServer{ + sv: sv, + } +} + +func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContainerRequest) (*types.CreateContainerResponse, error) { + if c.BundlePath == "" { + return nil, errors.New("empty bundle path") + } + e := containerd.NewEvent(containerd.StartContainerEventType) + e.ID = c.Id + e.BundlePath = c.BundlePath + if c.Checkpoint != "" { + e.Checkpoint = &runtime.Checkpoint{ + Name: c.Checkpoint, + } + } + e.Stdio = &runtime.Stdio{ + Stderr: c.Stderr, + Stdout: c.Stdout, + } + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.CreateContainerResponse{}, nil +} + +func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) { + e := containerd.NewEvent(containerd.SignalEventType) + e.ID = r.Id + e.Pid = int(r.Pid) + e.Signal = syscall.Signal(int(r.Signal)) + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.SignalResponse{}, nil +} + +func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) { + process := &specs.Process{ + Terminal: r.Terminal, + Args: r.Args, + Env: r.Env, + Cwd: r.Cwd, + User: specs.User{ + UID: r.User.Uid, + GID: r.User.Gid, + AdditionalGids: r.User.AdditionalGids, + }, + } + e := containerd.NewEvent(containerd.AddProcessEventType) + e.ID = r.Id + e.Process = process + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.AddProcessResponse{Pid: uint32(e.Pid)}, nil +} + +func (s *apiServer) CreateCheckpoint(ctx context.Context, r *types.CreateCheckpointRequest) (*types.CreateCheckpointResponse, error) { + e := containerd.NewEvent(containerd.CreateCheckpointEventType) + e.ID = r.Id + e.Checkpoint = &runtime.Checkpoint{ + Name: r.Checkpoint.Name, + Exit: r.Checkpoint.Exit, + Tcp: r.Checkpoint.Tcp, + UnixSockets: r.Checkpoint.UnixSockets, + Shell: r.Checkpoint.Shell, + } + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.CreateCheckpointResponse{}, nil +} + +func (s *apiServer) DeleteCheckpoint(ctx context.Context, r *types.DeleteCheckpointRequest) (*types.DeleteCheckpointResponse, error) { + if r.Name == "" { + return nil, errors.New("checkpoint name cannot be empty") + } + e := containerd.NewEvent(containerd.DeleteCheckpointEventType) + e.ID = r.Id + e.Checkpoint = &runtime.Checkpoint{ + Name: r.Name, + } + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.DeleteCheckpointResponse{}, nil +} + +func (s *apiServer) ListCheckpoint(ctx context.Context, r *types.ListCheckpointRequest) (*types.ListCheckpointResponse, error) { + e := containerd.NewEvent(containerd.GetContainerEventType) + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + var container runtime.Container + for _, c := range e.Containers { + if c.ID() == r.Id { + container = c + break + } + } + if container == nil { + return nil, grpc.Errorf(codes.NotFound, "no such containers") + } + checkpoints, err := container.Checkpoints() + if err != nil { + return nil, err + } + var out []*types.Checkpoint + for _, c := range checkpoints { + out = append(out, &types.Checkpoint{ + Name: c.Name, + Tcp: c.Tcp, + Shell: c.Shell, + UnixSockets: c.UnixSockets, + // TODO: figure out timestamp + //Timestamp: c.Timestamp, + }) + } + return &types.ListCheckpointResponse{Checkpoints: out}, nil +} + +func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) { + e := containerd.NewEvent(containerd.GetContainerEventType) + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + m := s.sv.Machine() + state := &types.StateResponse{ + Machine: &types.Machine{ + Id: m.ID, + Cpus: uint32(m.Cpus), + Memory: uint64(m.Cpus), + }, + } + for _, c := range e.Containers { + processes, err := c.Processes() + if err != nil { + return nil, grpc.Errorf(codes.Internal, "get processes for container") + } + var procs []*types.Process + for _, p := range processes { + pid, err := p.Pid() + if err != nil { + logrus.WithField("error", err).Error("get process pid") + } + oldProc := p.Spec() + procs = append(procs, &types.Process{ + Pid: uint32(pid), + Terminal: oldProc.Terminal, + Args: oldProc.Args, + Env: oldProc.Env, + Cwd: oldProc.Cwd, + User: &types.User{ + Uid: oldProc.User.UID, + Gid: oldProc.User.GID, + AdditionalGids: oldProc.User.AdditionalGids, + }, + }) + } + state.Containers = append(state.Containers, &types.Container{ + Id: c.ID(), + BundlePath: c.Path(), + Processes: procs, + Status: string(c.State().Status), + }) + } + return state, nil +} + +func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) { + e := containerd.NewEvent(containerd.UpdateContainerEventType) + e.ID = r.Id + if r.Signal != 0 { + e.Signal = syscall.Signal(r.Signal) + } + e.State = &runtime.State{ + Status: runtime.Status(r.Status), + } + s.sv.SendEvent(e) + if err := <-e.Err; err != nil { + return nil, err + } + return &types.UpdateContainerResponse{}, nil +} + +func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error { + events := s.sv.Events() + for evt := range events { + switch evt.Type { + case containerd.ExitEventType: + ev := &types.Event{ + Type: "exit", + Id: evt.ID, + Status: uint32(evt.Status), + } + if err := stream.Send(ev); err != nil { + return err + } + } + } + return nil +} diff --git a/api/grpc/types/api.pb.go b/api/grpc/types/api.pb.go new file mode 100644 index 000000000..a4aab76f7 --- /dev/null +++ b/api/grpc/types/api.pb.go @@ -0,0 +1,762 @@ +// Code generated by protoc-gen-go. +// source: api.proto +// DO NOT EDIT! + +/* +Package types is a generated protocol buffer package. + +It is generated from these files: + api.proto + +It has these top-level messages: + CreateContainerRequest + CreateContainerResponse + SignalRequest + SignalResponse + AddProcessRequest + User + AddProcessResponse + CreateCheckpointRequest + CreateCheckpointResponse + DeleteCheckpointRequest + DeleteCheckpointResponse + ListCheckpointRequest + Checkpoint + ListCheckpointResponse + StateRequest + ContainerState + Process + Container + Machine + StateResponse + UpdateContainerRequest + UpdateContainerResponse + EventsRequest + Event +*/ +package types + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type CreateContainerRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + BundlePath string `protobuf:"bytes,2,opt,name=bundlePath" json:"bundlePath,omitempty"` + Stdout string `protobuf:"bytes,4,opt,name=stdout" json:"stdout,omitempty"` + Stderr string `protobuf:"bytes,5,opt,name=stderr" json:"stderr,omitempty"` + Checkpoint string `protobuf:"bytes,7,opt,name=checkpoint" json:"checkpoint,omitempty"` +} + +func (m *CreateContainerRequest) Reset() { *m = CreateContainerRequest{} } +func (m *CreateContainerRequest) String() string { return proto.CompactTextString(m) } +func (*CreateContainerRequest) ProtoMessage() {} +func (*CreateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +type CreateContainerResponse struct { +} + +func (m *CreateContainerResponse) Reset() { *m = CreateContainerResponse{} } +func (m *CreateContainerResponse) String() string { return proto.CompactTextString(m) } +func (*CreateContainerResponse) ProtoMessage() {} +func (*CreateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +type SignalRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Pid uint32 `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"` + Signal uint32 `protobuf:"varint,3,opt,name=signal" json:"signal,omitempty"` +} + +func (m *SignalRequest) Reset() { *m = SignalRequest{} } +func (m *SignalRequest) String() string { return proto.CompactTextString(m) } +func (*SignalRequest) ProtoMessage() {} +func (*SignalRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +type SignalResponse struct { +} + +func (m *SignalResponse) Reset() { *m = SignalResponse{} } +func (m *SignalResponse) String() string { return proto.CompactTextString(m) } +func (*SignalResponse) ProtoMessage() {} +func (*SignalResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +type AddProcessRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Terminal bool `protobuf:"varint,2,opt,name=terminal" json:"terminal,omitempty"` + User *User `protobuf:"bytes,3,opt,name=user" json:"user,omitempty"` + Args []string `protobuf:"bytes,4,rep,name=args" json:"args,omitempty"` + Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` + Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"` +} + +func (m *AddProcessRequest) Reset() { *m = AddProcessRequest{} } +func (m *AddProcessRequest) String() string { return proto.CompactTextString(m) } +func (*AddProcessRequest) ProtoMessage() {} +func (*AddProcessRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *AddProcessRequest) GetUser() *User { + if m != nil { + return m.User + } + return nil +} + +type User struct { + Uid uint32 `protobuf:"varint,1,opt,name=uid" json:"uid,omitempty"` + Gid uint32 `protobuf:"varint,2,opt,name=gid" json:"gid,omitempty"` + AdditionalGids []uint32 `protobuf:"varint,3,rep,name=additionalGids" json:"additionalGids,omitempty"` +} + +func (m *User) Reset() { *m = User{} } +func (m *User) String() string { return proto.CompactTextString(m) } +func (*User) ProtoMessage() {} +func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +type AddProcessResponse struct { + Pid uint32 `protobuf:"varint,1,opt,name=pid" json:"pid,omitempty"` +} + +func (m *AddProcessResponse) Reset() { *m = AddProcessResponse{} } +func (m *AddProcessResponse) String() string { return proto.CompactTextString(m) } +func (*AddProcessResponse) ProtoMessage() {} +func (*AddProcessResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +type CreateCheckpointRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Checkpoint *Checkpoint `protobuf:"bytes,2,opt,name=checkpoint" json:"checkpoint,omitempty"` +} + +func (m *CreateCheckpointRequest) Reset() { *m = CreateCheckpointRequest{} } +func (m *CreateCheckpointRequest) String() string { return proto.CompactTextString(m) } +func (*CreateCheckpointRequest) ProtoMessage() {} +func (*CreateCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *CreateCheckpointRequest) GetCheckpoint() *Checkpoint { + if m != nil { + return m.Checkpoint + } + return nil +} + +type CreateCheckpointResponse struct { +} + +func (m *CreateCheckpointResponse) Reset() { *m = CreateCheckpointResponse{} } +func (m *CreateCheckpointResponse) String() string { return proto.CompactTextString(m) } +func (*CreateCheckpointResponse) ProtoMessage() {} +func (*CreateCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +type DeleteCheckpointRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` +} + +func (m *DeleteCheckpointRequest) Reset() { *m = DeleteCheckpointRequest{} } +func (m *DeleteCheckpointRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteCheckpointRequest) ProtoMessage() {} +func (*DeleteCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +type DeleteCheckpointResponse struct { +} + +func (m *DeleteCheckpointResponse) Reset() { *m = DeleteCheckpointResponse{} } +func (m *DeleteCheckpointResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteCheckpointResponse) ProtoMessage() {} +func (*DeleteCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +type ListCheckpointRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` +} + +func (m *ListCheckpointRequest) Reset() { *m = ListCheckpointRequest{} } +func (m *ListCheckpointRequest) String() string { return proto.CompactTextString(m) } +func (*ListCheckpointRequest) ProtoMessage() {} +func (*ListCheckpointRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +type Checkpoint struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Exit bool `protobuf:"varint,2,opt,name=exit" json:"exit,omitempty"` + Tcp bool `protobuf:"varint,3,opt,name=tcp" json:"tcp,omitempty"` + UnixSockets bool `protobuf:"varint,4,opt,name=unixSockets" json:"unixSockets,omitempty"` + Shell bool `protobuf:"varint,5,opt,name=shell" json:"shell,omitempty"` +} + +func (m *Checkpoint) Reset() { *m = Checkpoint{} } +func (m *Checkpoint) String() string { return proto.CompactTextString(m) } +func (*Checkpoint) ProtoMessage() {} +func (*Checkpoint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +type ListCheckpointResponse struct { + Checkpoints []*Checkpoint `protobuf:"bytes,1,rep,name=checkpoints" json:"checkpoints,omitempty"` +} + +func (m *ListCheckpointResponse) Reset() { *m = ListCheckpointResponse{} } +func (m *ListCheckpointResponse) String() string { return proto.CompactTextString(m) } +func (*ListCheckpointResponse) ProtoMessage() {} +func (*ListCheckpointResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +func (m *ListCheckpointResponse) GetCheckpoints() []*Checkpoint { + if m != nil { + return m.Checkpoints + } + return nil +} + +type StateRequest struct { +} + +func (m *StateRequest) Reset() { *m = StateRequest{} } +func (m *StateRequest) String() string { return proto.CompactTextString(m) } +func (*StateRequest) ProtoMessage() {} +func (*StateRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +type ContainerState struct { + Status string `protobuf:"bytes,1,opt,name=status" json:"status,omitempty"` +} + +func (m *ContainerState) Reset() { *m = ContainerState{} } +func (m *ContainerState) String() string { return proto.CompactTextString(m) } +func (*ContainerState) ProtoMessage() {} +func (*ContainerState) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +type Process struct { + Pid uint32 `protobuf:"varint,1,opt,name=pid" json:"pid,omitempty"` + Terminal bool `protobuf:"varint,2,opt,name=terminal" json:"terminal,omitempty"` + User *User `protobuf:"bytes,3,opt,name=user" json:"user,omitempty"` + Args []string `protobuf:"bytes,4,rep,name=args" json:"args,omitempty"` + Env []string `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"` + Cwd string `protobuf:"bytes,6,opt,name=cwd" json:"cwd,omitempty"` +} + +func (m *Process) Reset() { *m = Process{} } +func (m *Process) String() string { return proto.CompactTextString(m) } +func (*Process) ProtoMessage() {} +func (*Process) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +func (m *Process) GetUser() *User { + if m != nil { + return m.User + } + return nil +} + +type Container struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + BundlePath string `protobuf:"bytes,3,opt,name=bundlePath" json:"bundlePath,omitempty"` + Processes []*Process `protobuf:"bytes,4,rep,name=processes" json:"processes,omitempty"` + Status string `protobuf:"bytes,5,opt,name=status" json:"status,omitempty"` +} + +func (m *Container) Reset() { *m = Container{} } +func (m *Container) String() string { return proto.CompactTextString(m) } +func (*Container) ProtoMessage() {} +func (*Container) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *Container) GetProcesses() []*Process { + if m != nil { + return m.Processes + } + return nil +} + +type Machine struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Cpus uint32 `protobuf:"varint,2,opt,name=cpus" json:"cpus,omitempty"` + Memory uint64 `protobuf:"varint,3,opt,name=memory" json:"memory,omitempty"` +} + +func (m *Machine) Reset() { *m = Machine{} } +func (m *Machine) String() string { return proto.CompactTextString(m) } +func (*Machine) ProtoMessage() {} +func (*Machine) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } + +type StateResponse struct { + Containers []*Container `protobuf:"bytes,1,rep,name=containers" json:"containers,omitempty"` + Machine *Machine `protobuf:"bytes,2,opt,name=machine" json:"machine,omitempty"` +} + +func (m *StateResponse) Reset() { *m = StateResponse{} } +func (m *StateResponse) String() string { return proto.CompactTextString(m) } +func (*StateResponse) ProtoMessage() {} +func (*StateResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } + +func (m *StateResponse) GetContainers() []*Container { + if m != nil { + return m.Containers + } + return nil +} + +func (m *StateResponse) GetMachine() *Machine { + if m != nil { + return m.Machine + } + return nil +} + +type UpdateContainerRequest struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Signal uint32 `protobuf:"varint,2,opt,name=signal" json:"signal,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status" json:"status,omitempty"` +} + +func (m *UpdateContainerRequest) Reset() { *m = UpdateContainerRequest{} } +func (m *UpdateContainerRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateContainerRequest) ProtoMessage() {} +func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } + +type UpdateContainerResponse struct { +} + +func (m *UpdateContainerResponse) Reset() { *m = UpdateContainerResponse{} } +func (m *UpdateContainerResponse) String() string { return proto.CompactTextString(m) } +func (*UpdateContainerResponse) ProtoMessage() {} +func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } + +type EventsRequest struct { +} + +func (m *EventsRequest) Reset() { *m = EventsRequest{} } +func (m *EventsRequest) String() string { return proto.CompactTextString(m) } +func (*EventsRequest) ProtoMessage() {} +func (*EventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } + +type Event struct { + Type string `protobuf:"bytes,1,opt,name=type" json:"type,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` + Status uint32 `protobuf:"varint,3,opt,name=status" json:"status,omitempty"` + BundlePath string `protobuf:"bytes,4,opt,name=bundlePath" json:"bundlePath,omitempty"` + Pid uint32 `protobuf:"varint,5,opt,name=pid" json:"pid,omitempty"` + Signal uint32 `protobuf:"varint,7,opt,name=signal" json:"signal,omitempty"` + Process *Process `protobuf:"bytes,8,opt,name=process" json:"process,omitempty"` + Containers []*Container `protobuf:"bytes,9,rep,name=containers" json:"containers,omitempty"` + Checkpoint *Checkpoint `protobuf:"bytes,10,opt,name=checkpoint" json:"checkpoint,omitempty"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *Event) GetProcess() *Process { + if m != nil { + return m.Process + } + return nil +} + +func (m *Event) GetContainers() []*Container { + if m != nil { + return m.Containers + } + return nil +} + +func (m *Event) GetCheckpoint() *Checkpoint { + if m != nil { + return m.Checkpoint + } + return nil +} + +func init() { + proto.RegisterType((*CreateContainerRequest)(nil), "types.CreateContainerRequest") + proto.RegisterType((*CreateContainerResponse)(nil), "types.CreateContainerResponse") + proto.RegisterType((*SignalRequest)(nil), "types.SignalRequest") + proto.RegisterType((*SignalResponse)(nil), "types.SignalResponse") + proto.RegisterType((*AddProcessRequest)(nil), "types.AddProcessRequest") + proto.RegisterType((*User)(nil), "types.User") + proto.RegisterType((*AddProcessResponse)(nil), "types.AddProcessResponse") + proto.RegisterType((*CreateCheckpointRequest)(nil), "types.CreateCheckpointRequest") + proto.RegisterType((*CreateCheckpointResponse)(nil), "types.CreateCheckpointResponse") + proto.RegisterType((*DeleteCheckpointRequest)(nil), "types.DeleteCheckpointRequest") + proto.RegisterType((*DeleteCheckpointResponse)(nil), "types.DeleteCheckpointResponse") + proto.RegisterType((*ListCheckpointRequest)(nil), "types.ListCheckpointRequest") + proto.RegisterType((*Checkpoint)(nil), "types.Checkpoint") + proto.RegisterType((*ListCheckpointResponse)(nil), "types.ListCheckpointResponse") + proto.RegisterType((*StateRequest)(nil), "types.StateRequest") + proto.RegisterType((*ContainerState)(nil), "types.ContainerState") + proto.RegisterType((*Process)(nil), "types.Process") + proto.RegisterType((*Container)(nil), "types.Container") + proto.RegisterType((*Machine)(nil), "types.Machine") + proto.RegisterType((*StateResponse)(nil), "types.StateResponse") + proto.RegisterType((*UpdateContainerRequest)(nil), "types.UpdateContainerRequest") + proto.RegisterType((*UpdateContainerResponse)(nil), "types.UpdateContainerResponse") + proto.RegisterType((*EventsRequest)(nil), "types.EventsRequest") + proto.RegisterType((*Event)(nil), "types.Event") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// Client API for API service + +type APIClient interface { + CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) + UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) + Signal(ctx context.Context, in *SignalRequest, opts ...grpc.CallOption) (*SignalResponse, error) + AddProcess(ctx context.Context, in *AddProcessRequest, opts ...grpc.CallOption) (*AddProcessResponse, error) + CreateCheckpoint(ctx context.Context, in *CreateCheckpointRequest, opts ...grpc.CallOption) (*CreateCheckpointResponse, error) + DeleteCheckpoint(ctx context.Context, in *DeleteCheckpointRequest, opts ...grpc.CallOption) (*DeleteCheckpointResponse, error) + ListCheckpoint(ctx context.Context, in *ListCheckpointRequest, opts ...grpc.CallOption) (*ListCheckpointResponse, error) + State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error) + Events(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (API_EventsClient, error) +} + +type aPIClient struct { + cc *grpc.ClientConn +} + +func NewAPIClient(cc *grpc.ClientConn) APIClient { + return &aPIClient{cc} +} + +func (c *aPIClient) CreateContainer(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) { + out := new(CreateContainerResponse) + err := grpc.Invoke(ctx, "/types.API/CreateContainer", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) { + out := new(UpdateContainerResponse) + err := grpc.Invoke(ctx, "/types.API/UpdateContainer", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) Signal(ctx context.Context, in *SignalRequest, opts ...grpc.CallOption) (*SignalResponse, error) { + out := new(SignalResponse) + err := grpc.Invoke(ctx, "/types.API/Signal", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) AddProcess(ctx context.Context, in *AddProcessRequest, opts ...grpc.CallOption) (*AddProcessResponse, error) { + out := new(AddProcessResponse) + err := grpc.Invoke(ctx, "/types.API/AddProcess", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) CreateCheckpoint(ctx context.Context, in *CreateCheckpointRequest, opts ...grpc.CallOption) (*CreateCheckpointResponse, error) { + out := new(CreateCheckpointResponse) + err := grpc.Invoke(ctx, "/types.API/CreateCheckpoint", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) DeleteCheckpoint(ctx context.Context, in *DeleteCheckpointRequest, opts ...grpc.CallOption) (*DeleteCheckpointResponse, error) { + out := new(DeleteCheckpointResponse) + err := grpc.Invoke(ctx, "/types.API/DeleteCheckpoint", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) ListCheckpoint(ctx context.Context, in *ListCheckpointRequest, opts ...grpc.CallOption) (*ListCheckpointResponse, error) { + out := new(ListCheckpointResponse) + err := grpc.Invoke(ctx, "/types.API/ListCheckpoint", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) State(ctx context.Context, in *StateRequest, opts ...grpc.CallOption) (*StateResponse, error) { + out := new(StateResponse) + err := grpc.Invoke(ctx, "/types.API/State", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *aPIClient) Events(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (API_EventsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_API_serviceDesc.Streams[0], c.cc, "/types.API/Events", opts...) + if err != nil { + return nil, err + } + x := &aPIEventsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type API_EventsClient interface { + Recv() (*Event, error) + grpc.ClientStream +} + +type aPIEventsClient struct { + grpc.ClientStream +} + +func (x *aPIEventsClient) Recv() (*Event, error) { + m := new(Event) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// Server API for API service + +type APIServer interface { + CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) + UpdateContainer(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) + Signal(context.Context, *SignalRequest) (*SignalResponse, error) + AddProcess(context.Context, *AddProcessRequest) (*AddProcessResponse, error) + CreateCheckpoint(context.Context, *CreateCheckpointRequest) (*CreateCheckpointResponse, error) + DeleteCheckpoint(context.Context, *DeleteCheckpointRequest) (*DeleteCheckpointResponse, error) + ListCheckpoint(context.Context, *ListCheckpointRequest) (*ListCheckpointResponse, error) + State(context.Context, *StateRequest) (*StateResponse, error) + Events(*EventsRequest, API_EventsServer) error +} + +func RegisterAPIServer(s *grpc.Server, srv APIServer) { + s.RegisterService(&_API_serviceDesc, srv) +} + +func _API_CreateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(CreateContainerRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).CreateContainer(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_UpdateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(UpdateContainerRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).UpdateContainer(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_Signal_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(SignalRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).Signal(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_AddProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(AddProcessRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).AddProcess(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_CreateCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(CreateCheckpointRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).CreateCheckpoint(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_DeleteCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(DeleteCheckpointRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).DeleteCheckpoint(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_ListCheckpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(ListCheckpointRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).ListCheckpoint(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_State_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(StateRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(APIServer).State(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _API_Events_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(EventsRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(APIServer).Events(m, &aPIEventsServer{stream}) +} + +type API_EventsServer interface { + Send(*Event) error + grpc.ServerStream +} + +type aPIEventsServer struct { + grpc.ServerStream +} + +func (x *aPIEventsServer) Send(m *Event) error { + return x.ServerStream.SendMsg(m) +} + +var _API_serviceDesc = grpc.ServiceDesc{ + ServiceName: "types.API", + HandlerType: (*APIServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateContainer", + Handler: _API_CreateContainer_Handler, + }, + { + MethodName: "UpdateContainer", + Handler: _API_UpdateContainer_Handler, + }, + { + MethodName: "Signal", + Handler: _API_Signal_Handler, + }, + { + MethodName: "AddProcess", + Handler: _API_AddProcess_Handler, + }, + { + MethodName: "CreateCheckpoint", + Handler: _API_CreateCheckpoint_Handler, + }, + { + MethodName: "DeleteCheckpoint", + Handler: _API_DeleteCheckpoint_Handler, + }, + { + MethodName: "ListCheckpoint", + Handler: _API_ListCheckpoint_Handler, + }, + { + MethodName: "State", + Handler: _API_State_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Events", + Handler: _API_Events_Handler, + ServerStreams: true, + }, + }, +} + +var fileDescriptor0 = []byte{ + // 773 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x56, 0x5d, 0x4f, 0xdc, 0x3a, + 0x10, 0xdd, 0x25, 0x9b, 0xfd, 0x98, 0x65, 0xc3, 0x62, 0x60, 0x09, 0xd1, 0xe5, 0x02, 0xb9, 0xb7, + 0x55, 0x9f, 0x10, 0x82, 0x4a, 0xe5, 0xb1, 0x08, 0xaa, 0xaa, 0x12, 0x55, 0x11, 0x88, 0x4a, 0x7d, + 0x0c, 0x89, 0xc5, 0x46, 0x64, 0x93, 0x34, 0x76, 0x28, 0xfc, 0x8d, 0xfe, 0xb2, 0xfe, 0xa4, 0x3a, + 0x8e, 0xed, 0x7c, 0x6c, 0x52, 0x9e, 0xfa, 0xe8, 0xb1, 0x7d, 0xce, 0xcc, 0x99, 0xf1, 0x49, 0x60, + 0xe4, 0xc4, 0xfe, 0x61, 0x9c, 0x44, 0x34, 0x42, 0x3a, 0x7d, 0x8e, 0x31, 0xb1, 0x03, 0x98, 0x9d, + 0x27, 0xd8, 0xa1, 0xf8, 0x3c, 0x0a, 0xa9, 0xe3, 0x87, 0x38, 0xb9, 0xc6, 0xdf, 0x53, 0x4c, 0x28, + 0x02, 0x58, 0xf1, 0x3d, 0xb3, 0xbb, 0xdf, 0x7d, 0x33, 0x42, 0x6c, 0x71, 0x97, 0x86, 0x5e, 0x80, + 0xaf, 0x1c, 0x3a, 0x37, 0x57, 0x78, 0xcc, 0x80, 0x3e, 0xa1, 0x5e, 0x94, 0x52, 0xb3, 0x57, 0x5a, + 0xe3, 0x24, 0x31, 0x75, 0x79, 0xc7, 0x9d, 0x63, 0xf7, 0x21, 0x8e, 0xfc, 0x90, 0x9a, 0x83, 0x2c, + 0x66, 0xef, 0xc0, 0xf6, 0x12, 0x1b, 0x89, 0xa3, 0x90, 0x60, 0xfb, 0x14, 0x26, 0x37, 0xfe, 0x7d, + 0xe8, 0x04, 0x4d, 0xfc, 0x63, 0xd0, 0x62, 0xb6, 0xc8, 0x88, 0x27, 0x9c, 0x88, 0x9f, 0x34, 0xb5, + 0x6c, 0x6d, 0x4f, 0xc1, 0x90, 0x37, 0x05, 0x16, 0x85, 0xf5, 0x33, 0xcf, 0xbb, 0x4a, 0x22, 0x17, + 0x13, 0xd2, 0x84, 0x37, 0x85, 0x21, 0xc5, 0xc9, 0xc2, 0xcf, 0x40, 0x32, 0xd0, 0x21, 0xda, 0x81, + 0x5e, 0x4a, 0x70, 0xc2, 0x21, 0xc7, 0xc7, 0xe3, 0x43, 0xae, 0xce, 0xe1, 0x2d, 0x0b, 0xa1, 0x55, + 0xe8, 0x39, 0xc9, 0x3d, 0x61, 0x65, 0x6a, 0x79, 0x2a, 0x38, 0x7c, 0x64, 0x35, 0x8a, 0x85, 0xfb, + 0xc3, 0x33, 0xfb, 0xbc, 0xb8, 0x53, 0xe8, 0xf1, 0xf3, 0x2c, 0x98, 0x0a, 0xa6, 0x49, 0xb6, 0xb8, + 0x57, 0x99, 0xcf, 0xc0, 0x70, 0x3c, 0xcf, 0xa7, 0x7e, 0xc4, 0x88, 0x3f, 0xfa, 0x1e, 0x61, 0x74, + 0x1a, 0xab, 0xe0, 0x00, 0x50, 0x39, 0xdf, 0xbc, 0x0a, 0x59, 0x34, 0xc7, 0xb1, 0x2f, 0x95, 0x72, + 0x4a, 0xd3, 0xa6, 0xc2, 0x5e, 0x55, 0x44, 0x5f, 0xe1, 0xc5, 0xac, 0x8b, 0x62, 0x8a, 0x9b, 0xb6, + 0x05, 0xe6, 0x32, 0x9a, 0x10, 0xef, 0x04, 0xb6, 0x2f, 0x70, 0x80, 0x5f, 0x62, 0x62, 0xaa, 0x84, + 0xce, 0x02, 0xe7, 0xc3, 0x90, 0x01, 0x2e, 0x5f, 0x12, 0x80, 0xff, 0xc1, 0xd6, 0xa5, 0x4f, 0xe8, + 0x1f, 0xe1, 0xec, 0x6f, 0x00, 0xc5, 0x01, 0x05, 0xae, 0xa8, 0xf0, 0x93, 0x4f, 0x45, 0xa7, 0x98, + 0x2c, 0xd4, 0x8d, 0x79, 0xa3, 0x86, 0x68, 0x03, 0xc6, 0x69, 0xe8, 0x3f, 0xdd, 0x44, 0xee, 0x03, + 0xa6, 0x84, 0x4f, 0xe2, 0x10, 0x4d, 0x40, 0x27, 0x73, 0x1c, 0x04, 0x7c, 0x10, 0x87, 0xf6, 0x7b, + 0x98, 0xd5, 0xf9, 0x85, 0xc2, 0xaf, 0x61, 0x5c, 0xa8, 0x45, 0x18, 0x9b, 0xd6, 0x2c, 0x97, 0x01, + 0xab, 0x37, 0x94, 0xa9, 0x25, 0x12, 0xb7, 0xf7, 0xc1, 0x50, 0x03, 0xcc, 0x37, 0xf2, 0xe1, 0x77, + 0x68, 0x4a, 0x44, 0x39, 0x0f, 0x30, 0x10, 0xed, 0xac, 0xb4, 0xf1, 0xef, 0x0c, 0x5e, 0x00, 0x23, + 0x95, 0x4e, 0x7b, 0x8f, 0x6a, 0x8f, 0x58, 0xe3, 0xb1, 0x03, 0x18, 0xc5, 0x79, 0x9e, 0x38, 0xe7, + 0x19, 0x1f, 0x1b, 0x22, 0x05, 0x99, 0x7f, 0x51, 0x1a, 0x7f, 0xd7, 0x6c, 0x3e, 0x06, 0x9f, 0x1d, + 0x77, 0xce, 0xc8, 0xea, 0x5c, 0x6e, 0xcc, 0x0e, 0xa9, 0x37, 0xba, 0xc0, 0x8b, 0x28, 0x79, 0xe6, + 0x3c, 0x3d, 0xfb, 0x2b, 0x7b, 0xdd, 0xb9, 0x82, 0x42, 0xfa, 0xff, 0xd9, 0xa0, 0xca, 0x9c, 0xa5, + 0xf2, 0x53, 0xa9, 0xbc, 0x2a, 0x66, 0x0f, 0x06, 0x8b, 0x9c, 0x4b, 0xcc, 0xb2, 0x4c, 0x4e, 0x64, + 0x60, 0x5f, 0xc0, 0xec, 0x36, 0xf6, 0x5e, 0xb2, 0xaf, 0xc2, 0x31, 0x0a, 0x07, 0xc9, 0x4b, 0xd2, + 0xa4, 0x2d, 0x2d, 0xa1, 0x88, 0xe1, 0x5d, 0x83, 0xc9, 0x87, 0x47, 0xcc, 0xa6, 0x43, 0xf6, 0xfe, + 0x57, 0x17, 0x74, 0x1e, 0xc9, 0x2a, 0xce, 0x92, 0x11, 0x1c, 0x39, 0x5f, 0xc9, 0x1a, 0x15, 0xfe, + 0xa4, 0xa6, 0x7c, 0xaf, 0x6c, 0x69, 0x7a, 0xcd, 0xd2, 0x06, 0x7c, 0xcd, 0xea, 0x16, 0x6d, 0x31, + 0x87, 0x95, 0xba, 0x65, 0x53, 0xaa, 0xf2, 0x8d, 0x5a, 0xe4, 0xab, 0xba, 0x01, 0xb4, 0xb8, 0xc1, + 0xf1, 0x4f, 0x1d, 0xb4, 0xb3, 0xab, 0x4f, 0xe8, 0x1a, 0xd6, 0x6a, 0xee, 0x8c, 0x76, 0xe5, 0xe9, + 0xc6, 0x6f, 0x84, 0xf5, 0x6f, 0xdb, 0xb6, 0x50, 0xaf, 0x93, 0x61, 0xd6, 0xa4, 0x55, 0x98, 0xcd, + 0x8d, 0x53, 0x98, 0x6d, 0x1d, 0xe9, 0xa0, 0x77, 0xd0, 0xcf, 0x0d, 0x1f, 0x6d, 0x8a, 0xb3, 0x95, + 0x2f, 0x87, 0xb5, 0x55, 0x8b, 0xaa, 0x8b, 0xe7, 0x00, 0x85, 0xcf, 0x22, 0x53, 0x1c, 0x5b, 0xfa, + 0x54, 0x58, 0x3b, 0x0d, 0x3b, 0x0a, 0xe4, 0x16, 0xa6, 0x75, 0xef, 0x44, 0x35, 0x1d, 0xea, 0x4e, + 0x67, 0xed, 0xb5, 0xee, 0x97, 0x61, 0xeb, 0x0e, 0xaa, 0x60, 0x5b, 0xfc, 0x58, 0xc1, 0xb6, 0x5a, + 0x6f, 0x07, 0x7d, 0x01, 0xa3, 0x6a, 0x7e, 0xe8, 0x1f, 0x71, 0xa9, 0xd1, 0x93, 0xad, 0xdd, 0x96, + 0x5d, 0x05, 0xf8, 0x16, 0xf4, 0xdc, 0xf2, 0x36, 0xa4, 0xca, 0x25, 0x67, 0xb4, 0x36, 0xab, 0x41, + 0x75, 0xeb, 0x08, 0xfa, 0xf9, 0x33, 0x52, 0x2d, 0xab, 0xbc, 0x2a, 0x6b, 0xb5, 0x1c, 0xb5, 0x3b, + 0x47, 0xdd, 0xbb, 0x3e, 0xff, 0x4d, 0x39, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x82, 0xb4, + 0x20, 0xb3, 0x08, 0x00, 0x00, +} diff --git a/api/grpc/types/api.proto b/api/grpc/types/api.proto new file mode 100644 index 000000000..c9a473465 --- /dev/null +++ b/api/grpc/types/api.proto @@ -0,0 +1,145 @@ +syntax = "proto3"; + +package types; + +service API { + rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {} + rpc UpdateContainer(UpdateContainerRequest) returns (UpdateContainerResponse) {} + rpc Signal(SignalRequest) returns (SignalResponse) {} + rpc AddProcess(AddProcessRequest) returns (AddProcessResponse) {} + rpc CreateCheckpoint(CreateCheckpointRequest) returns (CreateCheckpointResponse) {} + rpc DeleteCheckpoint(DeleteCheckpointRequest) returns (DeleteCheckpointResponse) {} + rpc ListCheckpoint(ListCheckpointRequest) returns (ListCheckpointResponse) {} + rpc State(StateRequest) returns (StateResponse) {} + rpc Events(EventsRequest) returns (stream Event) {} +} + +message CreateContainerRequest { + string id = 1; + string bundlePath = 2; + string stdout = 4; + string stderr = 5; + string checkpoint = 7; +} + +message CreateContainerResponse { +} + +message SignalRequest { + string id = 1; + uint32 pid = 2; + uint32 signal = 3; +} + +message SignalResponse { +} + +message AddProcessRequest { + string id = 1; + bool terminal = 2; + User user = 3; + repeated string args = 4; + repeated string env = 5; + string cwd = 6; +}; + +message User { + uint32 uid = 1; + uint32 gid = 2; + repeated uint32 additionalGids = 3; +} + +message AddProcessResponse { + uint32 pid = 1; +} + +message CreateCheckpointRequest { + string id = 1; + Checkpoint checkpoint = 2; +} + +message CreateCheckpointResponse { +} + +message DeleteCheckpointRequest { + string id = 1; + string name = 2; +} + +message DeleteCheckpointResponse { +} + +message ListCheckpointRequest { + string id = 1; +} + +message Checkpoint { + string name = 1; + bool exit = 2; + bool tcp = 3; + bool unixSockets = 4; + bool shell = 5; +} + +message ListCheckpointResponse { + repeated Checkpoint checkpoints = 1; +} + +message StateRequest { +} + +message ContainerState { + string status = 1; +} + +message Process { + uint32 pid = 1; + bool terminal = 2; + User user = 3; + repeated string args = 4; + repeated string env = 5; + string cwd = 6; +} + +message Container { + string id = 1; + string name = 2; + string bundlePath = 3; + repeated Process processes = 4; + string status = 5; +} + +message Machine { + string id = 1; + uint32 cpus = 2; + uint64 memory = 3; +} + +message StateResponse { + repeated Container containers = 1; + Machine machine = 2; +} + +message UpdateContainerRequest { + string id = 1; + uint32 signal = 2; + string status = 3; +} + +message UpdateContainerResponse { +} + +message EventsRequest { +} + +message Event { + string type = 1; + string id = 2; + uint32 status = 3; + string bundlePath = 4; + uint32 pid = 5; + uint32 signal = 7; + Process process = 8; + repeated Container containers = 9; + Checkpoint checkpoint = 10; +} diff --git a/containerd/main.go b/containerd/main.go index 88a5bc8e8..48b467186 100644 --- a/containerd/main.go +++ b/containerd/main.go @@ -2,15 +2,21 @@ package main import ( "log" + "net" "net/http" "os" "runtime" "sync" "time" + "google.golang.org/grpc" + "google.golang.org/grpc/grpclog" + "github.com/Sirupsen/logrus" "github.com/codegangsta/cli" "github.com/docker/containerd" + "github.com/docker/containerd/api/grpc/server" + "github.com/docker/containerd/api/grpc/types" "github.com/docker/containerd/api/v1" "github.com/rcrowley/go-metrics" ) @@ -115,6 +121,16 @@ func daemon(id, stateDir string, concurrency, bufferSize int) error { if err := supervisor.Start(); err != nil { return err } + if os.Getenv("GRPC") != "" { + lis, err := net.Listen("tcp", ":8888") + if err != nil { + grpclog.Fatalf("failed to listen: %v", err) + } + grpcServer := grpc.NewServer() + types.RegisterAPIServer(grpcServer, server.NewServer(supervisor)) + return grpcServer.Serve(lis) + + } server := v1.NewServer(supervisor) return http.ListenAndServe("localhost:8888", server) }