mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
project: use vndr for vendoring
Signed-off-by: Alexander Morozov <lk4d4@docker.com>
This commit is contained in:
parent
f54339dfea
commit
f2614f2107
2107 changed files with 99972 additions and 26271 deletions
327
vendor/github.com/docker/swarmkit/agent/exec/controller.go
generated
vendored
Normal file
327
vendor/github.com/docker/swarmkit/agent/exec/controller.go
generated
vendored
Normal file
|
@ -0,0 +1,327 @@
|
|||
package exec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/swarmkit/api"
|
||||
"github.com/docker/swarmkit/api/equality"
|
||||
"github.com/docker/swarmkit/log"
|
||||
"github.com/docker/swarmkit/protobuf/ptypes"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Controller controls execution of a task.
|
||||
type Controller interface {
|
||||
// Update the task definition seen by the controller. Will return
|
||||
// ErrTaskUpdateFailed if the provided task definition changes fields that
|
||||
// cannot be changed.
|
||||
//
|
||||
// Will be ignored if the task has exited.
|
||||
Update(ctx context.Context, t *api.Task) error
|
||||
|
||||
// Prepare the task for execution. This should ensure that all resources
|
||||
// are created such that a call to start should execute immediately.
|
||||
Prepare(ctx context.Context) error
|
||||
|
||||
// Start the target and return when it has started successfully.
|
||||
Start(ctx context.Context) error
|
||||
|
||||
// Wait blocks until the target has exited.
|
||||
Wait(ctx context.Context) error
|
||||
|
||||
// Shutdown requests to exit the target gracefully.
|
||||
Shutdown(ctx context.Context) error
|
||||
|
||||
// Terminate the target.
|
||||
Terminate(ctx context.Context) error
|
||||
|
||||
// Remove all resources allocated by the controller.
|
||||
Remove(ctx context.Context) error
|
||||
|
||||
// Close closes any ephemeral resources associated with controller instance.
|
||||
Close() error
|
||||
}
|
||||
|
||||
// ContainerStatuser reports status of a container.
|
||||
//
|
||||
// This can be implemented by controllers or error types.
|
||||
type ContainerStatuser interface {
|
||||
// ContainerStatus returns the status of the target container, if
|
||||
// available. When the container is not available, the status will be nil.
|
||||
ContainerStatus(ctx context.Context) (*api.ContainerStatus, error)
|
||||
}
|
||||
|
||||
// PortStatuser reports status of ports which are allocated by the executor
|
||||
type PortStatuser interface {
|
||||
// PortStatus returns the status on a list of PortConfigs
|
||||
// which are managed at the host level by the controller.
|
||||
PortStatus(ctx context.Context) (*api.PortStatus, error)
|
||||
}
|
||||
|
||||
// Resolve attempts to get a controller from the executor and reports the
|
||||
// correct status depending on the tasks current state according to the result.
|
||||
//
|
||||
// Unlike Do, if an error is returned, the status should still be reported. The
|
||||
// error merely reports the failure at getting the controller.
|
||||
func Resolve(ctx context.Context, task *api.Task, executor Executor) (Controller, *api.TaskStatus, error) {
|
||||
status := task.Status.Copy()
|
||||
|
||||
defer func() {
|
||||
logStateChange(ctx, task.DesiredState, task.Status.State, status.State)
|
||||
}()
|
||||
|
||||
ctlr, err := executor.Controller(task)
|
||||
|
||||
// depending on the tasks state, a failed controller resolution has varying
|
||||
// impact. The following expresses that impact.
|
||||
if task.Status.State < api.TaskStateStarting {
|
||||
if err != nil {
|
||||
// before the task has been started, we consider it a rejection.
|
||||
status.Message = "resolving controller failed"
|
||||
status.Err = err.Error()
|
||||
status.State = api.TaskStateRejected
|
||||
} else if task.Status.State < api.TaskStateAccepted {
|
||||
// we always want to proceed to accepted when we resolve the contoller
|
||||
status.Message = "accepted"
|
||||
status.State = api.TaskStateAccepted
|
||||
}
|
||||
}
|
||||
|
||||
return ctlr, status, err
|
||||
}
|
||||
|
||||
// Do progresses the task state using the controller performing a single
|
||||
// operation on the controller. The return TaskStatus should be marked as the
|
||||
// new state of the task.
|
||||
//
|
||||
// The returned status should be reported and placed back on to task
|
||||
// before the next call. The operation can be cancelled by creating a
|
||||
// cancelling context.
|
||||
//
|
||||
// Errors from the task controller will reported on the returned status. Any
|
||||
// errors coming from this function should not be reported as related to the
|
||||
// individual task.
|
||||
//
|
||||
// If ErrTaskNoop is returned, it means a second call to Do will result in no
|
||||
// change. If ErrTaskDead is returned, calls to Do will no longer result in any
|
||||
// action.
|
||||
func Do(ctx context.Context, task *api.Task, ctlr Controller) (*api.TaskStatus, error) {
|
||||
status := task.Status.Copy()
|
||||
|
||||
// stay in the current state.
|
||||
noop := func(errs ...error) (*api.TaskStatus, error) {
|
||||
return status, ErrTaskNoop
|
||||
}
|
||||
|
||||
retry := func() (*api.TaskStatus, error) {
|
||||
// while we retry on all errors, this allows us to explicitly declare
|
||||
// retry cases.
|
||||
return status, ErrTaskRetry
|
||||
}
|
||||
|
||||
// transition moves the task to the next state.
|
||||
transition := func(state api.TaskState, msg string) (*api.TaskStatus, error) {
|
||||
current := status.State
|
||||
status.State = state
|
||||
status.Message = msg
|
||||
|
||||
if current > state {
|
||||
panic("invalid state transition")
|
||||
}
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// containerStatus exitCode keeps track of whether or not we've set it in
|
||||
// this particular method. Eventually, we assemble this as part of a defer.
|
||||
var (
|
||||
containerStatus *api.ContainerStatus
|
||||
portStatus *api.PortStatus
|
||||
exitCode int
|
||||
)
|
||||
|
||||
// returned when a fatal execution of the task is fatal. In this case, we
|
||||
// proceed to a terminal error state and set the appropriate fields.
|
||||
//
|
||||
// Common checks for the nature of an error should be included here. If the
|
||||
// error is determined not to be fatal for the task,
|
||||
fatal := func(err error) (*api.TaskStatus, error) {
|
||||
if err == nil {
|
||||
panic("err must not be nil when fatal")
|
||||
}
|
||||
|
||||
if cs, ok := err.(ContainerStatuser); ok {
|
||||
var err error
|
||||
containerStatus, err = cs.ContainerStatus(ctx)
|
||||
if err != nil && !contextDoneError(err) {
|
||||
log.G(ctx).WithError(err).Error("error resolving container status on fatal")
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we've set the *correct* exit code
|
||||
if ec, ok := err.(ExitCoder); ok {
|
||||
exitCode = ec.ExitCode()
|
||||
}
|
||||
|
||||
if cause := errors.Cause(err); cause == context.DeadlineExceeded || cause == context.Canceled {
|
||||
return retry()
|
||||
}
|
||||
|
||||
status.Err = err.Error() // still reported on temporary
|
||||
if IsTemporary(err) {
|
||||
return retry()
|
||||
}
|
||||
|
||||
// only at this point do we consider the error fatal to the task.
|
||||
log.G(ctx).WithError(err).Error("fatal task error")
|
||||
|
||||
// NOTE(stevvooe): The following switch dictates the terminal failure
|
||||
// state based on the state in which the failure was encountered.
|
||||
switch {
|
||||
case status.State < api.TaskStateStarting:
|
||||
status.State = api.TaskStateRejected
|
||||
case status.State >= api.TaskStateStarting:
|
||||
status.State = api.TaskStateFailed
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// below, we have several callbacks that are run after the state transition
|
||||
// is completed.
|
||||
defer func() {
|
||||
logStateChange(ctx, task.DesiredState, task.Status.State, status.State)
|
||||
|
||||
if !equality.TaskStatusesEqualStable(status, &task.Status) {
|
||||
status.Timestamp = ptypes.MustTimestampProto(time.Now())
|
||||
}
|
||||
}()
|
||||
|
||||
// extract the container status from the container, if supported.
|
||||
defer func() {
|
||||
// only do this if in an active state
|
||||
if status.State < api.TaskStateStarting {
|
||||
return
|
||||
}
|
||||
|
||||
if containerStatus == nil {
|
||||
// collect this, if we haven't
|
||||
cctlr, ok := ctlr.(ContainerStatuser)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
containerStatus, err = cctlr.ContainerStatus(ctx)
|
||||
if err != nil && !contextDoneError(err) {
|
||||
log.G(ctx).WithError(err).Error("container status unavailable")
|
||||
}
|
||||
|
||||
// at this point, things have gone fairly wrong. Remain positive
|
||||
// and let's get something out the door.
|
||||
if containerStatus == nil {
|
||||
containerStatus = new(api.ContainerStatus)
|
||||
containerStatusTask := task.Status.GetContainer()
|
||||
if containerStatusTask != nil {
|
||||
*containerStatus = *containerStatusTask // copy it over.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// at this point, we *must* have a containerStatus.
|
||||
if exitCode != 0 {
|
||||
containerStatus.ExitCode = int32(exitCode)
|
||||
}
|
||||
|
||||
status.RuntimeStatus = &api.TaskStatus_Container{
|
||||
Container: containerStatus,
|
||||
}
|
||||
|
||||
if portStatus == nil {
|
||||
pctlr, ok := ctlr.(PortStatuser)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var err error
|
||||
portStatus, err = pctlr.PortStatus(ctx)
|
||||
if err != nil && !contextDoneError(err) {
|
||||
log.G(ctx).WithError(err).Error("container port status unavailable")
|
||||
}
|
||||
}
|
||||
|
||||
status.PortStatus = portStatus
|
||||
}()
|
||||
|
||||
if task.DesiredState == api.TaskStateShutdown {
|
||||
if status.State >= api.TaskStateCompleted {
|
||||
return noop()
|
||||
}
|
||||
|
||||
if err := ctlr.Shutdown(ctx); err != nil {
|
||||
return fatal(err)
|
||||
}
|
||||
|
||||
return transition(api.TaskStateShutdown, "shutdown")
|
||||
}
|
||||
|
||||
if status.State > task.DesiredState {
|
||||
return noop() // way beyond desired state, pause
|
||||
}
|
||||
|
||||
// the following states may proceed past desired state.
|
||||
switch status.State {
|
||||
case api.TaskStatePreparing:
|
||||
if err := ctlr.Prepare(ctx); err != nil && err != ErrTaskPrepared {
|
||||
return fatal(err)
|
||||
}
|
||||
|
||||
return transition(api.TaskStateReady, "prepared")
|
||||
case api.TaskStateStarting:
|
||||
if err := ctlr.Start(ctx); err != nil && err != ErrTaskStarted {
|
||||
return fatal(err)
|
||||
}
|
||||
|
||||
return transition(api.TaskStateRunning, "started")
|
||||
case api.TaskStateRunning:
|
||||
if err := ctlr.Wait(ctx); err != nil {
|
||||
return fatal(err)
|
||||
}
|
||||
|
||||
return transition(api.TaskStateCompleted, "finished")
|
||||
}
|
||||
|
||||
// The following represent "pause" states. We can only proceed when the
|
||||
// desired state is beyond our current state.
|
||||
if status.State >= task.DesiredState {
|
||||
return noop()
|
||||
}
|
||||
|
||||
switch status.State {
|
||||
case api.TaskStateNew, api.TaskStatePending, api.TaskStateAssigned:
|
||||
return transition(api.TaskStateAccepted, "accepted")
|
||||
case api.TaskStateAccepted:
|
||||
return transition(api.TaskStatePreparing, "preparing")
|
||||
case api.TaskStateReady:
|
||||
return transition(api.TaskStateStarting, "starting")
|
||||
default: // terminal states
|
||||
return noop()
|
||||
}
|
||||
}
|
||||
|
||||
func logStateChange(ctx context.Context, desired, previous, next api.TaskState) {
|
||||
if previous != next {
|
||||
fields := logrus.Fields{
|
||||
"state.transition": fmt.Sprintf("%v->%v", previous, next),
|
||||
"state.desired": desired,
|
||||
}
|
||||
log.G(ctx).WithFields(fields).Debug("state changed")
|
||||
}
|
||||
}
|
||||
|
||||
func contextDoneError(err error) bool {
|
||||
cause := errors.Cause(err)
|
||||
return cause == context.Canceled || cause == context.DeadlineExceeded
|
||||
}
|
175
vendor/github.com/docker/swarmkit/agent/exec/controller_test.mock.go
generated
vendored
Normal file
175
vendor/github.com/docker/swarmkit/agent/exec/controller_test.mock.go
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
// Automatically generated by MockGen. DO NOT EDIT!
|
||||
// Source: controller.go
|
||||
|
||||
package exec
|
||||
|
||||
import (
|
||||
api "github.com/docker/swarmkit/api"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
context "golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Mock of Controller interface
|
||||
type MockController struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *_MockControllerRecorder
|
||||
}
|
||||
|
||||
// Recorder for MockController (not exported)
|
||||
type _MockControllerRecorder struct {
|
||||
mock *MockController
|
||||
}
|
||||
|
||||
func NewMockController(ctrl *gomock.Controller) *MockController {
|
||||
mock := &MockController{ctrl: ctrl}
|
||||
mock.recorder = &_MockControllerRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (_m *MockController) EXPECT() *_MockControllerRecorder {
|
||||
return _m.recorder
|
||||
}
|
||||
|
||||
func (_m *MockController) Update(ctx context.Context, t *api.Task) error {
|
||||
ret := _m.ctrl.Call(_m, "Update", ctx, t)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Update(arg0, arg1 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Update", arg0, arg1)
|
||||
}
|
||||
|
||||
func (_m *MockController) Prepare(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Prepare", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Prepare(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Prepare", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Start(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Start", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Start(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Start", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Wait(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Wait", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Wait(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Wait", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Shutdown(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Shutdown", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Shutdown(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Shutdown", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Terminate(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Terminate", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Terminate(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Terminate", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Remove(ctx context.Context) error {
|
||||
ret := _m.ctrl.Call(_m, "Remove", ctx)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Remove(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Remove", arg0)
|
||||
}
|
||||
|
||||
func (_m *MockController) Close() error {
|
||||
ret := _m.ctrl.Call(_m, "Close")
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
func (_mr *_MockControllerRecorder) Close() *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "Close")
|
||||
}
|
||||
|
||||
// Mock of ContainerStatuser interface
|
||||
type MockContainerStatuser struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *_MockContainerStatuserRecorder
|
||||
}
|
||||
|
||||
// Recorder for MockContainerStatuser (not exported)
|
||||
type _MockContainerStatuserRecorder struct {
|
||||
mock *MockContainerStatuser
|
||||
}
|
||||
|
||||
func NewMockContainerStatuser(ctrl *gomock.Controller) *MockContainerStatuser {
|
||||
mock := &MockContainerStatuser{ctrl: ctrl}
|
||||
mock.recorder = &_MockContainerStatuserRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (_m *MockContainerStatuser) EXPECT() *_MockContainerStatuserRecorder {
|
||||
return _m.recorder
|
||||
}
|
||||
|
||||
func (_m *MockContainerStatuser) ContainerStatus(ctx context.Context) (*api.ContainerStatus, error) {
|
||||
ret := _m.ctrl.Call(_m, "ContainerStatus", ctx)
|
||||
ret0, _ := ret[0].(*api.ContainerStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
func (_mr *_MockContainerStatuserRecorder) ContainerStatus(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "ContainerStatus", arg0)
|
||||
}
|
||||
|
||||
// Mock of PortStatuser interface
|
||||
type MockPortStatuser struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *_MockPortStatuserRecorder
|
||||
}
|
||||
|
||||
// Recorder for MockPortStatuser (not exported)
|
||||
type _MockPortStatuserRecorder struct {
|
||||
mock *MockPortStatuser
|
||||
}
|
||||
|
||||
func NewMockPortStatuser(ctrl *gomock.Controller) *MockPortStatuser {
|
||||
mock := &MockPortStatuser{ctrl: ctrl}
|
||||
mock.recorder = &_MockPortStatuserRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
func (_m *MockPortStatuser) EXPECT() *_MockPortStatuserRecorder {
|
||||
return _m.recorder
|
||||
}
|
||||
|
||||
func (_m *MockPortStatuser) PortStatus(ctx context.Context) (*api.PortStatus, error) {
|
||||
ret := _m.ctrl.Call(_m, "PortStatus", ctx)
|
||||
ret0, _ := ret[0].(*api.PortStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
func (_mr *_MockPortStatuserRecorder) PortStatus(arg0 interface{}) *gomock.Call {
|
||||
return _mr.mock.ctrl.RecordCall(_mr.mock, "PortStatus", arg0)
|
||||
}
|
84
vendor/github.com/docker/swarmkit/agent/exec/errors.go
generated
vendored
Normal file
84
vendor/github.com/docker/swarmkit/agent/exec/errors.go
generated
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
package exec
|
||||
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
var (
|
||||
// ErrRuntimeUnsupported encountered when a task requires a runtime
|
||||
// unsupported by the executor.
|
||||
ErrRuntimeUnsupported = errors.New("exec: unsupported runtime")
|
||||
|
||||
// ErrTaskPrepared is called if the task is already prepared.
|
||||
ErrTaskPrepared = errors.New("exec: task already prepared")
|
||||
|
||||
// ErrTaskStarted can be returned from any operation that cannot be
|
||||
// performed because the task has already been started. This does not imply
|
||||
// that the task is running but rather that it is no longer valid to call
|
||||
// Start.
|
||||
ErrTaskStarted = errors.New("exec: task already started")
|
||||
|
||||
// ErrTaskUpdateRejected is returned if a task update is rejected by a controller.
|
||||
ErrTaskUpdateRejected = errors.New("exec: task update rejected")
|
||||
|
||||
// ErrControllerClosed returned when a task controller has been closed.
|
||||
ErrControllerClosed = errors.New("exec: controller closed")
|
||||
|
||||
// ErrTaskRetry is returned by Do when an operation failed by should be
|
||||
// retried. The status should still be reported in this case.
|
||||
ErrTaskRetry = errors.New("exec: task retry")
|
||||
|
||||
// ErrTaskNoop returns when the a subsequent call to Do will not result in
|
||||
// advancing the task. Callers should avoid calling Do until the task has been updated.
|
||||
ErrTaskNoop = errors.New("exec: task noop")
|
||||
)
|
||||
|
||||
// ExitCoder is implemented by errors that have an exit code.
|
||||
type ExitCoder interface {
|
||||
// ExitCode returns the exit code.
|
||||
ExitCode() int
|
||||
}
|
||||
|
||||
// Temporary indicates whether or not the error condition is temporary.
|
||||
//
|
||||
// If this is encountered in the controller, the failing operation will be
|
||||
// retried when this returns true. Otherwise, the operation is considered
|
||||
// fatal.
|
||||
type Temporary interface {
|
||||
Temporary() bool
|
||||
}
|
||||
|
||||
// MakeTemporary makes the error temporary.
|
||||
func MakeTemporary(err error) error {
|
||||
if IsTemporary(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
return temporary{err}
|
||||
}
|
||||
|
||||
type temporary struct {
|
||||
error
|
||||
}
|
||||
|
||||
func (t temporary) Cause() error { return t.error }
|
||||
func (t temporary) Temporary() bool { return true }
|
||||
|
||||
// IsTemporary returns true if the error or a recursive cause returns true for
|
||||
// temporary.
|
||||
func IsTemporary(err error) bool {
|
||||
for err != nil {
|
||||
if tmp, ok := err.(Temporary); ok {
|
||||
if tmp.Temporary() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
cause := errors.Cause(err)
|
||||
if cause == err {
|
||||
break
|
||||
}
|
||||
|
||||
err = cause
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
45
vendor/github.com/docker/swarmkit/agent/exec/executor.go
generated
vendored
Normal file
45
vendor/github.com/docker/swarmkit/agent/exec/executor.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
package exec
|
||||
|
||||
import (
|
||||
"github.com/docker/swarmkit/api"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Executor provides controllers for tasks.
|
||||
type Executor interface {
|
||||
// Describe returns the underlying node description.
|
||||
Describe(ctx context.Context) (*api.NodeDescription, error)
|
||||
|
||||
// Configure uses the node object state to propagate node
|
||||
// state to the underlying executor.
|
||||
Configure(ctx context.Context, node *api.Node) error
|
||||
|
||||
// Controller provides a controller for the given task.
|
||||
Controller(t *api.Task) (Controller, error)
|
||||
|
||||
// SetNetworkBootstrapKeys passes the symmetric keys from the
|
||||
// manager to the executor.
|
||||
SetNetworkBootstrapKeys([]*api.EncryptionKey) error
|
||||
}
|
||||
|
||||
// SecretsProvider is implemented by objects that can store secrets, typically
|
||||
// an executor.
|
||||
type SecretsProvider interface {
|
||||
Secrets() SecretsManager
|
||||
}
|
||||
|
||||
// SecretGetter contains secret data necessary for the Controller.
|
||||
type SecretGetter interface {
|
||||
// Get returns the the secret with a specific secret ID, if available.
|
||||
// When the secret is not available, the return will be nil.
|
||||
Get(secretID string) *api.Secret
|
||||
}
|
||||
|
||||
// SecretsManager is the interface for secret storage and updates.
|
||||
type SecretsManager interface {
|
||||
SecretGetter
|
||||
|
||||
Add(secrets ...api.Secret) // add one or more secrets
|
||||
Remove(secrets []string) // remove the secrets by ID
|
||||
Reset() // remove all secrets
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue