From a435f2886cc491d2abfbf578f8539c4d677372aa Mon Sep 17 00:00:00 2001 From: Evan Hazlett Date: Wed, 6 Jun 2018 22:32:51 -0400 Subject: [PATCH] separate proc interfaces into standalone package Signed-off-by: Evan Hazlett --- runtime/linux/proc/deleted_state.go | 3 +- runtime/linux/proc/exec.go | 7 +-- runtime/linux/proc/init.go | 15 +++--- runtime/linux/proc/init_state.go | 15 +++--- runtime/linux/proc/process.go | 63 ---------------------- runtime/proc/proc.go | 83 +++++++++++++++++++++++++++++ runtime/shim/service.go | 7 +-- 7 files changed, 109 insertions(+), 84 deletions(-) create mode 100644 runtime/proc/proc.go diff --git a/runtime/linux/proc/deleted_state.go b/runtime/linux/proc/deleted_state.go index 87a3fd0c0..ab89c3ecb 100644 --- a/runtime/linux/proc/deleted_state.go +++ b/runtime/linux/proc/deleted_state.go @@ -22,6 +22,7 @@ import ( "context" "github.com/containerd/console" + "github.com/containerd/containerd/runtime/proc" google_protobuf "github.com/gogo/protobuf/types" "github.com/pkg/errors" ) @@ -65,6 +66,6 @@ func (s *deletedState) SetExited(status int) { // no op } -func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { return nil, errors.Errorf("cannot exec in a deleted state") } diff --git a/runtime/linux/proc/exec.go b/runtime/linux/proc/exec.go index 5fa667ae6..337db1b74 100644 --- a/runtime/linux/proc/exec.go +++ b/runtime/linux/proc/exec.go @@ -31,6 +31,7 @@ import ( "golang.org/x/sys/unix" "github.com/containerd/console" + "github.com/containerd/containerd/runtime/proc" "github.com/containerd/fifo" runc "github.com/containerd/go-runc" specs "github.com/opencontainers/runtime-spec/specs-go" @@ -40,7 +41,7 @@ import ( type execProcess struct { wg sync.WaitGroup - State + proc.State mu sync.Mutex id string @@ -51,7 +52,7 @@ type execProcess struct { pid int closers []io.Closer stdin io.Closer - stdio Stdio + stdio proc.Stdio path string spec specs.Process @@ -127,7 +128,7 @@ func (e *execProcess) Stdin() io.Closer { return e.stdin } -func (e *execProcess) Stdio() Stdio { +func (e *execProcess) Stdio() proc.Stdio { return e.stdio } diff --git a/runtime/linux/proc/init.go b/runtime/linux/proc/init.go index ed7f9066d..c538b7937 100644 --- a/runtime/linux/proc/init.go +++ b/runtime/linux/proc/init.go @@ -34,6 +34,7 @@ import ( "github.com/containerd/containerd/log" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/runtime/linux/runctypes" + "github.com/containerd/containerd/runtime/proc" "github.com/containerd/fifo" runc "github.com/containerd/go-runc" "github.com/containerd/typeurl" @@ -63,7 +64,7 @@ type Init struct { id string bundle string console console.Console - platform Platform + platform proc.Platform io runc.IO runtime *runc.Runc status int @@ -71,7 +72,7 @@ type Init struct { pid int closers []io.Closer stdin io.Closer - stdio Stdio + stdio proc.Stdio rootfs string IoUID int IoGID int @@ -94,7 +95,7 @@ func NewRunc(root, path, namespace, runtime, criu string, systemd bool) *runc.Ru } // New returns a new init process -func New(context context.Context, path, workDir, runtimeRoot, namespace, criu string, systemdCgroup bool, platform Platform, r *CreateConfig) (*Init, error) { +func New(context context.Context, path, workDir, runtimeRoot, namespace, criu string, systemdCgroup bool, platform proc.Platform, r *CreateConfig) (*Init, error) { var success bool var options runctypes.CreateOptions @@ -134,7 +135,7 @@ func New(context context.Context, path, workDir, runtimeRoot, namespace, criu st bundle: r.Bundle, runtime: runtime, platform: platform, - stdio: Stdio{ + stdio: proc.Stdio{ Stdin: r.Stdin, Stdout: r.Stdout, Stderr: r.Stderr, @@ -363,7 +364,7 @@ func (p *Init) Runtime() *runc.Runc { } // exec returns a new exec'd process -func (p *Init) exec(context context.Context, path string, r *ExecConfig) (Process, error) { +func (p *Init) exec(context context.Context, path string, r *ExecConfig) (proc.Process, error) { // process exec request var spec specs.Process if err := json.Unmarshal(r.Spec.Value, &spec); err != nil { @@ -376,7 +377,7 @@ func (p *Init) exec(context context.Context, path string, r *ExecConfig) (Proces path: path, parent: p, spec: spec, - stdio: Stdio{ + stdio: proc.Stdio{ Stdin: r.Stdin, Stdout: r.Stdout, Stderr: r.Stderr, @@ -430,7 +431,7 @@ func (p *Init) update(context context.Context, r *google_protobuf.Any) error { } // Stdio of the process -func (p *Init) Stdio() Stdio { +func (p *Init) Stdio() proc.Stdio { return p.stdio } diff --git a/runtime/linux/proc/init_state.go b/runtime/linux/proc/init_state.go index 0cbdc7ac1..55c0f0559 100644 --- a/runtime/linux/proc/init_state.go +++ b/runtime/linux/proc/init_state.go @@ -25,6 +25,7 @@ import ( "github.com/containerd/console" "github.com/containerd/containerd/errdefs" + "github.com/containerd/containerd/runtime/proc" "github.com/containerd/fifo" runc "github.com/containerd/go-runc" google_protobuf "github.com/gogo/protobuf/types" @@ -32,13 +33,13 @@ import ( ) type initState interface { - State + proc.State Pause(context.Context) error Resume(context.Context) error Update(context.Context, *google_protobuf.Any) error Checkpoint(context.Context, *CheckpointConfig) error - Exec(context.Context, string, *ExecConfig) (Process, error) + Exec(context.Context, string, *ExecConfig) (proc.Process, error) } type createdState struct { @@ -130,7 +131,7 @@ func (s *createdState) SetExited(status int) { } } -func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { s.p.mu.Lock() defer s.p.mu.Unlock() return s.p.exec(ctx, path, r) @@ -272,7 +273,7 @@ func (s *createdCheckpointState) SetExited(status int) { } } -func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { s.p.mu.Lock() defer s.p.mu.Unlock() @@ -364,7 +365,7 @@ func (s *runningState) SetExited(status int) { } } -func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { s.p.mu.Lock() defer s.p.mu.Unlock() return s.p.exec(ctx, path, r) @@ -456,7 +457,7 @@ func (s *pausedState) SetExited(status int) { } } -func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { s.p.mu.Lock() defer s.p.mu.Unlock() @@ -536,7 +537,7 @@ func (s *stoppedState) SetExited(status int) { // no op } -func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (Process, error) { +func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) { s.p.mu.Lock() defer s.p.mu.Unlock() diff --git a/runtime/linux/proc/process.go b/runtime/linux/proc/process.go index 135f9962b..53252ec60 100644 --- a/runtime/linux/proc/process.go +++ b/runtime/linux/proc/process.go @@ -19,66 +19,12 @@ package proc import ( - "context" - "io" - "sync" - "time" - - "github.com/containerd/console" "github.com/pkg/errors" ) // RuncRoot is the path to the root runc state directory const RuncRoot = "/run/containerd/runc" -// Stdio of a process -type Stdio struct { - Stdin string - Stdout string - Stderr string - Terminal bool -} - -// IsNull returns true if the stdio is not defined -func (s Stdio) IsNull() bool { - return s.Stdin == "" && s.Stdout == "" && s.Stderr == "" -} - -// Process on a linux system -type Process interface { - State - // ID returns the id for the process - ID() string - // Pid returns the pid for the process - Pid() int - // ExitStatus returns the exit status - ExitStatus() int - // ExitedAt is the time the process exited - ExitedAt() time.Time - // Stdin returns the process STDIN - Stdin() io.Closer - // Stdio returns io information for the container - Stdio() Stdio - // Status returns the process status - Status(context.Context) (string, error) - // Wait blocks until the process has exited - Wait() -} - -// State of a process -type State interface { - // Resize resizes the process console - Resize(ws console.WinSize) error - // Start execution of the process - Start(context.Context) error - // Delete deletes the process and its resourcess - Delete(context.Context) error - // Kill kills the process - Kill(context.Context, uint32, bool) error - // SetExited sets the exit status for the process - SetExited(status int) -} - func stateName(v interface{}) string { switch v.(type) { case *runningState, *execRunningState: @@ -94,12 +40,3 @@ func stateName(v interface{}) string { } panic(errors.Errorf("invalid state %v", v)) } - -// Platform handles platform-specific behavior that may differs across -// platform implementations -type Platform interface { - CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, - wg, cwg *sync.WaitGroup) (console.Console, error) - ShutdownConsole(ctx context.Context, console console.Console) error - Close() error -} diff --git a/runtime/proc/proc.go b/runtime/proc/proc.go new file mode 100644 index 000000000..02bc9bda8 --- /dev/null +++ b/runtime/proc/proc.go @@ -0,0 +1,83 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package proc + +import ( + "context" + "io" + "sync" + "time" + + "github.com/containerd/console" +) + +// Stdio of a process +type Stdio struct { + Stdin string + Stdout string + Stderr string + Terminal bool +} + +// IsNull returns true if the stdio is not defined +func (s Stdio) IsNull() bool { + return s.Stdin == "" && s.Stdout == "" && s.Stderr == "" +} + +// Process on a system +type Process interface { + State + // ID returns the id for the process + ID() string + // Pid returns the pid for the process + Pid() int + // ExitStatus returns the exit status + ExitStatus() int + // ExitedAt is the time the process exited + ExitedAt() time.Time + // Stdin returns the process STDIN + Stdin() io.Closer + // Stdio returns io information for the container + Stdio() Stdio + // Status returns the process status + Status(context.Context) (string, error) + // Wait blocks until the process has exited + Wait() +} + +// State of a process +type State interface { + // Resize resizes the process console + Resize(ws console.WinSize) error + // Start execution of the process + Start(context.Context) error + // Delete deletes the process and its resourcess + Delete(context.Context) error + // Kill kills the process + Kill(context.Context, uint32, bool) error + // SetExited sets the exit status for the process + SetExited(status int) +} + +// Platform handles platform-specific behavior that may differs across +// platform implementations +type Platform interface { + CopyConsole(ctx context.Context, console console.Console, stdin, stdout, stderr string, + wg, cwg *sync.WaitGroup) (console.Console, error) + ShutdownConsole(ctx context.Context, console console.Console) error + Close() error +} diff --git a/runtime/shim/service.go b/runtime/shim/service.go index 154f19c5c..379e5cf5b 100644 --- a/runtime/shim/service.go +++ b/runtime/shim/service.go @@ -34,6 +34,7 @@ import ( "github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime/linux/proc" "github.com/containerd/containerd/runtime/linux/runctypes" + rproc "github.com/containerd/containerd/runtime/proc" shimapi "github.com/containerd/containerd/runtime/shim/v1" runc "github.com/containerd/go-runc" "github.com/containerd/typeurl" @@ -78,7 +79,7 @@ func NewService(config Config, publisher events.Publisher) (*Service, error) { s := &Service{ config: config, context: ctx, - processes: make(map[string]proc.Process), + processes: make(map[string]rproc.Process), events: make(chan interface{}, 128), ec: Default.Subscribe(), } @@ -96,9 +97,9 @@ type Service struct { config Config context context.Context - processes map[string]proc.Process + processes map[string]rproc.Process events chan interface{} - platform proc.Platform + platform rproc.Platform ec chan runc.Exit // Filled by Create()