-
Notifications
You must be signed in to change notification settings - Fork 95
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
Implement image-rs basic features #4
Conversation
As we are early in the development stages, let's merge the PR so others may contribute to it? @sameo |
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 tried to check out the code and run the tests but hit some problems and had some questions.
oci-distribution = { git = "https://github.com/arronwy/oci-distribution", branch = "export_pull_layer" } | ||
oci-spec = { git = "https://github.com/containers/oci-spec-rs" } | ||
ocicrypt-rs = { git = "https://github.com/arronwy/ocicrypt-rs", branch = "oci_distribution" } |
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.
Hey @arronwy - I notice that these dependencies are pulled from a branch of your fork of the projects, is that something you're planning to resolve soon by getting those changes merged upstream and then using the main
versions?
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.
Yes, there are two pending PR in oci-distribution to support manifest list and public pull layer API, after these two PRs are merged, we'll use the upstream repo.
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.
Any progress about the oci-distribution upstream?
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.
Upstream PR for image manifest list support have beed merged, they basicly agree public pull_layer
and auth
API, the PR should be merged soon, these two API may face refactoring when oci-distribution targeting 1.0 release.
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use anyhow::{anyhow, Result}; | ||
use nix::mount::MsFlags; |
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.
When I run the cargo build
on my mac I get:
unresolved import `nix::mount`
--> src/snapshots/overlay.rs:6:10
|
6 | use nix::mount::MsFlags;
| ^^^^^ could not find `mount` in `nix`
It may well be that mac (x86_64, not darwin) isn't supported, but I thought I'd let you know.
data/generate_test_data.md
Outdated
@@ -0,0 +1,16 @@ | |||
## Generate keypair and container image for unit and integration tests | |||
|
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 think it might be worth adding some more instructions here, for example getting the user to log into their container registry then set a shell variable to their user account. e.g. export cr_user="<your container reg account>
then updating the skopeo commands to replace user
with cr_user
.
I'm not sure if this is supposed to support more that just Docker Hub either?
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.
Yes, we can add more detail info for the setup. It should support different registries, I tried with a local registry and Docker Hub, encrypted container image both works, but the server side may change the dest-compress-format
.
data/generate_test_data.md
Outdated
@@ -0,0 +1,16 @@ | |||
## Generate keypair and container image for unit and integration tests |
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 wonder if it is worth linking this file on the main README.md as part of a set up guide as it's easy to miss?
Signed-off-by: Arron Wang <[email protected]>
Hi @stevenhorsman, Thanks for your try, I just added the keyprovider config to the repo and the CI passed: BTW for |
Thanks for the info - and adding the GHA CI output link. I'm seeing better behaviour locally now, but still not quite right.
but if I run all the tests it fails (differently from before):
I tried single threading the tests to see if that helped, but it still failed, so it doesn't look like it was a synchronous issue. It is super late for you, so I'm not expecting anything now, I just wanted to share what I saw. Thanks! |
Most code is still assuming Linux. We may need a plan to support other OS . |
Sorry, I wasn't clear - this result in on my Ubuntu 20.04 system, not macOS |
Yes, we can add other OS support to the TODO list and add this info to the README |
The root cause maybe
I updated to use tempdir for the work dir, it works with multiple times cargo test now. |
It would be better to use |
Yes, we use |
Thanks for the changed. Just to confirm that I can run |
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.
General comments. Looks good overall.
src/pull.rs
Outdated
let mut media_type_str: &str = layer.media_type.as_str(); | ||
|
||
let mut decryptor = Decryptor::default(); | ||
if decryptor.is_encrypted(&layer.media_type) { |
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.
One of the issues we ran into with skopeo
was that if a decryption key was provided but the image was not encrypted, the image would be unpacked anyway. For CCv0 this meant that if the CSP intercepted an encrypted image and replaced it with an unencrypted image, skopeo
would unpack the unencrypted image inside the enclave without warning the user.
Does image-rs
do something similar? Here it looks like the format of the image determines whether the image is decrypted or not. Do we check whether or not encryption is expected from by the client?
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.
Yes, current PR for image-rs
do the same way as skopeo
, and after we pulled the image, we will return the image and layer metadata info like whether the image is signed and layer is encrypted.
The next step work for integrating signature
crate which also provide the policy info, we will do these verifications to ensure the image/layer info is comply with the policy.
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, let's just make sure we enforce the guest owner's policy at some point, even for unsigned 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.
small comment:
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 @arronwy. A few comments...
command: build | ||
args: --all-features | ||
|
||
- name: Run cargo test with root privilege |
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 is root needed?
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.
The snapshots module will do mount operation which require the root privilege.
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'd add a comment to make that clear. Also, is it worth running the unit tests twice as we do in Kata, once as root and once as non-root? That would allow you to assert that the mount tests (correctly) failed when not running as root for example.
#[derive(Clone, Debug, Deserialize)] | ||
pub struct ImageConfig { | ||
/// The location for `image-rs` to store data. | ||
pub work_dir: PathBuf, |
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.
- Should this path exist or will it be created?
- Should it be an absolute path or can it be relative?
- Are sym links allowed?
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.
work_dir
will be created if not existed, it can be relative or sym links, we did not enforce any policy or check for this directory.
src/config.rs
Outdated
// Construct a default instance of `ImageConfig` | ||
fn default() -> ImageConfig { | ||
let work_dir = PathBuf::from( | ||
std::env::var("IMAGE_WORK_DIR").unwrap_or_else(|_| DEFAULT_WORK_DIR.to_string()), |
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 is this needed / who uses this variable? Is it for testing / debug only?
- This looks potentially dangerous as no validation is being done on this env var value.
- The name of the variable is rather generic. If this is really needed what about prefixing with
CC_
orCONFIDENTIAL_CONTAINERS_
?
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.
This variable allow the user to easy set the work dir without create the config file.
Prefix with CC_
will be much better.
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.
Most of my comments are minor. This PR is very well laid out and easy to review, thanks a lot
@arronwy.
One overall comment: Could you please add some more detailed commit messages?
.map_err(|e| anyhow!("failed to open metastore file {}", e.to_string()))?; | ||
serde_json::from_reader::<File, MetaStore>(file) | ||
.map_err(|e| anyhow!("failed to parse metastore file {}", e.to_string())) | ||
} |
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.
How do we store/serialize the store?
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.
This will be in to todo list since current API only cover pull_image
API.
image: &str, | ||
bundle_dir: &Path, | ||
auth_info: &Option<&str>, | ||
decrypt_config: &Option<&str>, |
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.
Here again, this unstructured decrypt_config
argument is very opaque. What kind of strings are we expecting here?
Signed-off-by: Samuel Ortiz <[email protected]>
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 @sameo @jodh-intel for your reviewing. I'll add more detailed commit message and resolve all your comments.
command: build | ||
args: --all-features | ||
|
||
- name: Run cargo test with root privilege |
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.
The snapshots module will do mount operation which require the root privilege.
use tempfile; | ||
|
||
#[test] | ||
fn test_unpack() { |
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.
Given the comments about the current limitations of tar-rs
, shouldn't this also test sym-links? Also, what about other file types like char+block devices? I'm just wondering if we need tests for those here or can we rely on tar-rs
for those tests?
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.
The reason we did not test sym-links is current tar-rs
crate packing feature will not preserve the file time info, we may need a sepeate tool to crate the test file, I have add it as TODO for sym-links and other file types.
Current support gzip and zstd compression algorithm type. Signed-off-by: Arron Wang <[email protected]>
Unpack module will unpack contents of tarball to the destination path. Signed-off-by: Arron Wang <[email protected]>
@jodh-intel @stevenhorsman If you're ok with that new version, I think we could merge it. |
The decrypt module will use https://github.com/containers/ocicrypt-rs project to parse/retrive decrypt key and decrypt the data. Signed-off-by: Arron Wang <[email protected]>
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 @arronwy. A few nits and a small bug (I think)...
Provide the API to create bundle runtime config file which mainly add the config from container images: https://github.com/opencontainers/image-spec/blob/main/specs-go/v1/config.go to the annotation part of container runtime spec: https://github.com/opencontainers/runtime-spec/blob/main/specs-go/config.go Signed-off-by: Arron Wang <[email protected]>
Current we implement overlay snapshot as the default type. Signed-off-by: Arron Wang <[email protected]>
Signed-off-by: Arron Wang <[email protected]>
pull module will export the API to pull container image manifest, config and layers. it utilize oci-distribution crate to handle the real download process. Signed-off-by: Arron Wang <[email protected]>
Signed-off-by: Arron Wang <[email protected]>
The image module will provide CRI image service compatiable API, currently we implemented pull_image API. The unit test will focuse on different container registries to ensure the compalitibility with remote registries. Signed-off-by: Arron Wang <[email protected]>
Currently we use a hashmap to store the container image related metadata info, we may switch to a light database if needed. Signed-off-by: Arron Wang <[email protected]>
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 @arronwy.
lgtm
This PR implements image-rs basic features including OCI image download/decryption/decompression/unpack/mount.
Image signing verification is not included.