-
Notifications
You must be signed in to change notification settings - Fork 935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix devlxd image export #13730
Fix devlxd image export #13730
Conversation
@tomponline @MusicDin I'm guessing since devlxd image export was broken we don't have tests for it? I've tested it manually and from the speed of the image download in the guest it must have come from the host (the guest downloaded Another thing I wan't to be absolutely certain of is that an authenticated client can see public images in a project they don't have access to. Shall I mark as draft for now while I work on tests? Otherwise I can put up a separate PR. |
Thanks for this 🚀 I'm not sure how to reliably test it within CI. The instance needs internet access to fetch the fingerprint for the given image name/alias. Haven't tested, but maybe if fingerprint is provided instead of an alias, it will check for the image directly on the host. This would be handy as we can simply prevent instance's access to the internet and ensure image download does not fail. Otherwise, I can think only of limiting the time for the image download to ensure it was fetched from the host (maybe this can be more reliable if we use some bigger images like Ubuntu). For local development you can error out after this block: lxd/client/simplestreams_images.go Lines 70 to 76 in 9df996e
See the change in Also merging this PR should close this issue #13595 |
I think we should avoid calling out to external remotes if at all possible. I'll investigate whether it is possible to trick the guest LXD by using |
My last comment was a bit shortsighted 😆. We can't run nested LXD in the busy box test image. We'll have to put tests for this into the lxd-ci repo instead. |
This is fine by me |
Marking as draft for a bit. Still adding tests. I need to raise a couple of issues on the back of this as well. |
b71f344
to
2426d4d
Compare
@tomponline this is ready for review. The associated test PR is here: canonical/lxd-ci#240 |
lxd/images.go
Outdated
trusted := auth.IsTrusted(r.Context()) | ||
|
||
// Unauthenticated clients that do not provide a secret may only view public images. | ||
// Devlxd queries can be for private images but only if they are cached. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are only private cached images allowed? I feel like this comment could do with expanding.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the comments here but I'm still not sure I've made it super clear to be honest.
Devlxd queries can be for public images because the image is accessible to anyone. Devlxd queries can be for private images only when the image is cached from a public remote. E.g. if the host has ubuntu:22.04
downloaded, we cache it but don't make it public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that makes sense.
We don't want to trigger a download of an image on the host.
BTW are we restricting which project images are accessible by /dev/lxd requests to only those of the instance's effective image project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently are devlxd requests are for the default project.
I think this warrants a separate issue though. As I understand it, all cached images are stored in the default project. If I launch an ubuntu:22.04
container in project test
say, and then create another ubuntu:22.04
inside it, then restricting the devlxd
request to only project test
would miss the cached image and download it via the ubuntu remote instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing that doesn't make sense to me is how to actually make an image public on a host that is accessible to the nested LXD. The nested LXD doesn't have the host added as a remote, so it can't resolve the alias of the public image. As far as I can tell, this feature only works for cached images.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK thanks, yes please can you create a separate issue.
I'm not sure that "all cached images are stored in the default project" but if /dev/lxd only servers from the default project currently then we dont need to change it in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing that doesn't make sense to me is how to actually make an image public on a host that is accessible to the nested LXD. The nested LXD doesn't have the host added as a remote, so it can't resolve the alias of the public image. As far as I can tell, this feature only works for cached images.
Does lxc image import server:fingerprint
work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK thanks, yes please can you create a separate issue.
I'm not sure that "all cached images are stored in the default project" but if /dev/lxd only servers from the default project currently then we dont need to change it in this PR.
Another thing that doesn't make sense to me is how to actually make an image public on a host that is accessible to the nested LXD. The nested LXD doesn't have the host added as a remote, so it can't resolve the alias of the public image. As far as I can tell, this feature only works for cached images.
Does
lxc image import server:fingerprint
work?
In canonical/lxd-ci#240 I experimented with creating an image on the host and making it public. This would prove that image export over devlxd was working because the image would not be present anywhere else. The problem is that you can't specify the host as a remote (e.g. what do you put as "server" in the command you posted), so I tried out a few things related to this comment. The methods I tried were:
- (naively)
lxc init "ubuntu:{host_image_fingerprint}" c1
. This doesn't work because the client tries to resolve the image against the ubuntu remote. - Using
lxc query -X POST /1.0/instances
and providing an image source with the fingerprint of the public image on the host. For this you need to provide a remote URL, so I added the ubuntu URL. This fails because the guest LXD tries to get the image from the remote to perform architecture checks (here). - Downloading the image directly via cURL. This doesn't really work because the downloaded
octet-stream
needs to be split intorootfs
and metadata files before you can do anything. I also didn't like this because it doesn't actually test that the guest will download an image from the host when requested, only that the socket itself works.
b4657aa
to
931f1c1
Compare
Static analysis failing because I touched |
931f1c1
to
31b5ffa
Compare
Now fixed. |
Signed-off-by: Mark Laing <[email protected]>
Signed-off-by: Mark Laing <[email protected]>
…nts. Signed-off-by: Mark Laing <[email protected]>
Signed-off-by: Mark Laing <[email protected]>
31b5ffa
to
caf60bd
Compare
caf60bd
to
ebb2cbc
Compare
Signed-off-by: Mark Laing <[email protected]>
Signed-off-by: Mark Laing <[email protected]>
Go conventions state that single letter variable names should be used for receivers, for familiar types (e.g. r for io.Reader or *http.Request) or in very short scopes such as loops. They shouldn't be used for field names. See https://google.github.io/styleguide/go/decisions.html#single-letter-variable-names. Signed-off-by: Mark Laing <[email protected]>
Field names are optional if private according to the Go style guide (https://google.github.io/styleguide/go/decisions.html#field-names), but for consistency in our code-base we should include the field names. Signed-off-by: Mark Laing <[email protected]>
Additionally, if the `net.Conn` in `(*ConnPidMapper).ConnStateHandler` is not a (*net.UnixConn), return early to avoid a panic. Signed-off-by: Mark Laing <[email protected]>
Signed-off-by: Mark Laing <[email protected]>
Additionally standardise the error message. Signed-off-by: Mark Laing <[email protected]>
Signed-off-by: Mark Laing <[email protected]>
ebb2cbc
to
f58a9cd
Compare
@tomponline I've clarified the commits to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
Adds tests for the devlxd socket in a container. These tests are based on the devlxd tests for VMs, with additional testing for image export over the socket. Note: I wasn't sure where else to add this test other than in the github workflow. Also note: This test will fail on edge until canonical/lxd#13730 is merged.
This was caused by calling
CheckPermission
without considering that the handler is called internally by devlxd.In this PR I have updated all image handlers that have
AllowUntrusted
set to true. The handling of authentication/authorization is clarified with comments indicating what should happen when the caller is:Comments contextual of whether the image is public, private, or cached.
Closes #13678
Closes #13167