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