genpolicy: skip pulling layers for guest-pull

Skip pulling container image layers when guest-pull=true. The contents
of these layers were ignored due to:
- #11162, and
- tarfs snapshotter support having been removed from genpolicy.

Signed-off-by: Dan Mihai <dmihai@microsoft.com>
This commit is contained in:
Dan Mihai
2025-07-11 15:24:13 +00:00
parent f6016f4f36
commit 94995d7102
2 changed files with 104 additions and 79 deletions

View File

@@ -138,65 +138,11 @@ impl Container {
..Default::default() ..Default::default()
}); });
match client.pull_manifest_and_config(&reference, &auth).await { let (manifest, digest_hash, config_layer_str) = match client
Ok((manifest, digest_hash, config_layer_str)) => { .pull_manifest_and_config(&reference, &auth)
debug!("digest_hash: {:?}", digest_hash); .await
debug!( {
"manifest: {}", Ok((m, d, c)) => (m, d, c),
serde_json::to_string_pretty(&manifest).unwrap()
);
// Log the contents of the config layer.
if log::max_level() >= LevelFilter::Debug {
let mut deserializer = serde_json::Deserializer::from_str(&config_layer_str);
let mut serializer = serde_json::Serializer::pretty(io::stderr());
serde_transcode::transcode(&mut deserializer, &mut serializer).unwrap();
}
let config_layer: DockerConfigLayer =
serde_json::from_str(&config_layer_str).unwrap();
debug!("config_layer: {:?}", &config_layer);
let image_layers = get_image_layers(
&config.layers_cache,
&mut client,
&reference,
&manifest,
&config_layer,
)
.await
.unwrap();
// Find the last layer with an /etc/* file, respecting whiteouts.
let mut passwd = String::new();
let mut group = String::new();
// Nydus/guest_pull doesn't make available passwd/group files from layers properly.
// See issue https://github.com/kata-containers/kata-containers/issues/11162
if !config.settings.cluster_config.guest_pull {
for layer in &image_layers {
if layer.passwd == WHITEOUT_MARKER {
passwd = String::new();
} else if !layer.passwd.is_empty() {
passwd = layer.passwd.clone();
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
}
}
} else {
info!("Guest pull is enabled, skipping passwd/group file parsing");
}
Ok(Container {
image: image_string,
config_layer,
passwd,
group,
})
}
Err(oci_client::errors::OciDistributionError::AuthenticationFailure(message)) => { Err(oci_client::errors::OciDistributionError::AuthenticationFailure(message)) => {
panic!("Container image registry authentication failure ({}). Are docker credentials set-up for current user?", &message); panic!("Container image registry authentication failure ({}). Are docker credentials set-up for current user?", &message);
} }
@@ -206,7 +152,70 @@ impl Container {
&e &e
); );
} }
};
debug!("digest_hash: {:?}", digest_hash);
debug!(
"manifest: {}",
serde_json::to_string_pretty(&manifest).unwrap()
);
if log::max_level() >= LevelFilter::Debug {
let mut deserializer = serde_json::Deserializer::from_str(&config_layer_str);
let mut serializer = serde_json::Serializer::pretty(io::stderr());
serde_transcode::transcode(&mut deserializer, &mut serializer).unwrap();
} }
let config_layer: DockerConfigLayer = serde_json::from_str(&config_layer_str).unwrap();
debug!("config_layer: {:?}", &config_layer);
let mut passwd = String::new();
let mut group = String::new();
// Nydus/guest_pull doesn't make available passwd/group files from layers properly.
// See issue https://github.com/kata-containers/kata-containers/issues/11162
if config.settings.cluster_config.guest_pull {
info!("Guest pull is enabled, skipping passwd/group file parsing");
return Ok(Container {
image: image_string,
config_layer,
passwd,
group,
});
}
let image_layers = get_image_layers(
&config.layers_cache,
&mut client,
&reference,
&manifest,
&config_layer,
)
.await
.unwrap();
// Find the last layer with an /etc/* file, respecting whiteouts.
info!("Parsing users and groups in image layers");
for layer in &image_layers {
if layer.passwd == WHITEOUT_MARKER {
passwd = String::new();
} else if !layer.passwd.is_empty() {
passwd = layer.passwd.clone();
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
}
}
Ok(Container {
image: image_string,
config_layer,
passwd,
group,
})
} }
pub fn get_gid_from_passwd_uid(&self, uid: u32) -> Result<u32> { pub fn get_gid_from_passwd_uid(&self, uid: u32) -> Result<u32> {

View File

@@ -51,39 +51,54 @@ impl Container {
let image_ref: Reference = image_str.parse().unwrap(); let image_ref: Reference = image_str.parse().unwrap();
info!("Pulling image: {:?}", image_ref); info!("Pulling image: {:?}", image_ref);
pull_image(&image_ref, k8_cri_image_client.clone()).await?; pull_image(&image_ref, k8_cri_image_client.clone()).await?;
let image_ref_str = &image_ref.to_string(); let image_ref_str = &image_ref.to_string();
let manifest = get_image_manifest(image_ref_str, &ctrd_client).await?; let manifest = get_image_manifest(image_ref_str, &ctrd_client).await?;
debug!(
"manifest: {}",
serde_json::to_string_pretty(&manifest).unwrap()
);
let config_layer = get_config_layer(image_ref_str, k8_cri_image_client) let config_layer = get_config_layer(image_ref_str, k8_cri_image_client)
.await .await
.unwrap(); .unwrap();
let image_layers = debug!("config_layer: {:?}", &config_layer);
get_image_layers(&config.layers_cache, &manifest, &config_layer, &ctrd_client).await?;
// Find the last layer with an /etc/* file, respecting whiteouts.
let mut passwd = String::new(); let mut passwd = String::new();
let mut group = String::new(); let mut group = String::new();
// Nydus/guest_pull doesn't make available passwd/group files from layers properly. // Nydus/guest_pull doesn't make available passwd/group files from layers properly.
// See issue https://github.com/kata-containers/kata-containers/issues/11162 // See issue https://github.com/kata-containers/kata-containers/issues/11162
if !config.settings.cluster_config.guest_pull { if config.settings.cluster_config.guest_pull {
for layer in &image_layers {
if layer.passwd == WHITEOUT_MARKER {
passwd = String::new();
} else if !layer.passwd.is_empty() {
passwd = layer.passwd.clone();
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
}
}
} else {
info!("Guest pull is enabled, skipping passwd/group file parsing"); info!("Guest pull is enabled, skipping passwd/group file parsing");
return Ok(Container {
image: image_str,
config_layer,
passwd,
group,
});
}
let image_layers =
get_image_layers(&config.layers_cache, &manifest, &config_layer, &ctrd_client)
.await
.unwrap();
// Find the last layer with an /etc/* file, respecting whiteouts.
info!("Parsing users and groups in image layers");
for layer in &image_layers {
if layer.passwd == WHITEOUT_MARKER {
passwd = String::new();
} else if !layer.passwd.is_empty() {
passwd = layer.passwd.clone();
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
}
} }
Ok(Container { Ok(Container {
@@ -94,6 +109,7 @@ impl Container {
}) })
} }
} }
pub async fn get_content( pub async fn get_content(
digest: &str, digest: &str,
client: &containerd_client::Client, client: &containerd_client::Client,