66import com .fasterxml .jackson .databind .ObjectMapper ;
77import com .flowci .docker .domain .DockerStartOption ;
88import com .flowci .docker .domain .SSHOption ;
9+ import com .flowci .domain .ObjectWrapper ;
910import com .flowci .util .StringHelper ;
1011import com .github .dockerjava .api .command .InspectContainerResponse ;
1112import com .github .dockerjava .api .model .Container ;
1213import com .github .dockerjava .api .model .Frame ;
14+ import com .github .dockerjava .api .model .StreamType ;
1315import com .jcraft .jsch .*;
1416import lombok .AllArgsConstructor ;
1517import lombok .Getter ;
@@ -24,8 +26,11 @@ public class DockerSSHManager implements DockerManager {
2426
2527 private static final int ChannelTimeout = 10 * 1000 ;
2628
29+ private static final String FormatAsJson = "--format \" {{json .}}\" " ;
30+
2731 private static final ObjectMapper mapper = new ObjectMapper ();
2832
33+
2934 private Session session ;
3035
3136 private final ContainerManager containerManager = new ContainerManagerImpl ();
@@ -60,66 +65,127 @@ public ImageManager getImageManager() {
6065 }
6166
6267 private class ContainerManagerImpl implements ContainerManager {
68+
6369 @ Override
6470 public List <Container > list (String statusFilter , String nameFilter ) throws Exception {
6571 StringBuilder cmd = new StringBuilder ();
6672 cmd .append ("docker ps -a " );
67-
6873 if (StringHelper .hasValue (statusFilter )) {
6974 cmd .append (String .format ("--filter \" status=%s\" " , statusFilter ));
7075 }
71-
7276 if (StringHelper .hasValue (nameFilter )) {
7377 cmd .append (String .format ("--filter \" name=%s\" " , nameFilter ));
7478 }
75-
76- cmd .append ("--format \" {{json .}}\" " );
79+ cmd .append (FormatAsJson );
7780
7881 List <Container > list = new LinkedList <>();
79-
8082 Output output = runCmd (cmd .toString (), (line ) -> {
8183 try {
8284 list .add (mapper .readValue (line , Container .class ));
8385 } catch (JsonProcessingException ignore ) {
84- ignore .printStackTrace ();
8586 }
8687 });
8788
88- if (output .getExit () != 0 ) {
89- throw new Exception (output .getErr ());
90- }
91-
89+ throwExceptionIfError (output );
9290 return list ;
9391 }
9492
9593 @ Override
9694 public InspectContainerResponse inspect (String containerId ) throws Exception {
97- return null ;
95+ String cmd = String .format ("docker inspect %s %s" , containerId , FormatAsJson );
96+ final ObjectWrapper <InspectContainerResponse > inspected = new ObjectWrapper <>();
97+
98+ Output output = runCmd (cmd , (line ) -> {
99+ try {
100+ inspected .setValue (mapper .readValue (line , InspectContainerResponse .class ));
101+ } catch (JsonProcessingException ignore ) {
102+ }
103+ });
104+ throwExceptionIfError (output );
105+
106+ if (!inspected .hasValue ()) {
107+ throw new Exception (String .format ("Unable to inspect container %s result" , containerId ));
108+ }
109+
110+ return inspected .getValue ();
98111 }
99112
100113 @ Override
101114 public String start (DockerStartOption option ) throws Exception {
102- return null ;
115+ StringBuilder cmd = new StringBuilder ();
116+ cmd .append ("docker run -d " );
117+
118+ if (option .hasName ()) {
119+ cmd .append (String .format ("--name %s " , option .getName ()));
120+ }
121+
122+ List <String > entrypoint = option .getEntrypoint ();
123+ if (!entrypoint .isEmpty ()) {
124+ cmd .append (String .format ("--entrypoint %s " , entrypoint .get (0 )));
125+ }
126+
127+ option .getEnv ().forEach ((k , v ) -> cmd .append (String .format ("-e %s=%s " , k , v )));
128+ option .getBind ().forEach ((s , t ) -> cmd .append (String .format ("-v %s:%s " , s , t )));
129+ cmd .append (option .getImage ());
130+
131+ if (!entrypoint .isEmpty () && entrypoint .size () > 1 ) {
132+ cmd .append (" " );
133+ for (int i = 1 ; i < entrypoint .size (); i ++) {
134+ cmd .append (entrypoint .get (i )).append (" " );
135+ }
136+ }
137+
138+ ObjectWrapper <String > cid = new ObjectWrapper <>();
139+ Output output = runCmd (cmd .toString (), cid ::setValue );
140+ throwExceptionIfError (output );
141+
142+ if (!cid .hasValue ()) {
143+ throw new Exception ("Unable to get container line from output" );
144+ }
145+
146+ return cid .getValue ();
103147 }
104148
105149 @ Override
106150 public void wait (String containerId , int timeoutInSeconds , Consumer <Frame > onLog ) throws Exception {
107-
151+ String cmd = String .format ("docker logs -f %s" , containerId );
152+ Output output = runCmd (cmd , (log ) -> {
153+ if (onLog != null ) {
154+ onLog .accept (new Frame (StreamType .RAW , log .getBytes ()));
155+ }
156+ });
157+ throwExceptionIfError (output );
108158 }
109159
110160 @ Override
111161 public void stop (String containerId ) throws Exception {
112-
162+ InspectContainerResponse .ContainerState state = inspect (containerId ).getState ();
163+ Boolean running = state .getRunning ();
164+ if (running != null && running ) {
165+ String cmd = String .format ("docker stop %s" , containerId );
166+ Output output = runCmd (cmd , null );
167+ throwExceptionIfError (output );
168+ }
113169 }
114170
115171 @ Override
116172 public void resume (String containerId ) throws Exception {
117-
173+ String cmd = String .format ("docker start %s" , containerId );
174+ Output output = runCmd (cmd , null );
175+ throwExceptionIfError (output );
118176 }
119177
120178 @ Override
121179 public void delete (String containerId ) throws Exception {
180+ String cmd = String .format ("docker rm -f %s" , containerId );
181+ Output output = runCmd (cmd , null );
182+ throwExceptionIfError (output );
183+ }
184+ }
122185
186+ private void throwExceptionIfError (Output output ) throws Exception {
187+ if (output .getExit () != 0 ) {
188+ throw new Exception (output .getErr ());
123189 }
124190 }
125191
0 commit comments