1
1
package client
2
2
3
3
import (
4
- "bytes"
5
4
"context"
6
5
"errors"
6
+ "fmt"
7
7
"github.com/docker/docker/api/types"
8
8
"github.com/docker/docker/api/types/filters"
9
9
"github.com/docker/docker/client"
@@ -22,6 +22,7 @@ type Client struct {
22
22
waitGroup sync.WaitGroup
23
23
ctx context.Context
24
24
dockerClient * client.Client
25
+ UsePipes bool
25
26
}
26
27
27
28
// NewClientWithContext create a new docker compose client with custom context.
@@ -44,6 +45,7 @@ func NewClientWithContext(ctx context.Context, composePath string) (*Client, err
44
45
projectName : CompileNames (filepath .Base (composePath )),
45
46
dockerClient : dockerClient ,
46
47
ctx : ctx ,
48
+ UsePipes : true ,
47
49
}
48
50
return c , nil
49
51
}
@@ -59,14 +61,44 @@ func CompileNames(str string) string {
59
61
}
60
62
61
63
// initCmd initialize cmd for docker compose.
62
- func (c * Client ) initCmd (ctx context.Context , buffer * bytes. Buffer ) * exec.Cmd {
64
+ func (c * Client ) initCmd (ctx context.Context ) * exec.Cmd {
63
65
cmd := exec .CommandContext (ctx , c .bin , c .baseArgs ... )
64
66
cmd .Dir = c .composePath
65
- cmd .Stdout = buffer
66
- cmd .Stderr = buffer
67
67
return cmd
68
68
}
69
69
70
+ func (c * Client ) runCommand (args ... string ) (* Pipes , error ) {
71
+ cmd := c .initCmd (c .ctx )
72
+ var pipes * Pipes
73
+ var err error
74
+ if c .UsePipes {
75
+ stdin , err := cmd .StdinPipe ()
76
+ if err != nil {
77
+ return nil , err
78
+ }
79
+ stdout , err := cmd .StdoutPipe ()
80
+ if err != nil {
81
+ return nil , err
82
+ }
83
+ stderr , err := cmd .StderrPipe ()
84
+ if err != nil {
85
+ return nil , err
86
+ }
87
+ pipes = & Pipes {
88
+ Stdin : stdin ,
89
+ Stdout : stdout ,
90
+ Stderr : stderr ,
91
+ }
92
+ }
93
+ addCmdArgs (cmd , args ... )
94
+ err = cmd .Start ()
95
+ if err != nil {
96
+ return nil , err
97
+ }
98
+ c .addWaitForCmd (cmd )
99
+ return pipes , nil
100
+ }
101
+
70
102
// addCmdArgs add args to cmd.
71
103
func addCmdArgs (cmd * exec.Cmd , args ... string ) {
72
104
cmd .Args = append (cmd .Args , args ... )
@@ -78,125 +110,67 @@ func (c *Client) Wait() {
78
110
}
79
111
80
112
// Up create and start containers.
81
- func (c * Client ) Up () (* bytes.Buffer , error ) {
82
- stdout := & bytes.Buffer {}
83
- cmd := c .initCmd (c .ctx , stdout )
84
- addCmdArgs (cmd , "up" , "-d" )
85
- err := cmd .Start ()
86
- if err != nil {
87
- return nil , err
88
- }
89
- c .addWaitForCmd (cmd )
90
- return stdout , nil
91
- }
92
-
93
- func (c * Client ) baseStartStop (start bool , service * string ) (* bytes.Buffer , error ) {
94
- stdout := & bytes.Buffer {}
95
- cmd := c .initCmd (c .ctx , stdout )
96
- if start {
97
- if service == nil {
98
- addCmdArgs (cmd , "start" )
99
- } else {
100
- addCmdArgs (cmd , "start" , CompileNames (* service ))
101
- }
102
- } else {
103
- if service == nil {
104
- addCmdArgs (cmd , "stop" )
105
- } else {
106
- addCmdArgs (cmd , "stop" , CompileNames (* service ))
107
- }
108
- }
109
- err := cmd .Start ()
110
- if err != nil {
111
- return nil , err
112
- }
113
-
114
- c .addWaitForCmd (cmd )
115
- return stdout , nil
113
+ func (c * Client ) Up () (* Pipes , error ) {
114
+ return c .runCommand ("up" , "-d" )
116
115
}
117
116
118
117
// Start service container.
119
- func (c * Client ) Start (service string ) (* bytes. Buffer , error ) {
120
- return c .baseStartStop ( true , & service )
118
+ func (c * Client ) Start (service string ) (* Pipes , error ) {
119
+ return c .runCommand ( "start" , CompileNames ( service ) )
121
120
}
122
121
123
122
// StartAll start all service containers.
124
- func (c * Client ) StartAll () (* bytes. Buffer , error ) {
125
- return c .baseStartStop ( true , nil )
123
+ func (c * Client ) StartAll () (* Pipes , error ) {
124
+ return c .runCommand ( "start" )
126
125
}
127
126
128
127
// Stop service container.
129
- func (c * Client ) Stop (service string ) (* bytes. Buffer , error ) {
130
- return c .baseStartStop ( false , & service )
128
+ func (c * Client ) Stop (service string ) (* Pipes , error ) {
129
+ return c .runCommand ( "stop" , CompileNames ( service ) )
131
130
}
132
131
133
132
// StopAll stop all service containers.
134
- func (c * Client ) StopAll () (* bytes.Buffer , error ) {
135
- return c .baseStartStop (false , nil )
136
- }
137
-
138
- func (c * Client ) baseBuild (service * string ) (* bytes.Buffer , error ) {
139
- stdout := & bytes.Buffer {}
140
- cmd := c .initCmd (c .ctx , stdout )
141
- if service == nil {
142
- addCmdArgs (cmd , "build" )
143
- } else {
144
- addCmdArgs (cmd , "build" , CompileNames (* service ))
145
- }
146
- err := cmd .Start ()
147
- if err != nil {
148
- return nil , err
149
- }
150
-
151
- c .addWaitForCmd (cmd )
152
- return stdout , nil
133
+ func (c * Client ) StopAll () (* Pipes , error ) {
134
+ return c .runCommand ("stop" )
153
135
}
154
136
155
137
// Build or rebuild services.
156
- func (c * Client ) Build (service string ) (* bytes. Buffer , error ) {
157
- return c .baseBuild ( & service )
138
+ func (c * Client ) Build (service string ) (* Pipes , error ) {
139
+ return c .runCommand ( "build" , CompileNames ( service ) )
158
140
}
159
141
160
142
// BuildAll Build or rebuild services.
161
- func (c * Client ) BuildAll () (* bytes. Buffer , error ) {
162
- return c .baseBuild ( nil )
143
+ func (c * Client ) BuildAll () (* Pipes , error ) {
144
+ return c .runCommand ( "build" )
163
145
}
164
146
165
147
// Convert converts the compose file to platform's canonical format.
166
- func (c * Client ) Convert () error {
167
- panic ( "implement me " )
148
+ func (c * Client ) Convert () ( * Pipes , error ) {
149
+ return c . runCommand ( "convert " )
168
150
}
169
151
170
152
func (c * Client ) Cp () error {
171
153
panic ("implement me" )
172
154
}
173
155
174
156
// Create creates container for a service.
175
- func (c * Client ) Create (service string ) error {
176
- panic ( "implement me" )
157
+ func (c * Client ) Create (service string ) ( * Pipes , error ) {
158
+ return c . runCommand ( "create" , CompileNames ( service ) )
177
159
}
178
160
179
161
// CreateAll creates containers for a service.
180
- func (c * Client ) CreateAll () error {
181
- panic ( "implement me " )
162
+ func (c * Client ) CreateAll () ( * Pipes , error ) {
163
+ return c . runCommand ( "create " )
182
164
}
183
165
184
166
// Down stops containers and removes containers, networks, volumes, and images created by up.
185
- func (c * Client ) Down () (* bytes.Buffer , error ) {
186
- stdout := & bytes.Buffer {}
187
- cmd := c .initCmd (c .ctx , stdout )
188
- addCmdArgs (cmd , "down" )
189
- err := cmd .Start ()
190
- if err != nil {
191
- return nil , err
192
- }
193
- c .addWaitForCmd (cmd )
194
- return stdout , nil
167
+ func (c * Client ) Down () (* Pipes , error ) {
168
+ return c .runCommand ("down" )
195
169
}
196
170
197
171
// Events displays real time events from containers.
198
- func (c * Client ) Events () error {
199
- panic ( "implement me " )
172
+ func (c * Client ) Events () ( * Pipes , error ) {
173
+ return c . runCommand ( "events " )
200
174
}
201
175
202
176
// Exec execute a command in a running container.
@@ -209,59 +183,39 @@ func (c *Client) Images() error {
209
183
panic ("implement me" )
210
184
}
211
185
212
- func (c * Client ) baseKill (service * string ) error {
213
- cmd := c .initCmd (c .ctx , nil )
214
- if service == nil {
215
- addCmdArgs (cmd , "kill" )
216
- } else {
217
- addCmdArgs (cmd , "kill" , CompileNames (* service ))
218
- }
219
- err := cmd .Run ()
220
- if err != nil {
221
- return err
222
- }
223
- return nil
224
- }
225
-
226
186
// Kill stops running container without removing them.
227
- func (c * Client ) Kill (service string ) error {
228
- return c .baseKill ( & service )
187
+ func (c * Client ) Kill (service string ) ( * Pipes , error ) {
188
+ return c .runCommand ( "kill" , CompileNames ( service ) )
229
189
}
230
190
231
191
// KillAll stops running containers without removing them.
232
- func (c * Client ) KillAll () error {
233
- return c .baseKill ( nil )
192
+ func (c * Client ) KillAll () ( * Pipes , error ) {
193
+ return c .runCommand ( "kill" )
234
194
}
235
195
236
196
// Logs shows container logs.
237
- func (c * Client ) Logs (service string ) error {
197
+ func (c * Client ) Logs (service string ) ( * Pipes , error ) {
238
198
panic ("implement me" )
239
199
}
240
200
241
201
// LogsStream shows container logs as a stream.
242
- func (c * Client ) LogsStream (service string ) error {
202
+ func (c * Client ) LogsStream (service string ) ( * Pipes , error ) {
243
203
panic ("implement me" )
244
204
}
245
205
246
206
// LogsAll shows all container logs.
247
- func (c * Client ) LogsAll () error {
207
+ func (c * Client ) LogsAll () ( * Pipes , error ) {
248
208
panic ("implement me" )
249
209
}
250
210
251
211
// LogsAllStream shows all container logs as a stream.
252
- func (c * Client ) LogsAllStream () error {
212
+ func (c * Client ) LogsAllStream () ( * Pipes , error ) {
253
213
panic ("implement me" )
254
214
}
255
215
256
216
// Pause pauses container.
257
- func (c * Client ) Pause (service string ) error {
258
- cmd := c .initCmd (c .ctx , nil )
259
- addCmdArgs (cmd , "pause" )
260
- err := cmd .Run ()
261
- if err != nil {
262
- return err
263
- }
264
- return nil
217
+ func (c * Client ) Pause (service string ) (* Pipes , error ) {
218
+ return c .runCommand ("pause" , CompileNames (service ))
265
219
}
266
220
267
221
// PauseAll pauses all containers.
@@ -270,24 +224,18 @@ func (c *Client) PauseAll() error {
270
224
}
271
225
272
226
// Unpause unpauses container.
273
- func (c * Client ) Unpause (service string ) error {
274
- cmd := c .initCmd (c .ctx , nil )
275
- addCmdArgs (cmd , "unpause" )
276
- err := cmd .Run ()
277
- if err != nil {
278
- return err
279
- }
280
- return nil
227
+ func (c * Client ) Unpause (service string ) (* Pipes , error ) {
228
+ return c .runCommand ("unpause" , CompileNames (service ))
281
229
}
282
230
283
231
// UnpauseAll unpauses all containers.
284
- func (c * Client ) UnpauseAll () error {
285
- panic ( "implement me " )
232
+ func (c * Client ) UnpauseAll () ( * Pipes , error ) {
233
+ return c . runCommand ( "unpause " )
286
234
}
287
235
288
236
// Port displays public facing port of the container.
289
- func (c * Client ) Port (service string , innerPort uint16 ) error {
290
- panic ( "implement me" )
237
+ func (c * Client ) Port (service string , innerPort uint16 ) ( * Pipes , error ) {
238
+ return c . runCommand ( "port" , CompileNames ( service ), fmt . Sprintf ( "%d" , innerPort ) )
291
239
}
292
240
293
241
// Ps lists running containers.
@@ -310,60 +258,28 @@ func (c *Client) Push() error {
310
258
panic ("implement me" )
311
259
}
312
260
313
- func (c * Client ) baseRestart (service * string ) (* bytes.Buffer , error ) {
314
- stdout := & bytes.Buffer {}
315
- cmd := c .initCmd (c .ctx , stdout )
316
- if service == nil {
317
- addCmdArgs (cmd , "restart" )
318
- } else {
319
- addCmdArgs (cmd , "restart" , * service )
320
- }
321
- err := cmd .Start ()
322
- if err != nil {
323
- return nil , err
324
- }
325
- c .addWaitForCmd (cmd )
326
- return stdout , nil
327
- }
328
-
329
261
// Restart restart service container.
330
- func (c * Client ) Restart (service string ) (* bytes. Buffer , error ) {
331
- return c .baseRestart ( & service )
262
+ func (c * Client ) Restart (service string ) (* Pipes , error ) {
263
+ return c .runCommand ( "restart" , CompileNames ( service ) )
332
264
}
333
265
334
266
// RestartAll restart service containers.
335
- func (c * Client ) RestartAll () (* bytes.Buffer , error ) {
336
- return c .baseRestart (nil )
337
- }
338
-
339
- func (c * Client ) baseRm (service * string ) (* bytes.Buffer , error ) {
340
- stdout := & bytes.Buffer {}
341
- cmd := c .initCmd (c .ctx , stdout )
342
- if service == nil {
343
- addCmdArgs (cmd , "rm" )
344
- } else {
345
- addCmdArgs (cmd , "rm" , * service )
346
- }
347
- err := cmd .Start ()
348
- if err != nil {
349
- return nil , err
350
- }
351
- c .addWaitForCmd (cmd )
352
- return stdout , nil
267
+ func (c * Client ) RestartAll () (* Pipes , error ) {
268
+ return c .runCommand ("restart" )
353
269
}
354
270
355
271
// Rm removes stopped service containers.
356
- func (c * Client ) Rm (service string ) (* bytes. Buffer , error ) {
357
- return c .baseRm ( & service )
272
+ func (c * Client ) Rm (service string ) (* Pipes , error ) {
273
+ return c .runCommand ( "rm" , CompileNames ( service ) )
358
274
}
359
275
360
276
// RmAll removes all service containers.
361
- func (c * Client ) RmAll () (* bytes. Buffer , error ) {
362
- return c .baseRm ( nil )
277
+ func (c * Client ) RmAll () (* Pipes , error ) {
278
+ return c .runCommand ( "rm" )
363
279
}
364
280
365
281
// Run a one-off command on a service.
366
- func (c * Client ) Run (service string , commands ... string ) (* bytes. Buffer , error ) {
282
+ func (c * Client ) Run (service string , commands ... string ) (* Pipes , error ) {
367
283
panic ("implement me" )
368
284
}
369
285
0 commit comments