fix(render): do not overwrite function docker network if set, start crossplane-container in same network#65
Conversation
|
Thanks for the PR, @nkzk! Would you mind creating an issue for this as well, for discoverability and tracking? I haven't reviewed in detail yet, but the described fixes sound reasonable. |
cad5894 to
abb26bd
Compare
|
I see that there are already tests for passing function annotations to the engine. I had copilot help me create unit tests for injectNetworkAnnotations. Also ran flake check. |
|
Hmm, i got it to work in a devcontainer with this fix, but the current implemention has some issues in CI. But i think this can be solved on the user-side. One of our earliest approaches was to start up functions as service-containers before running multiple/different renders, and it worked because gitlab/github connects the job-container to the bridge-network used by service-containers. But since crossplane render will start up crossplane in another temporary bridge network, it doesnt seem that this will continue to work. However, my theory is that the user can specify the docker-network in their CI-provider (gitlab/github), and then specify the the docker-network flag in the crossplane render command with the fix in this branch to solve this. We have another workflow which uses rootless DinD/PinP, but kind of the same issue there. I'll do some more testing soon. But let me know if something i say sounds off :D |
669f038 to
396a2d1
Compare
|
Think this PR is ready for review, i did some more testing in CI and did not completely figure it out yet, but i think its just an issue of configuring the docker-network in CI and setting that value as the function-docker-network flag in the render-command. A quality of life improvement for us would be if we can spin up the crossplane container ourselves and make render use it. If we could configure the crossplane-containerthe same way as functions, with the development annotation to manage the container lifecycle ourselves, it would just simplify this alot for us. But maybe its out of scope for this PR, i'm not sure whats the best way to implement this would be. But open to work on it if someone has some ideas. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThis PR adds an optional CrossplaneDockerNetwork flag, threads it into the docker render engine, makes dockerRenderEngine.Setup skip temporary network creation when a network is preconfigured, preserves existing runtime network annotations, provides an annotation parser, and wires network defaulting into both render commands. ChangesDocker network preconfiguration support
Sequence DiagramsequenceDiagram
participant RenderCmd
participant FunctionSet
participant EngineFlags
participant dockerEngine
participant DockerNetwork
RenderCmd->>FunctionSet: load functions with annotations
RenderCmd->>RenderCmd: SetDefaultCrossplaneDockerNetwork(fns)
activate RenderCmd
RenderCmd->>FunctionSet: find first function with AnnotationKeyRuntimeDockerNetwork
RenderCmd->>EngineFlags: set CrossplaneDockerNetwork if flag empty
deactivate RenderCmd
RenderCmd->>dockerEngine: NewEngineFromFlags(network: CrossplaneDockerNetwork)
dockerEngine->>dockerEngine: Setup(functions)
alt CrossplaneDockerNetwork is preconfigured
dockerEngine->>FunctionSet: skip annotation injection
dockerEngine-->>RenderCmd: return no-op cleanup
else CrossplaneDockerNetwork is empty
dockerEngine->>DockerNetwork: create temporary render network
dockerEngine->>FunctionSet: inject network annotation
dockerEngine-->>RenderCmd: return cleanup to remove network
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
@nkzk Good thought - I can see how this would be useful. It's a little tricky, since the crossplane container in For your use-case, would it be easier to download a crossplane binary and use the |
adamwg
left a comment
There was a problem hiding this comment.
Thanks for filing an issue for this, and for the fix. A few comments inline, but the overall approach looks good to me.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
cmd/crossplane/render/engine.go (1)
67-71: ⚡ Quick winUpdate stale constructor docs after signature change.
Could you update this comment? On Line 69 it still mentions a
network parameter, butNewEngineFromFlagsnow derives this fromEngineFlags.CrossplaneDockerNetwork.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cmd/crossplane/render/engine.go` around lines 67 - 71, Update the doc comment for NewEngineFromFlags to remove the outdated reference to a `network parameter` and instead state that the Docker network is derived from EngineFlags.CrossplaneDockerNetwork; specifically edit the comment block above the NewEngineFromFlags function to reflect that when no binary path is set it returns a Docker engine using the resolved image reference and that the Docker network is taken from EngineFlags.CrossplaneDockerNetwork (not supplied by the caller).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/crossplane/render/op/cmd.go`:
- Around line 170-185: The override parsing for
render.AnnotationKeyRuntimeDockerNetwork is nested inside the if
c.EngineFlags.CrossplaneDockerNetwork == "" block so the --function-annotations
override never applies when a network is already set; move the block that parses
c.FunctionAnnotations (using render.NewAnnotationsFromStrings and checking
render.AnnotationKeyRuntimeDockerNetwork) out of that conditional and always run
it so that when an annotation value exists you set
c.EngineFlags.CrossplaneDockerNetwork (and/or c.CrossplaneDockerNetwork if used
elsewhere) to that value, ensuring the function-annotations override takes
precedence.
---
Nitpick comments:
In `@cmd/crossplane/render/engine.go`:
- Around line 67-71: Update the doc comment for NewEngineFromFlags to remove the
outdated reference to a `network parameter` and instead state that the Docker
network is derived from EngineFlags.CrossplaneDockerNetwork; specifically edit
the comment block above the NewEngineFromFlags function to reflect that when no
binary path is set it returns a Docker engine using the resolved image reference
and that the Docker network is taken from EngineFlags.CrossplaneDockerNetwork
(not supplied by the caller).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 14a09b90-8615-4a74-831b-924cd8db6271
📒 Files selected for processing (6)
cmd/crossplane/render/annotation.gocmd/crossplane/render/engine.gocmd/crossplane/render/engine_docker.gocmd/crossplane/render/op/cmd.gocmd/crossplane/render/render.gocmd/crossplane/render/xr/cmd.go
🚧 Files skipped from review as they are similar to previous changes (2)
- cmd/crossplane/render/engine_docker.go
- cmd/crossplane/render/render.go
5ecd13a to
2c2f39b
Compare
|
I like this change and I want to see it land, but you've checked off the PR checklist box about adding tests and I don't see any. Have I missed something? |
adamwg
left a comment
There was a problem hiding this comment.
LGTM. Per @jcogilvie's comment, this could probably use a bit of test coverage (may be easiest to factor out the network defaulting logic from both render commands and test it separately).
|
yeah my bad, had some tests but dissapeared in a revert+refactor. i can look into it tomorrow! |
Signed-off-by: Nikita Z <nkzk95@gmail.com>
…ntainer in it Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
…tions in comment Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
…lags if empty, default to the first docker-network annotation in the provided functions. If provided, the docker-network annotation in the FunctionAnnotations cli flag takes presedence Signed-off-by: Nikita Z <nkzk95@gmail.com>
…aneDockerNetwork Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Move Crossplane Docker network defaulting into a shared render helper used by both XR and operation render commands. Add focused coverage for function annotation overrides and network defaulting precedence. Also test both render commands to make sure --function-annotations sets the render engine Docker network before the engine is created. Signed-off-by: Nikita Z <nkzk95@gmail.com>
2974e59 to
591793c
Compare
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <54776184+nkzk@users.noreply.github.com>
|
Added tests with alot of help from copilot, but the tests look reasonable to me. Let me know if you have any more feedback, thanks! :) |
Signed-off-by: Nikita Z <nkzk95@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/crossplane/render/network.go`:
- Around line 42-44: In the condition checking for
AnnotationKeyRuntimeDockerNetwork, add an additional check to verify that the
annotation value is not empty before assigning it to f.CrossplaneDockerNetwork
and returning. If the value is empty, the code should skip the assignment and
return, allowing the loop to continue checking for other valid annotations
instead of short-circuiting on an empty annotation value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 053e7f3a-2568-4b83-a7b9-3686bac7c660
📒 Files selected for processing (11)
cmd/crossplane/render/annotation.gocmd/crossplane/render/engine.gocmd/crossplane/render/engine_docker.gocmd/crossplane/render/network.gocmd/crossplane/render/network_test.gocmd/crossplane/render/op/cmd.gocmd/crossplane/render/op/cmd_test.gocmd/crossplane/render/render.gocmd/crossplane/render/render_test.gocmd/crossplane/render/xr/cmd.gocmd/crossplane/render/xr/cmd_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
- cmd/crossplane/render/annotation.go
- cmd/crossplane/render/engine_docker.go
- cmd/crossplane/render/render.go
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Signed-off-by: Nikita Z <54776184+nkzk@users.noreply.github.com>
…eFlags Now that we no longer manage the docker network ourselves, the CROSSPLANE_DIFF_DOCKER_NETWORK env var doesn't need its own stamping pass over fetched functions. NewEngineRenderFn reads it once and threads the value through render.EngineFlags.CrossplaneDockerNetwork (crossplane/cli#65). The docker engine then: - runs the crossplane-render container on that network (which fixes the other half of crossplane/cli#75 — our prior implementation only placed function containers on the network, leaving the render container unreachable from inside-a-container deployments); - annotates each fn at Setup time so its container joins it too, honouring the don't-overwrite contract for fns the caller has already pinned. What's deleted: - applyDockerNetworkAnnotation helper. - The DefaultFunctionProvider/CachedFunctionProvider calls into it. - The CachedFunctionProvider cache-hit re-stamp dance and its accompanying TestCachedFunctionProvider_DockerNetworkAnnotation_CacheHit test (cache entries no longer need to track env state). - TestApplyDockerNetworkAnnotation (the helper's gone; engine.Setup owns this behaviour now and has its own coverage upstream). Also tightens the EngineRenderFn / Render docstrings and the startRuntimes-error rollback comment to match the merged upstream Engine.Setup contract (cli#159 + follow-up commit ad8307749). The new phrasing acknowledges that no Setup call may ever return a real cleanup (--crossplane-docker-network preset, or local engine), and frames the rollback as "if this call created the environment" rather than "if this was the very first call". Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com>
…359) * refactor(render): unwind multi-composition workaround using cli#159 crossplane/cli#159 makes dockerRenderEngine.Setup idempotent in the network-already-set branch by calling injectNetworkAnnotation there too. That removes the need for EngineRenderFn to capture the docker network name off the first batch's annotations and re-stamp it on later batches itself. EngineRenderFn now calls engine.Setup(ctx, newFns) on every render and accumulates the returned cleanups in a slice that Cleanup walks in LIFO order. The first cleanup is the real one; the rest are no-ops, so the order keeps network teardown last without any first-vs-subsequent bookkeeping. The applyNetworkAnnotation helper was also used by function_provider's CROSSPLANE_DIFF_DOCKER_NETWORK env-var path. That's an independent use case (pre-stamping fns so dockerRenderEngine.Setup's don't-overwrite clause picks up the user's network), so the 6-line loop is inlined into applyDockerNetworkAnnotation, its only remaining caller. The go.mod replace directive points at the PR #159 head while it's in review. Drop it once that PR merges and a crossplane/cli release ships with the fix. Fixes #338 Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> * build(deps): repin crossplane/cli/v2 to upstream main post-merge of cli#159 Upstream PR crossplane/cli#159 — the idempotent-Setup fix this branch relies on — merged to crossplane/cli main at 86f5f7a0. Drop the fork replace directive and pin directly to that commit via the v2.5.0-rc.0.0.20260626181113-86f5f7a0c4bf pseudo-version so this PR can land without waiting for a tagged cli release. The transitive bumps in go.sum (go-openapi/swag/* 0.25.5 → 0.26.0, docker/cli 29.5.3 → 29.6.0, klog/v2 2.130.1 → 2.140.0) come from upstream cli main's newer indirect deps; nothing in crossplane-diff touches those modules directly. Once a tagged cli release containing cli#159 ships (likely v2.4.1 or v2.5.0), a follow-up should bump the pseudo-version to that tag. Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> * chore(lint): apply earthly +reviewable autofixes - render_engine.go: rewrite Cleanup's reverse loop as slices.Backward (Go 1.23+ idiom, suggested by intrange/copyloopvar lint). - function_provider_test.go: regroup the render import added in the workaround unwind alongside the other third-party imports. Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> * refactor(render): route docker network env var through upstream EngineFlags Now that we no longer manage the docker network ourselves, the CROSSPLANE_DIFF_DOCKER_NETWORK env var doesn't need its own stamping pass over fetched functions. NewEngineRenderFn reads it once and threads the value through render.EngineFlags.CrossplaneDockerNetwork (crossplane/cli#65). The docker engine then: - runs the crossplane-render container on that network (which fixes the other half of crossplane/cli#75 — our prior implementation only placed function containers on the network, leaving the render container unreachable from inside-a-container deployments); - annotates each fn at Setup time so its container joins it too, honouring the don't-overwrite contract for fns the caller has already pinned. What's deleted: - applyDockerNetworkAnnotation helper. - The DefaultFunctionProvider/CachedFunctionProvider calls into it. - The CachedFunctionProvider cache-hit re-stamp dance and its accompanying TestCachedFunctionProvider_DockerNetworkAnnotation_CacheHit test (cache entries no longer need to track env state). - TestApplyDockerNetworkAnnotation (the helper's gone; engine.Setup owns this behaviour now and has its own coverage upstream). Also tightens the EngineRenderFn / Render docstrings and the startRuntimes-error rollback comment to match the merged upstream Engine.Setup contract (cli#159 + follow-up commit ad8307749). The new phrasing acknowledges that no Setup call may ever return a real cleanup (--crossplane-docker-network preset, or local engine), and frames the rollback as "if this call created the environment" rather than "if this was the very first call". Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> * refactor(render): only call engine.Setup when there are new fns to integrate Per Copilot review feedback on PR #359: we were calling engine.Setup and appending its returned cleanup to e.cleanups on every Render, even when newFns was empty (all fns already started by a prior render). The slice would grow without bound across long-running engines and the Setup call itself was wasted work. Gate the whole Setup+startRuntimes+bookkeeping block on len(newFns) > 0. Renders where every fn is already running now skip straight to building the render request, leaving e.cleanups bounded by the number of distinct fn batches the engine has actually integrated. No behavioural change for the renders that DO integrate new fns: Setup, startRuntimes, the rollback-on-startRuntimes-error path, and the LIFO cleanup ordering all work the same. Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> * docs(render): align Render/Cleanup doc comments with current behaviour Two Copilot review comments on PR #359, both valid drift introduced by the prior commit that gated Setup on len(newFns) > 0: - Render's doc said "Setup runs on every invocation" — it doesn't anymore. Rewrite to "Setup runs only on invocations that introduce previously-unseen functions; renders whose fns are all already running skip straight to building the request." - Cleanup's doc said it "releases the docker network" — that's only one possible effect now. The cleanups slice is engine-agnostic, so rewrite to "runs the cleanups accumulated from each engine.Setup call in LIFO order. The effect of those cleanups is engine-specific — docker creates and releases a network; local and pre-configured docker accumulate only no-op cleanups." No code change. Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com> --------- Signed-off-by: Jonathan Ogilvie <jonathan.ogilvie@sumologic.com>
Description of your changes
Closes #75
Fixes:
FunctionAnnotationsflag, run crossplane-container in it.I have:
./nix.sh flake checkto ensure this PR is ready for review.backport release-x.ylabels to auto-backport this PR.Need help with this checklist? See the cheat sheet.