summaryrefslogtreecommitdiff
path: root/runtime/execdriver/driver.go
blob: 27a575cb3a4b66d5fac56ee5dde837244b4716c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package execdriver

import (
	"errors"
	"io"
	"os"
	"os/exec"
)

// Context is a generic key value pair that allows
// arbatrary data to be sent
type Context map[string]string

var (
	ErrNotRunning              = errors.New("Process could not be started")
	ErrWaitTimeoutReached      = errors.New("Wait timeout reached")
	ErrDriverAlreadyRegistered = errors.New("A driver already registered this docker init function")
	ErrDriverNotFound          = errors.New("The requested docker init has not been found")
)

var dockerInitFcts map[string]InitFunc

type (
	StartCallback func(*Command)
	InitFunc      func(i *InitArgs) error
)

func RegisterInitFunc(name string, fct InitFunc) error {
	if dockerInitFcts == nil {
		dockerInitFcts = make(map[string]InitFunc)
	}
	if _, ok := dockerInitFcts[name]; ok {
		return ErrDriverAlreadyRegistered
	}
	dockerInitFcts[name] = fct
	return nil
}

func GetInitFunc(name string) (InitFunc, error) {
	fct, ok := dockerInitFcts[name]
	if !ok {
		return nil, ErrDriverNotFound
	}
	return fct, nil
}

// Args provided to the init function for a driver
type InitArgs struct {
	User       string
	Gateway    string
	Ip         string
	WorkDir    string
	Privileged bool
	Env        []string
	Args       []string
	Mtu        int
	Driver     string
	Console    string
	Pipe       int
	Root       string
}

// Driver specific information based on
// processes registered with the driver
type Info interface {
	IsRunning() bool
}

// Terminal in an interface for drivers to implement
// if they want to support Close and Resize calls from
// the core
type Terminal interface {
	io.Closer
	Resize(height, width int) error
}

type TtyTerminal interface {
	Master() *os.File
}

type Driver interface {
	Run(c *Command, pipes *Pipes, startCallback StartCallback) (int, error) // Run executes the process and blocks until the process exits and returns the exit code
	Kill(c *Command, sig int) error
	Name() string                                 // Driver name
	Info(id string) Info                          // "temporary" hack (until we move state from core to plugins)
	GetPidsForContainer(id string) ([]int, error) // Returns a list of pids for the given container.
	Terminate(c *Command) error                   // kill it with fire
}

// Network settings of the container
type Network struct {
	Interface *NetworkInterface `json:"interface"` // if interface is nil then networking is disabled
	Mtu       int               `json:"mtu"`
}

type NetworkInterface struct {
	Gateway     string `json:"gateway"`
	IPAddress   string `json:"ip"`
	Bridge      string `json:"bridge"`
	IPPrefixLen int    `json:"ip_prefix_len"`
}

type Resources struct {
	Memory     int64 `json:"memory"`
	MemorySwap int64 `json:"memory_swap"`
	CpuShares  int64 `json:"cpu_shares"`
}

type Mount struct {
	Source      string `json:"source"`
	Destination string `json:"destination"`
	Writable    bool   `json:"writable"`
	Private     bool   `json:"private"`
}

// Process wrapps an os/exec.Cmd to add more metadata
type Command struct {
	exec.Cmd `json:"-"`

	ID         string              `json:"id"`
	Privileged bool                `json:"privileged"`
	User       string              `json:"user"`
	Rootfs     string              `json:"rootfs"`   // root fs of the container
	InitPath   string              `json:"initpath"` // dockerinit
	Entrypoint string              `json:"entrypoint"`
	Arguments  []string            `json:"arguments"`
	WorkingDir string              `json:"working_dir"`
	ConfigPath string              `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
	Tty        bool                `json:"tty"`
	Network    *Network            `json:"network"`
	Config     map[string][]string `json:"config"` //  generic values that specific drivers can consume
	Resources  *Resources          `json:"resources"`
	Mounts     []Mount             `json:"mounts"`

	Terminal     Terminal `json:"-"`             // standard or tty terminal
	Console      string   `json:"-"`             // dev/console path
	ContainerPid int      `json:"container_pid"` // the pid for the process inside a container
}

// Return the pid of the process
// If the process is nil -1 will be returned
func (c *Command) Pid() int {
	return c.ContainerPid
}