genpolicy: inspect layers under guest-pull

Always parse passwd and group data from image layers when building
genpolicy container metadata, even when guest-pull is enabled.

This lets the policy derive UID, GID, and supplemental groups from
the image instead of preserving host-visible fallback values.

Refresh the affected golden policy outputs for the new identity data.

Signed-off-by: Manuel Huber <manuelh@nvidia.com>
Assisted-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Manuel Huber
2026-06-02 22:15:16 +00:00
parent 31d349f999
commit 493ecccc43
10 changed files with 97 additions and 107 deletions

View File

@@ -690,11 +690,9 @@ struct TopologySpreadConstraint {
}
impl Container {
pub async fn init(&mut self, config: &Config, is_pause_container: bool) {
pub async fn init(&mut self, config: &Config) {
// Load container image properties from the registry.
self.registry = registry::get_container(config, &self.image, is_pause_container)
.await
.unwrap();
self.registry = registry::get_container(config, &self.image).await.unwrap();
}
pub fn get_env_variables(
@@ -1267,8 +1265,7 @@ pub async fn add_pause_container(containers: &mut Vec<Container>, config: &Confi
}),
..Default::default()
};
let is_pause_container = true;
pause_container.init(config, is_pause_container).await;
pause_container.init(config).await;
containers.insert(0, pause_container);
debug!("pause container added.");
}

View File

@@ -125,7 +125,7 @@ const GROUP_FILE_WHITEOUT_TAR_PATH: &str = "etc/.wh.group";
pub const WHITEOUT_MARKER: &str = "WHITEOUT";
impl Container {
pub async fn new(config: &Config, image: &str, is_pause_container: bool) -> Result<Self> {
pub async fn new(config: &Config, image: &str) -> Result<Self> {
info!("============================================");
info!("Pulling manifest and config for {image}");
let image_string = image.to_string();
@@ -166,38 +166,31 @@ impl Container {
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
let v1_policy = config.settings.cluster_config.pause_container_id_policy == "v1";
if config.settings.cluster_config.guest_pull && (v1_policy || !is_pause_container) {
info!("Guest pull is enabled, skipping passwd/group file parsing");
} else {
let image_layers = get_image_layers(
&config.layers_cache,
&mut client,
&reference,
&manifest,
&config_layer,
)
.await
.unwrap();
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();
debug!("Container:new: Found in image layer passwd = \n{passwd}");
}
// 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();
debug!("Container:new: Found in image layer passwd = \n{passwd}");
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
debug!("Container:new: Found in image layer group = \n{group}");
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
debug!("Container:new: Found in image layer group = \n{group}");
}
}
@@ -652,16 +645,11 @@ pub fn get_users_from_decompressed_layer(path: &Path) -> Result<(String, String)
Ok((passwd, group))
}
pub async fn get_container(
config: &Config,
image: &str,
is_pause_container: bool,
) -> Result<Container> {
pub async fn get_container(config: &Config, image: &str) -> Result<Container> {
if let Some(socket_path) = &config.containerd_socket_path {
return Container::new_containerd_pull(config, image, socket_path, is_pause_container)
.await;
return Container::new_containerd_pull(config, image, socket_path).await;
}
Container::new(config, image, is_pause_container).await
Container::new(config, image).await
}
fn build_auth(reference: &Reference) -> RegistryAuth {

View File

@@ -32,7 +32,6 @@ impl Container {
config: &Config,
image: &str,
containerd_socket_path: &str,
is_pause_container: bool,
) -> Result<Self> {
info!("============================================");
info!("Using containerd socket: {:?}", containerd_socket_path);
@@ -69,31 +68,24 @@ impl Container {
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
let v1_policy = config.settings.cluster_config.pause_container_id_policy == "v1";
if config.settings.cluster_config.guest_pull && (v1_policy || !is_pause_container) {
info!("Guest pull is enabled, skipping passwd/group file parsing");
} else {
let image_layers =
get_image_layers(&config.layers_cache, &manifest, &config_layer, &ctrd_client)
.await
.unwrap();
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();
}
// 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();
}
if layer.group == WHITEOUT_MARKER {
group = String::new();
} else if !layer.group.is_empty() {
group = layer.group.clone();
}
}

View File

@@ -278,8 +278,7 @@ pub fn get_yaml_header(yaml: &str) -> anyhow::Result<YamlHeader> {
pub async fn k8s_resource_init(spec: &mut pod::PodSpec, config: &Config) {
for container in &mut spec.containers {
let is_pause_container = false;
container.init(config, is_pause_container).await;
container.init(config).await;
}
pod::add_pause_container(&mut spec.containers, config).await;
@@ -287,8 +286,7 @@ pub async fn k8s_resource_init(spec: &mut pod::PodSpec, config: &Config) {
if let Some(init_containers) = &spec.initContainers {
for container in init_containers {
let mut new_container = container.clone();
let is_pause_container = false;
new_container.init(config, is_pause_container).await;
new_container.init(config).await;
spec.containers.insert(1, new_container);
}
}

View File

@@ -295,10 +295,10 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},
@@ -629,10 +629,10 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},

View File

@@ -286,10 +286,10 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},
@@ -612,10 +612,10 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},

View File

@@ -293,10 +293,10 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},
@@ -628,8 +628,8 @@
"AdditionalGids": [
0
],
"GID": 0,
"UID": 0,
"GID": 1,
"UID": 2,
"Username": ""
}
},

View File

@@ -108,9 +108,9 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
1000
],
"GID": 0,
"GID": 1000,
"UID": 1000,
"Username": ""
}

View File

@@ -278,7 +278,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -581,7 +582,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -630,7 +632,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -665,7 +668,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -700,7 +704,8 @@
"Terminal": true,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -743,7 +748,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -778,7 +784,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -813,7 +820,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -883,7 +891,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -918,7 +927,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -1041,7 +1051,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -1076,7 +1087,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -1120,7 +1132,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,

View File

@@ -294,7 +294,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,
@@ -367,7 +368,8 @@
"Terminal": false,
"User": {
"AdditionalGids": [
0
0,
10
],
"GID": 0,
"UID": 0,