separate proc interfaces into standalone package

Signed-off-by: Evan Hazlett <ejhazlett@gmail.com>
This commit is contained in:
Evan Hazlett 2018-06-06 22:32:51 -04:00
parent 00d4910633
commit a435f2886c
7 changed files with 109 additions and 84 deletions

View File

@ -22,6 +22,7 @@ import (
"context" "context"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd/runtime/proc"
google_protobuf "github.com/gogo/protobuf/types" google_protobuf "github.com/gogo/protobuf/types"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -65,6 +66,6 @@ func (s *deletedState) SetExited(status int) {
// no op // 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") return nil, errors.Errorf("cannot exec in a deleted state")
} }

View File

@ -31,6 +31,7 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd/runtime/proc"
"github.com/containerd/fifo" "github.com/containerd/fifo"
runc "github.com/containerd/go-runc" runc "github.com/containerd/go-runc"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
@ -40,7 +41,7 @@ import (
type execProcess struct { type execProcess struct {
wg sync.WaitGroup wg sync.WaitGroup
State proc.State
mu sync.Mutex mu sync.Mutex
id string id string
@ -51,7 +52,7 @@ type execProcess struct {
pid int pid int
closers []io.Closer closers []io.Closer
stdin io.Closer stdin io.Closer
stdio Stdio stdio proc.Stdio
path string path string
spec specs.Process spec specs.Process
@ -127,7 +128,7 @@ func (e *execProcess) Stdin() io.Closer {
return e.stdin return e.stdin
} }
func (e *execProcess) Stdio() Stdio { func (e *execProcess) Stdio() proc.Stdio {
return e.stdio return e.stdio
} }

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/log" "github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount" "github.com/containerd/containerd/mount"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
"github.com/containerd/containerd/runtime/proc"
"github.com/containerd/fifo" "github.com/containerd/fifo"
runc "github.com/containerd/go-runc" runc "github.com/containerd/go-runc"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
@ -63,7 +64,7 @@ type Init struct {
id string id string
bundle string bundle string
console console.Console console console.Console
platform Platform platform proc.Platform
io runc.IO io runc.IO
runtime *runc.Runc runtime *runc.Runc
status int status int
@ -71,7 +72,7 @@ type Init struct {
pid int pid int
closers []io.Closer closers []io.Closer
stdin io.Closer stdin io.Closer
stdio Stdio stdio proc.Stdio
rootfs string rootfs string
IoUID int IoUID int
IoGID 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 // 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 success bool
var options runctypes.CreateOptions var options runctypes.CreateOptions
@ -134,7 +135,7 @@ func New(context context.Context, path, workDir, runtimeRoot, namespace, criu st
bundle: r.Bundle, bundle: r.Bundle,
runtime: runtime, runtime: runtime,
platform: platform, platform: platform,
stdio: Stdio{ stdio: proc.Stdio{
Stdin: r.Stdin, Stdin: r.Stdin,
Stdout: r.Stdout, Stdout: r.Stdout,
Stderr: r.Stderr, Stderr: r.Stderr,
@ -363,7 +364,7 @@ func (p *Init) Runtime() *runc.Runc {
} }
// exec returns a new exec'd process // 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 // process exec request
var spec specs.Process var spec specs.Process
if err := json.Unmarshal(r.Spec.Value, &spec); err != nil { 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, path: path,
parent: p, parent: p,
spec: spec, spec: spec,
stdio: Stdio{ stdio: proc.Stdio{
Stdin: r.Stdin, Stdin: r.Stdin,
Stdout: r.Stdout, Stdout: r.Stdout,
Stderr: r.Stderr, Stderr: r.Stderr,
@ -430,7 +431,7 @@ func (p *Init) update(context context.Context, r *google_protobuf.Any) error {
} }
// Stdio of the process // Stdio of the process
func (p *Init) Stdio() Stdio { func (p *Init) Stdio() proc.Stdio {
return p.stdio return p.stdio
} }

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/console" "github.com/containerd/console"
"github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/runtime/proc"
"github.com/containerd/fifo" "github.com/containerd/fifo"
runc "github.com/containerd/go-runc" runc "github.com/containerd/go-runc"
google_protobuf "github.com/gogo/protobuf/types" google_protobuf "github.com/gogo/protobuf/types"
@ -32,13 +33,13 @@ import (
) )
type initState interface { type initState interface {
State proc.State
Pause(context.Context) error Pause(context.Context) error
Resume(context.Context) error Resume(context.Context) error
Update(context.Context, *google_protobuf.Any) error Update(context.Context, *google_protobuf.Any) error
Checkpoint(context.Context, *CheckpointConfig) error Checkpoint(context.Context, *CheckpointConfig) error
Exec(context.Context, string, *ExecConfig) (Process, error) Exec(context.Context, string, *ExecConfig) (proc.Process, error)
} }
type createdState struct { 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() s.p.mu.Lock()
defer s.p.mu.Unlock() defer s.p.mu.Unlock()
return s.p.exec(ctx, path, r) 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() s.p.mu.Lock()
defer s.p.mu.Unlock() 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() s.p.mu.Lock()
defer s.p.mu.Unlock() defer s.p.mu.Unlock()
return s.p.exec(ctx, path, r) 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() s.p.mu.Lock()
defer s.p.mu.Unlock() defer s.p.mu.Unlock()
@ -536,7 +537,7 @@ func (s *stoppedState) SetExited(status int) {
// no op // 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() s.p.mu.Lock()
defer s.p.mu.Unlock() defer s.p.mu.Unlock()

View File

@ -19,66 +19,12 @@
package proc package proc
import ( import (
"context"
"io"
"sync"
"time"
"github.com/containerd/console"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// RuncRoot is the path to the root runc state directory // RuncRoot is the path to the root runc state directory
const RuncRoot = "/run/containerd/runc" 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 { func stateName(v interface{}) string {
switch v.(type) { switch v.(type) {
case *runningState, *execRunningState: case *runningState, *execRunningState:
@ -94,12 +40,3 @@ func stateName(v interface{}) string {
} }
panic(errors.Errorf("invalid state %v", v)) 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
}

83
runtime/proc/proc.go Normal file
View File

@ -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
}

View File

@ -34,6 +34,7 @@ import (
"github.com/containerd/containerd/runtime" "github.com/containerd/containerd/runtime"
"github.com/containerd/containerd/runtime/linux/proc" "github.com/containerd/containerd/runtime/linux/proc"
"github.com/containerd/containerd/runtime/linux/runctypes" "github.com/containerd/containerd/runtime/linux/runctypes"
rproc "github.com/containerd/containerd/runtime/proc"
shimapi "github.com/containerd/containerd/runtime/shim/v1" shimapi "github.com/containerd/containerd/runtime/shim/v1"
runc "github.com/containerd/go-runc" runc "github.com/containerd/go-runc"
"github.com/containerd/typeurl" "github.com/containerd/typeurl"
@ -78,7 +79,7 @@ func NewService(config Config, publisher events.Publisher) (*Service, error) {
s := &Service{ s := &Service{
config: config, config: config,
context: ctx, context: ctx,
processes: make(map[string]proc.Process), processes: make(map[string]rproc.Process),
events: make(chan interface{}, 128), events: make(chan interface{}, 128),
ec: Default.Subscribe(), ec: Default.Subscribe(),
} }
@ -96,9 +97,9 @@ type Service struct {
config Config config Config
context context.Context context context.Context
processes map[string]proc.Process processes map[string]rproc.Process
events chan interface{} events chan interface{}
platform proc.Platform platform rproc.Platform
ec chan runc.Exit ec chan runc.Exit
// Filled by Create() // Filled by Create()