Skip to content

Commit 2746040

Browse files
committed
Remove the legacy execStart() implementation
The modern execStart() allows interactive exec based on OkHttp 5.3.0
1 parent 545d42b commit 2746040

File tree

3 files changed

+69
-66
lines changed

3 files changed

+69
-66
lines changed

client/src/main/groovy/de/gesellix/docker/client/container/ManageContainerClient.groovy

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ package de.gesellix.docker.client.container
33
import de.gesellix.docker.client.EngineResponseContent
44
import de.gesellix.docker.client.repository.RepositoryAndTag
55
import de.gesellix.docker.client.repository.RepositoryTagParser
6-
import de.gesellix.docker.engine.AttachConfig
76
import de.gesellix.docker.engine.EngineClient
8-
import de.gesellix.docker.engine.EngineResponse
97
import de.gesellix.docker.remote.api.ContainerConfig
108
import de.gesellix.docker.remote.api.ContainerCreateRequest
119
import de.gesellix.docker.remote.api.ContainerCreateResponse
@@ -195,37 +193,6 @@ class ManageContainerClient implements ManageContainer {
195193
return new EngineResponseContent<IdResponse>(containerExec)
196194
}
197195

198-
/**
199-
* @deprecated removed
200-
* @see #startExec(java.lang.String, de.gesellix.docker.remote.api.ExecStartConfig, de.gesellix.docker.remote.api.core.StreamCallback, java.time.Duration)
201-
*/
202-
@Deprecated
203-
@Override
204-
void startExec(String execId, ExecStartConfig execStartConfig, AttachConfig attachConfig) {
205-
log.info("docker start exec '${execId}'")
206-
207-
// When using the TTY setting is enabled in POST /containers/create,
208-
// the stream is the raw data from the process PTY and client’s stdin.
209-
// When the TTY is disabled, then the stream is multiplexed to separate stdout and stderr.
210-
ExecInspectResponse execInspect = client.execApi.execInspect(execId)
211-
boolean multiplexStreams = !execInspect.processConfig.tty
212-
EngineResponse response = engineClient.post([
213-
path : "/exec/${execId}/start".toString(),
214-
body : [Detach: execStartConfig.detach, Tty: execStartConfig.tty],
215-
requestContentType: "application/json",
216-
attach : attachConfig,
217-
multiplexStreams : multiplexStreams])
218-
219-
if (!attachConfig) {
220-
if (response.status?.code == 404) {
221-
log.error("no such exec '${execId}'")
222-
}
223-
responseHandler.ensureSuccessfulResponse(response, new IllegalStateException("docker exec start failed"))
224-
response.stream.multiplexStreams = multiplexStreams
225-
}
226-
// return response
227-
}
228-
229196
@Override
230197
void startExec(String execId, ExecStartConfig execStartConfig, StreamCallback<Frame> callback, Duration timeout) {
231198
log.info("docker start exec '${execId}'")

client/src/main/java/de/gesellix/docker/client/container/ManageContainer.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package de.gesellix.docker.client.container;
22

33
import de.gesellix.docker.client.EngineResponseContent;
4-
import de.gesellix.docker.engine.AttachConfig;
54
import de.gesellix.docker.remote.api.ContainerCreateRequest;
65
import de.gesellix.docker.remote.api.ContainerCreateResponse;
76
import de.gesellix.docker.remote.api.ContainerInspectResponse;
@@ -62,13 +61,6 @@ void attach(String containerId,
6261

6362
EngineResponseContent<IdResponse> createExec(String container, ExecConfig execConfig);
6463

65-
/**
66-
* @deprecated removed
67-
* @see #startExec(java.lang.String, de.gesellix.docker.remote.api.ExecStartConfig, de.gesellix.docker.remote.api.core.StreamCallback, java.time.Duration)
68-
*/
69-
@Deprecated
70-
void startExec(String execId, ExecStartConfig execStartConfig, AttachConfig attachConfig);
71-
7264
void startExec(String execId, ExecStartConfig execStartConfig, StreamCallback<Frame> callback, Duration timeout);
7365

7466
EngineResponseContent<ExecInspectResponse> inspectExec(String execId);

integration-test/src/test/groovy/de/gesellix/docker/client/DockerContainerIntegrationSpec.groovy

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package de.gesellix.docker.client
22

33
import de.gesellix.docker.client.container.ArchiveUtil
4-
import de.gesellix.docker.engine.AttachConfig
54
import de.gesellix.docker.remote.api.ChangeType
65
import de.gesellix.docker.remote.api.ContainerCreateRequest
76
import de.gesellix.docker.remote.api.ContainerUpdateRequest
@@ -23,6 +22,7 @@ import groovy.json.JsonOutput
2322
import groovy.util.logging.Slf4j
2423
import okhttp3.Response
2524
import okhttp3.WebSocket
25+
import okio.BufferedSink
2626
import okio.ByteString
2727
import okio.Okio
2828
import okio.Sink
@@ -657,36 +657,80 @@ class DockerContainerIntegrationSpec extends Specification {
657657

658658
String input = "exec ${UUID.randomUUID()}"
659659
String expectedOutput = "#$input#"
660-
def outputStream = new ByteArrayOutputStream()
661660

662-
def onSinkClosed = new CountDownLatch(1)
663-
def onSourceConsumed = new CountDownLatch(1)
661+
when:
662+
Cancellable job = null
663+
List<Frame> frames = []
664+
def execStartConfig = new ExecStartConfig(false, true, null)
665+
def callback = new StreamCallback<Frame>() {
664666

665-
def attachConfig = new AttachConfig()
666-
attachConfig.streams.stdin = new ByteArrayInputStream("$input\n".bytes)
667-
attachConfig.streams.stdout = outputStream
668-
attachConfig.onFailure = { Exception e ->
669-
log.error("exec failed", e)
670-
}
671-
attachConfig.onResponse = { Response response ->
672-
log.trace("onResponse (${response})")
667+
@Override
668+
void onStarting(Cancellable cancellable) {
669+
job = cancellable
670+
}
671+
672+
@Override
673+
void attachInput(Sink sink) {
674+
System.out.println("attachInput, sending data...")
675+
new Thread(() -> {
676+
BufferedSink buffer = Okio.buffer(sink)
677+
try {
678+
buffer.writeUtf8("$input\n")
679+
buffer.flush()
680+
System.out.println("... data sent")
681+
} catch (IOException e) {
682+
e.printStackTrace()
683+
System.err.println("Failed to write to stdin: " + e.getMessage())
684+
} finally {
685+
try {
686+
Thread.sleep(100)
687+
sink.close()
688+
} catch (Exception ignored) {
689+
// ignore
690+
}
691+
}
692+
}).start()
693+
}
694+
695+
@Override
696+
void onNext(Frame element) {
697+
log.info(element?.toString())
698+
frames.add(element)
699+
}
700+
701+
@Override
702+
void onFailed(Exception e) {
703+
log.error("Exec Attach failed", e)
704+
}
705+
706+
@Override
707+
void onFinished() {
708+
log.info("Exec Attach finished")
709+
}
673710
}
674-
attachConfig.onSinkClosed = { Response response ->
675-
log.trace("onSinkClosed (${response})")
676-
onSinkClosed.countDown()
711+
712+
new Thread(() -> {
713+
dockerClient.startExec(execId, execStartConfig, callback, Duration.ofSeconds(10))
714+
}, "exec-client").start()
715+
716+
CountDownLatch wait = new CountDownLatch(1)
717+
new Timer().schedule(new TimerTask() {
718+
@Override
719+
void run() {
720+
if (job != null) {
721+
job.cancel()
722+
}
723+
wait.countDown()
724+
}
725+
}, 5000)
726+
727+
try {
728+
wait.await()
677729
}
678-
attachConfig.onSourceConsumed = {
679-
log.trace("onSourceConsumed")
680-
onSourceConsumed.countDown()
730+
catch (InterruptedException e) {
731+
e.printStackTrace()
681732
}
682733

683-
when:
684-
def execStartConfig = new ExecStartConfig(false, true, null)
685-
dockerClient.startExec(execId, execStartConfig, attachConfig)
686-
// dockerClient.startExec(execId, execStartConfig, callback, Duration.of(1, ChronoUnit.MINUTES))
687-
onSinkClosed.await(5, SECONDS)
688-
onSourceConsumed.await(5, SECONDS)
689-
690734
def containerIsolation = dockerClient.inspectContainer(containerId).content.hostConfig?.isolation
691735
def actualIsolation = containerIsolation ? SystemInfo.Isolation.values().find { it.value == containerIsolation.value } : LocalDocker.getDaemonIsolation()
692736
if (actualIsolation == SystemInfo.Isolation.Hyperv) {

0 commit comments

Comments
 (0)