From d4ca79c978a3da4f833b8fe25af6f4a569ddee47 Mon Sep 17 00:00:00 2001 From: John Howard Date: Mon, 29 Feb 2016 10:48:39 -0800 Subject: [PATCH] Getting ctr closer to compiling on Windows Signed-off-by: John Howard --- api/grpc/server/server.go | 3 ++- api/grpc/server/server_linux.go | 9 ++++---- api/grpc/server/server_windows.go | 6 +++--- ctr/container.go | 22 +------------------- ctr/container_unix.go | 30 +++++++++++++++++++++++++++ ctr/container_windows.go | 6 ++++++ runtime/container.go | 20 ++++-------------- runtime/container_linux.go | 27 +++++++++++++++++------- runtime/container_windows.go | 15 +++++++++++--- runtime/process.go | 12 ++++++----- runtime/runtime.go | 4 +++- runtime/spec_linux.go | 8 ------- runtime/spec_windows.go | 8 ------- specs/spec_linux.go | 9 ++++++++ specs/{windows.go => spec_windows.go} | 8 +++++++ specs/unsupported.go | 3 --- supervisor/add_process.go | 3 ++- supervisor/sort_test.go | 5 +++-- 18 files changed, 115 insertions(+), 83 deletions(-) create mode 100644 ctr/container_unix.go create mode 100644 ctr/container_windows.go delete mode 100644 runtime/spec_linux.go delete mode 100644 runtime/spec_windows.go create mode 100644 specs/spec_linux.go rename specs/{windows.go => spec_windows.go} (91%) delete mode 100644 specs/unsupported.go diff --git a/api/grpc/server/server.go b/api/grpc/server/server.go index 25d807c..fb72324 100644 --- a/api/grpc/server/server.go +++ b/api/grpc/server/server.go @@ -11,6 +11,7 @@ import ( "github.com/docker/containerd/api/grpc/types" "github.com/docker/containerd/runtime" + "github.com/docker/containerd/specs" "github.com/docker/containerd/supervisor" "golang.org/x/net/context" ) @@ -66,7 +67,7 @@ func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types. } func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) { - process := &runtime.ProcessSpec{ + process := &specs.ProcessSpec{ Terminal: r.Terminal, Args: r.Args, Env: r.Env, diff --git a/api/grpc/server/server_linux.go b/api/grpc/server/server_linux.go index 4700adb..087d2e9 100644 --- a/api/grpc/server/server_linux.go +++ b/api/grpc/server/server_linux.go @@ -10,11 +10,12 @@ import ( "github.com/docker/containerd/api/grpc/types" "github.com/docker/containerd/runtime" + "github.com/docker/containerd/specs" "github.com/docker/containerd/supervisor" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/system" - "github.com/opencontainers/specs" + ocs "github.com/opencontainers/specs" "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -241,7 +242,7 @@ func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.St return t, nil } -func setUserFieldsInProcess(p *types.Process, oldProc runtime.ProcessSpec) { +func setUserFieldsInProcess(p *types.Process, oldProc specs.ProcessSpec) { p.User = &types.User{ Uid: oldProc.User.UID, Gid: oldProc.User.GID, @@ -249,8 +250,8 @@ func setUserFieldsInProcess(p *types.Process, oldProc runtime.ProcessSpec) { } } -func setPlatformRuntimeProcessSpecUserFields(r *types.User, process *runtime.ProcessSpec) { - process.User = specs.User{ +func setPlatformRuntimeProcessSpecUserFields(r *types.User, process *specs.ProcessSpec) { + process.User = ocs.User{ UID: r.Uid, GID: r.Gid, AdditionalGids: r.AdditionalGids, diff --git a/api/grpc/server/server_windows.go b/api/grpc/server/server_windows.go index c4d950e..96b34e7 100644 --- a/api/grpc/server/server_windows.go +++ b/api/grpc/server/server_windows.go @@ -4,7 +4,7 @@ import ( "errors" "github.com/docker/containerd/api/grpc/types" - "github.com/docker/containerd/runtime" + "github.com/docker/containerd/specs" "github.com/docker/containerd/supervisor" "golang.org/x/net/context" ) @@ -32,8 +32,8 @@ func (s *apiServer) Stats(ctx context.Context, r *types.StatsRequest) (*types.St return nil, errors.New("Stats() not supported on Windows") } -func setUserFieldsInProcess(p *types.Process, oldProc runtime.ProcessSpec) { +func setUserFieldsInProcess(p *types.Process, oldProc specs.ProcessSpec) { } -func setPlatformRuntimeProcessSpecUserFields(r *types.User, process *runtime.ProcessSpec) { +func setPlatformRuntimeProcessSpecUserFields(r *types.User, process *specs.ProcessSpec) { } diff --git a/ctr/container.go b/ctr/container.go index 6753c97..4af28eb 100644 --- a/ctr/container.go +++ b/ctr/container.go @@ -17,8 +17,8 @@ import ( "github.com/codegangsta/cli" "github.com/docker/containerd/api/grpc/types" + "github.com/docker/containerd/specs" "github.com/docker/docker/pkg/term" - "github.com/opencontainers/specs" netcontext "golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/grpclog" @@ -538,23 +538,3 @@ type stdio struct { stdout string stderr string } - -func createStdio() (s stdio, err error) { - tmp, err := ioutil.TempDir("", "ctr-") - if err != nil { - return s, err - } - // create fifo's for the process - for name, fd := range map[string]*string{ - "stdin": &s.stdin, - "stdout": &s.stdout, - "stderr": &s.stderr, - } { - path := filepath.Join(tmp, name) - if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { - return s, err - } - *fd = path - } - return s, nil -} diff --git a/ctr/container_unix.go b/ctr/container_unix.go new file mode 100644 index 0000000..bd31ecc --- /dev/null +++ b/ctr/container_unix.go @@ -0,0 +1,30 @@ +// +build !windows + +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "syscall" +) + +func createStdio() (s stdio, err error) { + tmp, err := ioutil.TempDir("", "ctr-") + if err != nil { + return s, err + } + // create fifo's for the process + for name, fd := range map[string]*string{ + "stdin": &s.stdin, + "stdout": &s.stdout, + "stderr": &s.stderr, + } { + path := filepath.Join(tmp, name) + if err := syscall.Mkfifo(path, 0755); err != nil && !os.IsExist(err) { + return s, err + } + *fd = path + } + return s, nil +} diff --git a/ctr/container_windows.go b/ctr/container_windows.go new file mode 100644 index 0000000..9348b3f --- /dev/null +++ b/ctr/container_windows.go @@ -0,0 +1,6 @@ +package main + +// TODO Windows: This will have a very different implementation +func createStdio() (s stdio, err error) { + return stdio{}, nil +} diff --git a/runtime/container.go b/runtime/container.go index 93a0f90..f43ed56 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -5,9 +5,9 @@ import ( "io/ioutil" "os" "path/filepath" - "syscall" "github.com/Sirupsen/logrus" + "github.com/docker/containerd/specs" ) type Container interface { @@ -18,7 +18,7 @@ type Container interface { // Start starts the init process of the container Start(checkpoint string, s Stdio) (Process, error) // Exec starts another process in an existing container - Exec(string, ProcessSpec, Stdio) (Process, error) + Exec(string, specs.ProcessSpec, Stdio) (Process, error) // Delete removes the container's state and any resources Delete() error // Processes returns all the containers processes that have been added @@ -175,8 +175,8 @@ func (c *container) Labels() []string { return c.labels } -func (c *container) readSpec() (*PlatformSpec, error) { - var spec PlatformSpec +func (c *container) readSpec() (*specs.PlatformSpec, error) { + var spec specs.PlatformSpec f, err := os.Open(filepath.Join(c.bundle, "config.json")) if err != nil { return nil, err @@ -188,18 +188,6 @@ func (c *container) readSpec() (*PlatformSpec, error) { return &spec, nil } -func (c *container) State() State { - proc := c.processes["init"] - if proc == nil || proc.pid == 0 { - return Stopped - } - err := syscall.Kill(proc.pid, 0) - if err != nil && err == syscall.ESRCH { - return Stopped - } - return Running -} - func (c *container) Delete() error { return os.RemoveAll(filepath.Join(c.root, c.id)) } diff --git a/runtime/container_linux.go b/runtime/container_linux.go index 6f6a501..ae660f8 100644 --- a/runtime/container_linux.go +++ b/runtime/container_linux.go @@ -9,17 +9,18 @@ import ( "syscall" "time" + "github.com/docker/containerd/specs" "github.com/opencontainers/runc/libcontainer" - "github.com/opencontainers/specs" + ocs "github.com/opencontainers/specs" ) -func getRootIDs(s *PlatformSpec) (int, int, error) { +func getRootIDs(s *specs.PlatformSpec) (int, int, error) { if s == nil { return 0, 0, nil } var hasUserns bool for _, ns := range s.Linux.Namespaces { - if ns.Type == specs.UserNamespace { + if ns.Type == ocs.UserNamespace { hasUserns = true break } @@ -32,6 +33,18 @@ func getRootIDs(s *PlatformSpec) (int, int, error) { return uid, gid, nil } +func (c *container) State() State { + proc := c.processes["init"] + if proc == nil || proc.pid == 0 { + return Stopped + } + err := syscall.Kill(proc.pid, 0) + if err != nil && err == syscall.ESRCH { + return Stopped + } + return Running +} + func (c *container) Runtime() string { return c.runtime } @@ -136,7 +149,7 @@ func (c *container) Start(checkpoint string, s Stdio) (Process, error) { c: c, stdio: s, spec: spec, - processSpec: ProcessSpec(spec.Process), + processSpec: specs.ProcessSpec(spec.Process), } p, err := newProcess(config) if err != nil { @@ -152,7 +165,7 @@ func (c *container) Start(checkpoint string, s Stdio) (Process, error) { return p, nil } -func (c *container) Exec(pid string, spec ProcessSpec, s Stdio) (Process, error) { +func (c *container) Exec(pid string, spec specs.ProcessSpec, s Stdio) (Process, error) { processRoot := filepath.Join(c.root, c.id, pid) if err := os.Mkdir(processRoot, 0755); err != nil { return nil, err @@ -187,14 +200,14 @@ func (c *container) Exec(pid string, spec ProcessSpec, s Stdio) (Process, error) } func (c *container) getLibctContainer() (libcontainer.Container, error) { - f, err := libcontainer.New(specs.LinuxStateDirectory, libcontainer.Cgroupfs) + f, err := libcontainer.New(ocs.LinuxStateDirectory, libcontainer.Cgroupfs) if err != nil { return nil, err } return f.Load(c.id) } -func hostIDFromMap(id uint32, mp []specs.IDMapping) int { +func hostIDFromMap(id uint32, mp []ocs.IDMapping) int { for _, m := range mp { if (id >= m.ContainerID) && (id <= (m.ContainerID + m.Size - 1)) { return int(m.HostID + (id - m.ContainerID)) diff --git a/runtime/container_windows.go b/runtime/container_windows.go index a7348af..d13dfa3 100644 --- a/runtime/container_windows.go +++ b/runtime/container_windows.go @@ -1,11 +1,20 @@ package runtime -import "errors" +import ( + "errors" -func getRootIDs(s *PlatformSpec) (int, int, error) { + "github.com/docker/containerd/specs" +) + +func getRootIDs(s *specs.PlatformSpec) (int, int, error) { return 0, 0, nil } +// TODO Windows: This will have a different implementation +func (c *container) State() State { + return Running // HACK HACK HACK +} + func (c *container) Runtime() string { return "windows" } @@ -38,7 +47,7 @@ func (c *container) Start(checkpoint string, s Stdio) (Process, error) { // TODO Windows: Implement me. // This will have a very different implementation on Windows. -func (c *container) Exec(pid string, spec ProcessSpec, s Stdio) (Process, error) { +func (c *container) Exec(pid string, spec specs.ProcessSpec, s Stdio) (Process, error) { return nil, errors.New("Exec not yet implemented on Windows") } diff --git a/runtime/process.go b/runtime/process.go index c3b2674..7f58378 100644 --- a/runtime/process.go +++ b/runtime/process.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" "strconv" + + "github.com/docker/containerd/specs" ) type Process interface { @@ -25,7 +27,7 @@ type Process interface { // has not exited ExitStatus() (int, error) // Spec returns the process spec that created the process - Spec() ProcessSpec + Spec() specs.ProcessSpec // Signal sends the provided signal to the process Signal(os.Signal) error // Container returns the container that the process belongs to @@ -39,8 +41,8 @@ type Process interface { type processConfig struct { id string root string - processSpec ProcessSpec - spec *PlatformSpec + processSpec specs.ProcessSpec + spec *specs.PlatformSpec c *container stdio Stdio exec bool @@ -118,7 +120,7 @@ type process struct { exitPipe *os.File controlPipe *os.File container *container - spec ProcessSpec + spec specs.ProcessSpec stdio Stdio } @@ -163,7 +165,7 @@ func (p *process) ExitStatus() (int, error) { return strconv.Atoi(string(data)) } -func (p *process) Spec() ProcessSpec { +func (p *process) Spec() specs.ProcessSpec { return p.spec } diff --git a/runtime/runtime.go b/runtime/runtime.go index 5727593..82685aa 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -3,6 +3,8 @@ package runtime import ( "errors" "time" + + "github.com/docker/containerd/specs" ) var ( @@ -46,7 +48,7 @@ type state struct { } type ProcessState struct { - ProcessSpec + specs.ProcessSpec Exec bool `json:"exec"` Stdin string `json:"containerdStdin"` Stdout string `json:"containerdStdout"` diff --git a/runtime/spec_linux.go b/runtime/spec_linux.go deleted file mode 100644 index 147affb..0000000 --- a/runtime/spec_linux.go +++ /dev/null @@ -1,8 +0,0 @@ -package runtime - -import "github.com/opencontainers/specs" - -type ( - PlatformSpec specs.LinuxSpec - ProcessSpec specs.Process -) diff --git a/runtime/spec_windows.go b/runtime/spec_windows.go deleted file mode 100644 index ff4a06a..0000000 --- a/runtime/spec_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -package runtime - -// Temporary Windows version of the spec in lieu of opencontainers/specs having -// Windows support currently. -import "github.com/docker/containerd/specs" - -type PlatformSpec specs.WindowsSpec -type ProcessSpec specs.Process diff --git a/specs/spec_linux.go b/specs/spec_linux.go new file mode 100644 index 0000000..27d9977 --- /dev/null +++ b/specs/spec_linux.go @@ -0,0 +1,9 @@ +package specs + +import ocs "github.com/opencontainers/specs" + +type ( + PlatformSpec ocs.LinuxSpec + ProcessSpec ocs.Process + Spec ocs.Spec +) diff --git a/specs/windows.go b/specs/spec_windows.go similarity index 91% rename from specs/windows.go rename to specs/spec_windows.go index 4871e88..50cbeff 100644 --- a/specs/windows.go +++ b/specs/spec_windows.go @@ -1,5 +1,13 @@ package specs +// Temporary Windows version of the spec in lieu of opencontainers/specs having +// Windows support currently. + +type ( + PlatformSpec WindowsSpec + ProcessSpec Process +) + // This is a temporary module in lieu of opencontainers/specs being compatible // currently on Windows. diff --git a/specs/unsupported.go b/specs/unsupported.go deleted file mode 100644 index fdb50a2..0000000 --- a/specs/unsupported.go +++ /dev/null @@ -1,3 +0,0 @@ -// +build !windows - -package specs diff --git a/supervisor/add_process.go b/supervisor/add_process.go index 6a7e23f..e76077f 100644 --- a/supervisor/add_process.go +++ b/supervisor/add_process.go @@ -4,6 +4,7 @@ import ( "time" "github.com/docker/containerd/runtime" + "github.com/docker/containerd/specs" ) type AddProcessTask struct { @@ -13,7 +14,7 @@ type AddProcessTask struct { Stdout string Stderr string Stdin string - ProcessSpec *runtime.ProcessSpec + ProcessSpec *specs.ProcessSpec StartResponse chan StartResponse } diff --git a/supervisor/sort_test.go b/supervisor/sort_test.go index 0a7498a..905bce0 100644 --- a/supervisor/sort_test.go +++ b/supervisor/sort_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/docker/containerd/runtime" + "github.com/docker/containerd/specs" ) type testProcess struct { @@ -44,8 +45,8 @@ func (p *testProcess) Container() runtime.Container { return nil } -func (p *testProcess) Spec() runtime.ProcessSpec { - return runtime.ProcessSpec{} +func (p *testProcess) Spec() specs.ProcessSpec { + return specs.ProcessSpec{} } func (p *testProcess) Signal(os.Signal) error {