davsclaus opened a new pull request, #29021:
URL: https://github.com/apache/camel/pull/29021

   Fixes [CAMEL-26191](https://issues.apache.org/jira/browse/CAMEL-26191).
   
   All five points of the issue are real and fixed here.
   
   ### 1. imagebuild with a String or byte[] body succeeds with the body 
unchanged
   
   **What was wrong:** `AsyncDockerProducer.process` caught a `DockerException` 
(and an `InterruptedException`), only logged it and completed the exchange. So 
imagebuild with a body that was not an `InputStream` or a `File` (a `byte[]`, a 
file from a file consumer, `null`, ...) did not build anything and the exchange 
succeeded. This applied to all seven operations of the async producer.
   
   **What changed:**
   - Every exception of the async producer is set on the exchange. An interrupt 
also restores the interrupt flag.
   - imagebuild takes a `File` (Dockerfile or its directory) as before; any 
other body is converted to an `InputStream` (the tar archive of the build 
context), so a `byte[]` or the file of a file consumer works. Without a body 
that converts, the exchange fails with a clear message (the old message was 
"Unable to location source Image").
   
   ### 2. imagebuild ends with the image id of each item, null for a tagged 
build
   
   **What was wrong:** `onNext` set the body to `item.getImageId()` for each 
item, so the last item won. For a tagged build the last line is "Successfully 
tagged", which has no image id, so the body was `null`. A failed build (an 
error item) also ended with `null` and a successful exchange.
   
   **What changed:** the body is set once, after the build, to 
`BuildImageResultCallback.awaitImageId()`. A failed build now fails the 
exchange with "Could not build image: ...".
   
   ### 3. Output of containerlog, attach and execstart is lost; imagepull, 
imagepush and containerwait give the callback
   
   **What was wrong:** the frames were only logged at TRACE, and the body was 
the docker-java callback object, set before the stream was even done.
   
   **What changed** (the body is set after the stream is done):
   - `containerattach`, `containerlog`, `execstart`: the payload of all frames 
(stdout and stderr, in the order received) as a `String`, decoded with the 
exchange charset (UTF-8 by default). The bytes are joined before decoding, so a 
character split over two frames is kept.
   - `containerwait`: the exit code (`Integer`) from `awaitStatusCode()`.
   - `imagepull`: the last `PullResponseItem`. A failed pull fails the exchange 
(docker-java checks it in `awaitCompletion`).
   - `imagepush`: the last `PushResponseItem`. Docker reports a failed push as 
an error item in the stream, which the plain callback ignored; now it fails the 
exchange with "Could not push image: ...".
   
   ### 4. The default cmdExecFactory fails on macOS
   
   **What was wrong:** the default is `NettyDockerCmdExecFactory`. docker-java 
ships the Netty native transports only for x86_64 (`kqueue osx-x86_64`, `epoll 
linux-x86_64`), so on Apple silicon (and Linux arm64) the unix socket fails 
with `UnsatisfiedLinkError: netty_transport_native_kqueue_aarch_64`. 
`DockerConstants.DEFAULT_CMD_EXEC_FACTORY` named the Jersey factory, which is 
not the default.
   
   **What changed:** camel-docker adds 
`netty-transport-native-kqueue:osx-aarch_64` and 
`netty-transport-native-epoll:linux-aarch_64` at runtime scope (version from 
the Netty BOM, same as docker-java uses). The default stays Netty, so nothing 
changes where it already worked. `DEFAULT_CMD_EXEC_FACTORY` now names the Netty 
factory, and `DockerConfiguration` uses the constant.
   
   Checked by hand on macOS arm64 against a local Docker 29.9.2 daemon: before, 
the Netty factory failed with the `UnsatisfiedLinkError`; with this change, 
`version`, `imagebuild` (with a `byte[]` tar and a tag: body is the image id), 
`containerlog` (body is the log text), `containerwait` (body is the exit code) 
all work with the default factory. The probe image and container were removed 
afterwards.
   
   ### 5. The events consumer passes the since time in milliseconds
   
   **What was wrong:** `processInitialEvent` passed `System.currentTimeMillis() 
- initialRange` to `withSince`. docker-java sends it as is to the `since` query 
parameter, which Docker reads as seconds. A millisecond value is a time far in 
the future, so the past events of `CamelDockerInitialRange` were never replayed 
(the live events still came, as Docker does not filter them by `since`).
   
   **What changed:** the value is converted to seconds. 
`CamelDockerInitialRange` stays in milliseconds; its description now says so 
(it was "The initial range").
   
   ### Tests
   
   - New `AsyncDockerProducerTest` (12 tests) with a mocked `DockerClient` 
whose commands feed items to the real docker-java callbacks: image id of a 
tagged build from a `byte[]` body, a build without a build context, a failed 
build, the output of containerlog (with a non-ASCII character), attach and 
execstart, a failed stream, the exit code of containerwait, the last item and 
the failure of imagepull and imagepush. 10 of them failed before the fix; the 
other two (a failed stream and a failed pull) passed before too and guard the 
new error handling.
   - New `DockerEventsConsumerTest.sinceIsInSeconds`: failed before (`since 
1793660628893 is not near 1793660628`).
   - Full module: `mvn clean install -Psourcecheck` 67 tests, 0 failures (4 
skipped, the existing ITs that need a daemon).
   
   ### Docs and generated files
   
   - `@BodyTypes` of the endpoint updated (imagebuild input and output, the 
outputs of the streaming operations); regenerated `docker.json`, copied to the 
catalog with the component doc.
   - Component doc: new "Streaming operations" section.
   - Header description of `CamelDockerInitialRange`; regenerated 
`DockerEndpointBuilderFactory`.
   - Upgrade guide 4.24: a `camel-docker` section, as the bodies change and the 
exchange now fails on errors.
   
   ### Not changed
   
   - The default `cmdExecFactory` is still Netty. Making Jersey the default (as 
the constant suggested) would also fix macOS, but it changes the HTTP transport 
for every user, and the Jersey factory also applies `requestTimeout` as a read 
timeout, which would cut long `containerlog`/`containerwait` calls for users 
who set it.
   - containerattach/containerlog/execstart give the output as one `String`; 
stdout and stderr are not separated. A user who needs them apart can set 
`stdErr=false` or `stdOut=false`.
   
   _Claude Code on behalf of Claus Ibsen (davsclaus)_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to