moving HostConfig into the ThinContainerExecRunner interface
[arvados.git] / lib / crunchrun / container_exec_types.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package crunchrun
6
7 import (
8         "bufio"
9         "io"
10         "net"
11
12         "golang.org/x/net/context"
13 )
14
15 // ContainerConfig holds all values needed for Docker and Singularity
16 // to run a container. In the case of docker is similar to
17 // github.com/docker/docker/api/types/container/Config
18 // see https://github.com/moby/moby/blob/master/api/types/container/config.go
19 // "It should hold only portable information about the container."
20 // and for Singularity TBD
21 type ContainerConfig struct {
22         Image        string
23         OpenStdin    bool
24         StdinOnce    bool
25         AttachStdin  bool
26         AttachStdout bool
27         AttachStderr bool
28
29         Cmd        []string
30         WorkingDir string
31         Env        []string
32         Volumes    map[string]struct{}
33 }
34
35 // LogConfig represents the logging configuration of the container.
36 type LogConfig struct {
37         Type   string
38         Config map[string]string
39 }
40
41 // Resources contains container's resources (cgroups config, ulimits...)
42 type Resources struct {
43         Memory       int64  // Memory limit (in bytes)
44         NanoCPUs     int64  `json:"NanoCpus"` // CPU quota in units of 10<sup>-9</sup> CPUs.
45         CgroupParent string // Parent cgroup.
46         MemorySwap   int64  // Total memory usage (memory + swap); set `-1` to enable unlimited swap
47         KernelMemory int64  // Kernel memory limit (in bytes)
48 }
49
50 type NetworkMode string
51
52 // HostConfig holds all values needed for Docker and Singularity
53 // to run a container related to the host. In the case of docker is
54 // similar to github.com/docker/docker/api/types/container/HostConfig
55 // see https://github.com/moby/moby/blob/master/api/types/container/host_config.go
56 // "dependent of the host we are running on".
57 // and for Singularity TBD
58 type HostConfig struct {
59         NetworkMode NetworkMode
60         Binds       []string // List of volume bindings for this container
61         //important bits:
62         LogConfig LogConfig // Configuration of the logs for this container
63
64         // Contains container's resources (cgroups, ulimits)
65         Resources
66 }
67
68 // ---- NETROWKING STUFF
69 // EndpointIPAMConfig represents IPAM configurations for the endpoint
70 type EndpointIPAMConfig struct {
71         IPv4Address  string   `json:",omitempty"`
72         IPv6Address  string   `json:",omitempty"`
73         LinkLocalIPs []string `json:",omitempty"`
74 }
75
76 // EndpointSettings stores the network endpoint details
77 type EndpointSettings struct {
78         // Configurations
79         IPAMConfig *EndpointIPAMConfig
80         Links      []string
81         Aliases    []string
82         // Operational data
83         NetworkID           string
84         EndpointID          string
85         Gateway             string
86         IPAddress           string
87         IPPrefixLen         int
88         IPv6Gateway         string
89         GlobalIPv6Address   string
90         GlobalIPv6PrefixLen int
91         MacAddress          string
92         DriverOpts          map[string]string
93 }
94
95 // ----
96 // NetworkingConfig holds all values needed for Docker and Singularity
97 // related network. In the case of docker is similar to
98 // github.com/docker/docker/api/types/network/NetworkingConfig
99 // and for Singularity TBD.
100 type NetworkingConfig struct {
101         EndpointsConfig map[string]*EndpointSettings
102 }
103
104 // ContainerCreateResponse in the case of docker will be similar to
105 // github.com/docker/docker/api/types/container/ContainerCreateCreatedBody
106 // and for Singularity TBD.
107 type ContainerCreateResponse struct {
108         // The ID of the created container
109         // Required: true
110         ID string
111         // Warnings encountered when creating the container
112         // Required: true
113         Warnings []string
114 }
115
116 // ContainerStartOptions in the case of docker will be similar to
117 // github.com/docker/docker/api/types/container/ContainerStartOptions
118 // and for Singularity TBD.
119 type ContainerStartOptions struct {
120         // FIXME: do we need this in this wrapping? since we only use it's zero value
121         // just to comply with Docker's ContainerStart API
122         // maybe not using it will be the best
123         CheckpointID  string
124         CheckpointDir string
125 }
126
127 // ContainerRemoveOptions in the case of docker will be similar to
128 // github.com/docker/docker/api/types/container/ContainerRemoveOptions
129 // and for Singularity TBD.
130 type ContainerRemoveOptions struct {
131         // FIXME: we *only* call it with dockertypes.ContainerRemoveOptions{Force: true})
132         // may be should not be in this
133         Force bool
134 }
135
136 // ContainerAttachOptions in the case of docker will be similar to
137 // github.com/docker/docker/api/types/container/ContainerAttachOptions
138 // and for Singularity TBD.
139 type ContainerAttachOptions struct {
140         Stream bool
141         Stdin  bool
142         Stdout bool
143         Stderr bool
144 }
145
146 // ImageRemoveOptions in the case of docker will be similar to
147 // github.com/docker/docker/api/types/container/ImageRemoveOptions
148 // and for Singularity TBD.
149 type ImageRemoveOptions struct {
150         Force         bool
151         PruneChildren bool
152         //not used as far as I know
153 }
154
155 // ContainerInspectResponse in the case of docker will be similar to
156 // github.com/docker/docker/api/types/ContainerJSON
157 // and for Singularity TBD.
158 // MAYBE call it ExecRunnerContainer? since the struct is describing  a container
159 // from the underlying ExecRunner
160 type ContainerInspectResponse struct {
161         //Important bits for us
162         // State = current checks: (nil, Running, Created)
163         State *ContainerState
164 }
165
166 // ImageInspectResponse  in the case of docker is similar to
167 //  github.com/docker/docker/api/types/ImageInspect
168 // and for Singularity TBD.
169 // MAYBE call it ExecRunnerImage? since the struct is describing an image
170 // from the underlying ExecRunner
171 type ImageInspectResponse struct {
172         // we don't use the respones but we use ImageInspectWithRaw(context.TODO(), imageID)
173         // to check if we already have the docker image, maybe we can do the
174         // a imagePresent(id string) (bool)
175         ID string
176 }
177
178 // ImageLoadResponse returns information to the client about a load process.
179 type ImageLoadResponse struct {
180         // Body must be closed to avoid a resource leak
181         Body io.ReadCloser
182         JSON bool
183 }
184
185 // ImageDeleteResponseItem is a reply from ImageRemove.
186 type ImageDeleteResponseItem struct {
187
188         // The image ID of an image that was deleted
189         Deleted string `json:"Deleted,omitempty"`
190
191         // The image ID of an image that was untagged
192         Untagged string `json:"Untagged,omitempty"`
193 }
194
195 // ContainerState stores container's running state
196 // it's part of ContainerJSONBase and will return by "inspect" command
197 type ContainerState struct {
198         Status     string // String representation of the container state. Can be one of "created", "running", "paused", "restarting", "removing", "exited", or "dead"
199         Running    bool
200         Paused     bool
201         Restarting bool
202         OOMKilled  bool
203         Dead       bool
204         Pid        int
205         ExitCode   int
206         Error      string
207         StartedAt  string
208         FinishedAt string
209 }
210
211 // HijackedResponse holds connection information for a hijacked request.
212
213 // HijackedResponse is needed as an artifact that comes from docker.
214 // We need to figure out if this is the best abstraction at this level
215 // for now this is a copy and paste from docker package. Might evolve later.
216 type HijackedResponse struct {
217         Conn   net.Conn
218         Reader *bufio.Reader
219 }
220
221 // Close closes the hijacked connection and reader.
222 func (h *HijackedResponse) Close() {
223         h.Conn.Close()
224 }
225
226 // CloseWriter is an interface that implements structs
227 // that close input streams to prevent from writing.
228 type CloseWriter interface {
229         CloseWrite() error
230 }
231
232 // CloseWrite closes a readWriter for writing.
233 func (h *HijackedResponse) CloseWrite() error {
234         if conn, ok := h.Conn.(CloseWriter); ok {
235                 return conn.CloseWrite()
236         }
237         return nil
238 }
239
240 //------------ End of HijackedResponse
241
242 // Similar to HijackedResponse, Waitcondtion is here and will decide later how is implemented in Singularity
243
244 // WaitCondition is a type used to specify a container state for which
245 // to wait.
246 type WaitCondition string
247
248 // Possible WaitCondition Values.
249 //
250 // WaitConditionNotRunning (default) is used to wait for any of the non-running
251 // states: "created", "exited", "dead", "removing", or "removed".
252 //
253 // WaitConditionNextExit is used to wait for the next time the state changes
254 // to a non-running state. If the state is currently "created" or "exited",
255 // this would cause Wait() to block until either the container runs and exits
256 // or is removed.
257 //
258 // WaitConditionRemoved is used to wait for the container to be removed.
259 const (
260         WaitConditionNotRunning WaitCondition = "not-running"
261         WaitConditionNextExit   WaitCondition = "next-exit"
262         WaitConditionRemoved    WaitCondition = "removed"
263 )
264
265 //------------ End of WaitCondition
266
267 // ContainerWaitOKBody
268 /// yetanother copy, this time from  from docker/api/types/container/container_wait.go.
269 // That file is generated from swagger, so I don't think is a good idea to have it
270 // here. but for now, I'll finish creating the abstraction layer
271
272 // ContainerWaitOKBodyError container waiting error, if any
273 // swagger:model ContainerWaitOKBodyError
274 type ContainerWaitOKBodyError struct {
275
276         // Details of an error
277         Message string `json:"Message,omitempty"`
278 }
279
280 // ContainerWaitOKBody OK response to ContainerWait operation
281 // swagger:model ContainerWaitOKBody
282 type ContainerWaitOKBody struct {
283
284         // error
285         // Required: true
286         Error *ContainerWaitOKBodyError `json:"Error"`
287
288         // Exit code of the container
289         // Required: true
290         StatusCode int64 `json:"StatusCode"`
291 }
292
293 //------------ End of ContainerWaitOKBody
294
295 // ThinContainerExecRunner is the "common denominator" interface for all ExecRunners
296 // (either Docker or Singularity or more to come). For now is based in the
297 //  ThinDockerClient interface with our own objects (instead of the ones that come
298 // from docker)
299 type ThinContainerExecRunner interface {
300         GetContainerConfig() (ContainerConfig, error)
301         GetHostConfig() (HostConfig, error)
302
303         GetImage() (imageID string)
304         SetImage(imageID string)
305
306         SetHostConfig(hostConfig HostConfig) error
307         GetNetworkMode() (networkMode NetworkMode)
308         SetNetworkMode(networkMode NetworkMode)
309
310         ContainerAttach(ctx context.Context, container string, options ContainerAttachOptions) (HijackedResponse, error)
311         ContainerCreate(ctx context.Context, config ContainerConfig, hostConfig HostConfig, networkingConfig *NetworkingConfig, containerName string) (ContainerCreateResponse, error)
312         ContainerStart(ctx context.Context, container string, options ContainerStartOptions) error
313         ContainerRemove(ctx context.Context, container string, options ContainerRemoveOptions) error
314         ContainerWait(ctx context.Context, container string, condition WaitCondition) (<-chan ContainerWaitOKBody, <-chan error)
315
316         ContainerInspect(ctx context.Context, id string) (ContainerInspectResponse, error)
317         ImageInspectWithRaw(ctx context.Context, image string) (ImageInspectResponse, []byte, error)
318
319         ImageLoad(ctx context.Context, input io.Reader, quiet bool) (ImageLoadResponse, error)
320         ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]ImageDeleteResponseItem, error)
321 }