common/pkg/json-proxy: extract proxy library from skopeo#677
common/pkg/json-proxy: extract proxy library from skopeo#677baude merged 3 commits intocontainers:mainfrom
Conversation
|
Packit jobs failed. @containers/packit-build please check. |
2 similar comments
|
Packit jobs failed. @containers/packit-build please check. |
|
Packit jobs failed. @containers/packit-build please check. |
ebf44e7 to
dd325bd
Compare
|
@mtrmac @cgwalters PTAL |
|
changes for Skopeo: containers/skopeo#2816 |
|
I was curious about the diff between this and the original code. Recently I got burned by an LLM rewriting some of code I just expected to be moved (see composefs/composefs-rs#240 ). On this one I had Opus take a look and it said:
(This looks right!)
The core protocol and all RPC method implementations are functionally identical to the skopeo originals. Is this accurate? It seems well worth noting if so any intentional changes from the original... I guess we probably should discuss at least the BSD support, AFAIK this would all work just fine there and would be useful for all the same reasons. MacOS...more nuanced but this does relate to e.g. containers/skopeo#658 in that if we offer a stable RPC API, having progress notifications as part of it would be clearly useful. (Though solving the skopeo-on-mac-progress-and-RPC problem domain really quickly gets into jsonrpc bindings for the Copy operation, not just raw blob fetches) |
the context propagation was forced by the linter we have here, in fact it was not present in the first iteration. The panic was an explicit change I've done to avoid having it in the library code. I wrongly assumed this was Linux-only, I'll take another look at that right now. |
fixed now |
|
Do you know if Go link time dead code will ensure this is omitted from things not using it today? That relates to a related topic in that I think we might just call this "proxy v0" or so and create a "proxy v1" which uses jsonrpc-fdpass from the start or so? |
I've tried vendoring this version into podman, that doesn't use the package, and there is no difference in the resulting binary size |
mtrmac
left a comment
There was a problem hiding this comment.
Just a drive-by looking at the external API shape only. This is not an implicit ACK to the idea.
I really have not followed any progress on the "tar with file descriptor passing for data" PR space since originally complaining about complexity vs. benefit.
I continue to be worried around #674 (comment) , this []any parameter passing style is not really helpful. But I have no firm opinion on long-term direction, nor on possible short-term/long-term trade-offs.
How does this help with #651 at all? c/storage can’t depend on c/common (and this can’t go into c/storage because it depends on c/image).
8e64662 to
7deee87
Compare
there are two reasons for moving the proxy code here: 1) possibly exposing it in podman, so that bootc doesn't need both podman and skopeo, 2) for #651 we will still need a way to expose the splitfdstream JSON API somewhere, and since we already have something similar, we can just add it as a functionality here |
|
This LGTM overall. I did run this through a Gemini review. It pointed out the thought of a Version() function to check the proxies match across versions of Podman say. I didn't see it in the code, is it necessary? Heres Gemini's take: |
I am not deep into this so I may be wrong here but: do we need to invent a new pkg/container-libs that acts as a super-lib that depends on the others and might have this? (effectively starting the ball rolling on making the monorepo more into a monolibrary) |
|
c/common already is "the top one". The point is that we must not have a dependency circle (it doesn’t matter whether it is between Go modules or just subpackages), so c/storage can’t directly depend on anything higher in the stack. |
How did you give Gemini the context here? Seems hard to miss https://github.com/containers/container-libs/pull/677/changes#diff-b737bb5db7429044b5422fe3a693f965cecd5e9c6011364c9ce7e488f901dda8R20 |
IIRC there was historically resistance to this, but I can’t remember the details (there is containers/podman#10075 but that probably doesn’t explain much). @containers/podman-maintainers ? |
|
I agree, if the goal is to add this to podman then this should be discussed with all podman maintainers first if we even want this. And I echo @mtrmac comments about testing, we have enough fragile parts of the stack that we cannot test properly here and always require tests in downstream repos, adding yet another such case is not good. |
|
We are not going to add it to Podman (yet), this is just to prepare this possibility. It will be exposed only in Skopeo for now. Now this feature is hidden in Skopeo, but at some point we'd need to stabilize that as well, unless we are planning to keep using |
|
also, this change will make #651 easier as we will reuse the same proxy endpoint to expose the fd-pass interface |
|
I don't have strong feeling about the location of the code. I don't work on it so if you believe having this here is less maintenance effort sure no objection. I cannot commit to reviewing this here though so I am not going to LGTM it and let someone else do the review/merge. |
Hi @Luap99 we already discussed this in containers/skopeo#2576 (comment) Bigger picture your reply (kind of as before) felt more like a "no" and not a "yes and" - you were not giving any alternative suggestions for paths forward. I'm not just showing up here to slightly increase the binary size of podman - my employer is shipping a product for which we are trying to tightly integrate podman and bootc among other tools to have a more container-native operating system, and so I hope we can come to rough consensus on a path to better integration! To be clear, there is an alternative to this whole codebase, which is in the short term on the bootc (composefs really) side we grow a readonly implmentation of the overlay driver, that's in composefs/composefs-rs#218 But in that path, we'd need to ensure that any nontrivial (esp breaking) changes are coordinated obviously when shipping a product. |
|
I'm generally OK with this and think this is probably the right initial location. Couple of questions: are there consumers of this now or soon in the future that will complain if it is moved again ? secondly, is it possible to include some tests to help address Paul's maintainer concerns? |
the only consumer is Skopeo, there are no other consumers planned for now. Are you OK if we add tests later so in the meanwhile we unblock other work that depends on this? The only goal was to move verbatim (as much as possible) the code from Skopeo here without affecting the functionalities |
|
It should be pretty easy to wire up a new test context here for this. I did one manually before in containers/skopeo#1781 but I think that basically got moved to cirrus in containers/skopeo#1808 and then became a black hole to me... (Edit nevermind I see it now on recent PRs) Edit 2: That said we can do WAY WAY better here nowadays. The way this should work I think is:
|
|
I'm am fine with a promissory test of course. |
|
… oh. We have “integration” tests in Skopeo, and we do run the integration test suite for Skopeo here, but only for the c/image repo. We don’t currently have infrastructure for running Skopeo tests on updates to c/common. So we would notice breakage here only after vendoring updated c/common into Skopeo, with an arbitrarily-long delay. |
|
would be acceptable to run these tests also for this package?
I've added a new commit that enables Skopeo tests also for changes to this package |
But what does this test? The skopeo CI task is named |
.cirrus.yml
Outdated
| $CIRRUS_PR == '' || | ||
| changesInclude('.cirrus.yml', 'go.work', 'go.work.sum') || | ||
| changesInclude('storage/**', 'image/**') | ||
| changesInclude('storage/**', 'image/**', 'common/pkg/json-proxy/**') |
There was a problem hiding this comment.
well arguably this is not right, running the cross task or the in repo image tests when the proxy code changes is not useful
at most we should run it for image_test_skopeo_task but even then see my other comment I do not see how this tests the actual proxy code as this is a different cirrus task in skopeo (ostree-rs-ext)
(I was mostly wrong here, the Skopeo tests do vendor an updated c/common, they just don’t trigger on c/common changes.)
There actually is https://github.com/containers/skopeo/blob/main/integration/proxy_test.go . ( A LLM tells me the two test suites have broadly comparable coverage, testing most of the workflow, with some gaps (different in each one). |
|
@Luap99 thanks for checking that. So it seems we have only two alternatives, accept the delay or duplicate the I'd pick the delay and use a vendoring PR to validate changes, that is no different than what we do with Podman/Buildah |
Ah yeah I guess we could update the cirrus condition then to only run the skopeo int task
I can certainly live with that. |
|
I have not looked at any of the code changes to verify they are right so I wont LGTM but I do not object to having the code here so someone else can merge it anytime. |
|
I'd like to get at least another LGTM here before merging. |
|
I agree with the concerns about tests, we had a live chat about this, I think there's a few options; but leaving aside the full reverse dependency testing (which I think is quite doable and I might have an agent try to draft), but for now:
|
|
Reverse dependency is a good idea, but I think a separate conversation; just getting some testing running locally is IMO sufficient to get this merged. |
Closes: containers#674 Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com> Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
|
added some local tests |
Copy proxy_test.go from skopeo's integration tests and adapt it to run against a minimal test server binary (json-proxy-test-server) that exercises the proxy library directly. Tests are skipped unless JSON_PROXY_TEST_BINARY is set, so they don't break normal CI runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Add a test-integration target to common/Makefile that builds the json-proxy-test-server binary and runs the proxy integration tests against it. Wire it into the Cirrus CI common_testing task. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
mtrmac
left a comment
There was a problem hiding this comment.
Just a late note to keep in mind for the future, no need to immediately change anything (this is an explicitly unstable API anyway).
| // standard logger is used. | ||
| // | ||
| // EXPERIMENTAL: This function is experimental and subject to breaking changes. | ||
| func WithLogger(logger logrus.FieldLogger) Option { |
There was a problem hiding this comment.
logrus is “in maintenance mode”, so adding more explicit dependencies to it is no longer ideal.
I don’t know what to do instead (we have no other logger set up in Skopeo/Podman now). context.Context is sort of non-committal, and sufficient for log/slog to do priority filtering.
Closes: #674
Skopeo PR: containers/skopeo#2816