mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-02 07:34:45 +08:00
test(podman): make rootful userns and cgroup checks pass
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
This commit is contained in:
@@ -16,6 +16,16 @@
|
||||
|
||||
use openshell_e2e::harness::sandbox::SandboxGuard;
|
||||
|
||||
const CGROUP_READ_POLICY: &str = r"version: 1
|
||||
filesystem_policy:
|
||||
include_workdir: true
|
||||
read_only: [/usr, /lib, /lib64, /proc, /etc, /sys/fs/cgroup]
|
||||
read_write: [/sandbox, /tmp, /dev/null]
|
||||
landlock:
|
||||
compatibility: best_effort
|
||||
network_policies: {}
|
||||
";
|
||||
|
||||
const CPU_REQUEST: &str = "500m";
|
||||
const MEMORY_REQUEST: &str = "512Mi";
|
||||
|
||||
@@ -39,9 +49,19 @@ async fn sandbox_resource_limits_are_enforced_via_cgroups() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut sandbox = SandboxGuard::create(&["--cpu", CPU_REQUEST, "--memory", MEMORY_REQUEST])
|
||||
.await
|
||||
.expect("sandbox create with resource limits should succeed");
|
||||
let policy = tempfile::NamedTempFile::new().expect("create cgroup read policy file");
|
||||
std::fs::write(policy.path(), CGROUP_READ_POLICY).expect("write cgroup read policy");
|
||||
let policy_path = policy.path().to_str().expect("policy path is UTF-8");
|
||||
let mut sandbox = SandboxGuard::create(&[
|
||||
"--cpu",
|
||||
CPU_REQUEST,
|
||||
"--memory",
|
||||
MEMORY_REQUEST,
|
||||
"--policy",
|
||||
policy_path,
|
||||
])
|
||||
.await
|
||||
.expect("sandbox create with resource limits should succeed");
|
||||
|
||||
let memory_max = sandbox
|
||||
.exec(&["cat", "/sys/fs/cgroup/memory.max"])
|
||||
|
||||
@@ -9,6 +9,18 @@
|
||||
- name: Wait for SSH
|
||||
ansible.builtin.wait_for_connection:
|
||||
|
||||
# Rootful Podman's --userns auto allocates IDs from the "containers"
|
||||
# subordinate ranges, which the Fedora cloud image does not define.
|
||||
- name: Configure rootful Podman subordinate IDs
|
||||
become: true
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item }}"
|
||||
regexp: '^containers:'
|
||||
line: 'containers:1000000:65536'
|
||||
loop:
|
||||
- /etc/subuid
|
||||
- /etc/subgid
|
||||
|
||||
- name: Enable rootful Podman socket
|
||||
become: true
|
||||
ansible.builtin.systemd_service:
|
||||
|
||||
@@ -86,16 +86,38 @@ async fn configured_userns_matches_podman_reference() {
|
||||
}
|
||||
|
||||
fn normalize_uid_map(value: &str) -> Option<String> {
|
||||
let mappings = value
|
||||
.lines()
|
||||
.filter_map(|line| {
|
||||
let fields = line.split_whitespace().collect::<Vec<_>>();
|
||||
(fields.len() == 3
|
||||
&& fields
|
||||
.iter()
|
||||
.all(|field| field.bytes().all(|byte| byte.is_ascii_digit())))
|
||||
.then(|| fields.join(" "))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
(!mappings.is_empty()).then(|| mappings.join("\n"))
|
||||
let mut mappings: Vec<(u64, u64, u64)> = Vec::new();
|
||||
for line in value.lines() {
|
||||
let fields = line
|
||||
.split_whitespace()
|
||||
.map(str::parse::<u64>)
|
||||
.collect::<Result<Vec<_>, _>>();
|
||||
let Ok(fields) = fields else { continue };
|
||||
let [inside, outside, length] = fields.as_slice() else {
|
||||
continue;
|
||||
};
|
||||
if let Some(previous) = mappings.last_mut()
|
||||
&& previous.0.checked_add(previous.2) == Some(*inside)
|
||||
&& previous.1.checked_add(previous.2) == Some(*outside)
|
||||
{
|
||||
previous.2 += *length;
|
||||
} else {
|
||||
mappings.push((*inside, *outside, *length));
|
||||
}
|
||||
}
|
||||
(!mappings.is_empty()).then(|| {
|
||||
mappings
|
||||
.iter()
|
||||
.map(|(inside, outside, length)| format!("{inside} {outside} {length}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adjacent_uid_ranges_match_a_combined_mapping() {
|
||||
assert_eq!(
|
||||
normalize_uid_map("0 0 1\n1 1 65535\n"),
|
||||
normalize_uid_map("0 0 65536\n")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user