Start work on execution server implementation

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-12-02 11:33:58 -08:00
parent d0e2f3778a
commit 6641888667
31 changed files with 125 additions and 26 deletions

View file

@ -38,3 +38,5 @@ message ListContainersRequest {
message ListContainersResponse { message ListContainersResponse {
repeated Container containers = 1; repeated Container containers = 1;
} }

View file

@ -13,6 +13,8 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/containerd" "github.com/docker/containerd"
api "github.com/docker/containerd/api/execution"
"github.com/docker/containerd/services/execution"
metrics "github.com/docker/go-metrics" metrics "github.com/docker/go-metrics"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -35,6 +37,16 @@ high performance container runtime
Name: "debug", Name: "debug",
Usage: "enable debug output in logs", Usage: "enable debug output in logs",
}, },
cli.StringFlag{
Name: "root",
Usage: "containerd state directory",
Value: "/run/containerd",
},
cli.StringFlag{
Name: "runtime",
Usage: "default runtime for execution",
Value: "runc",
},
cli.StringFlag{ cli.StringFlag{
Name: "socket, s", Name: "socket, s",
Usage: "socket path for containerd's GRPC server", Usage: "socket path for containerd's GRPC server",
@ -69,7 +81,17 @@ high performance container runtime
return err return err
} }
execService, err := execution.New(execution.Opts{
Root: context.GlobalString("root"),
Runtime: context.GlobalString("runtime"),
})
if err != nil {
return err
}
server := grpc.NewServer() server := grpc.NewServer()
api.RegisterExecutionServiceServer(server, execService)
api.RegisterContainerServiceServer(server, execService)
go serveGRPC(server, l) go serveGRPC(server, l)
for s := range signals { for s := range signals {

View file

@ -1,13 +0,0 @@
package containerd
import "errors"
var ErrProcessSet = errors.New("container process is already set")
type Runtime interface {
Create(*Container) (ProcessDelegate, error)
Start(*Container) error
Delete(*Container) error
Exec(*Container, *Process) (ProcessDelegate, error)
Load(id string) (ProcessDelegate, error)
}

15
executor.go Normal file
View file

@ -0,0 +1,15 @@
package containerd
import "errors"
var ErrProcessSet = errors.New("container process is already set")
type Executor interface {
List() ([]*Container, error)
Load(id string) (*Container, error)
Create(CreateOpts) (*Container, error)
Start(string) error
Delete(string) error
Exec(string, *Process) (ProcessDelegate, error)
}

13
executors/executors.go Normal file
View file

@ -0,0 +1,13 @@
package executors
import "github.com/docker/containerd"
var executors = make(map[string]func() containerd.Executor)
func Register(name string, e func() containerd.Executor) {
executors[name] = e
}
func Get(name string) func() containerd.Executor {
return executors[name]
}

View file

@ -5,35 +5,28 @@ import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv" "strconv"
"time" "time"
"github.com/docker/containerd" "github.com/docker/containerd"
"github.com/docker/containerd/executors"
) )
var ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string") var ErrRootEmpty = errors.New("oci: runtime root cannot be an empty string")
type Opts struct { func init() {
Name string executors.Register("oci", New)
Root string executors.Register("runc", New)
Args []string
} }
func New(opts Opts) (*OCIRuntime, error) { func New() *OCIRuntime {
if opts.Root == "" {
return nil, ErrRootEmpty
}
if err := os.MkdirAll(opts.Root, 0711); err != nil {
return nil, err
}
return &OCIRuntime{ return &OCIRuntime{
root: opts.Root, root: opts.Root,
name: opts.Name, name: opts.Name,
args: opts.Args, args: opts.Args,
}, nil }
} }
type OCIRuntime struct { type OCIRuntime struct {

View file

@ -0,0 +1,67 @@
package execution
import (
"context"
"github.com/docker/containerd"
api "github.com/docker/containerd/api/execution"
"github.com/docker/containerd/executors"
)
type Opts struct {
Root string
Runtime string
}
func New(o Opts) (*Service, error) {
executor, err := executors.Get(o.Runtime)(o.Root)
if err != nil {
return nil, err
}
return &Service{
o: o,
executor: executor,
}, nil
}
type Service struct {
o Opts
executor containerd.Executor
}
func (s *Service) Create(ctx context.Context, r *api.CreateContainerRequest) (*api.CreateContainerResponse, error) {
// TODO: write io and bundle path to dir
container, err := s.executor.Create(r.ID, r.BundlePath, &IO{})
if err != nil {
return nil, err
}
s.supervisor.Add(container.Process())
return &api.CreateContainerResponse{
Container: toGRPCContainer(container),
}, nil
}
func (s *Service) Delete(ctx context.Context, r *api.DeleteContainerRequest) (*api.Empty, error) {
if err := s.executor.Delete(r.ID); err != nil {
return nil, err
}
return nil, nil
}
func (s *Service) List(ctx context.Context, r *api.ListContainerRequest) (*api.ListContainerResponse, error) {
containers, err := s.executor.List()
if err != nil {
return nil, err
}
for _, c := range containers {
r.Containers = append(r.Containers, toGRPCContainer(c))
}
return r, nil
}
var (
_ = (api.ExecutionServiceServer)(&Service{})
_ = (api.ContainerServiceServer)(&Service{})
)