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