Skip to content

Commit bb30f54

Browse files
committed
Add support for Docker
Signed-off-by: Michal Jura <[email protected]> (cherry picked from commit 2dcad30)
1 parent 1ca0aef commit bb30f54

File tree

1 file changed

+80
-5
lines changed

1 file changed

+80
-5
lines changed

lockc/src/bin/lockc-runc-wrapper.rs

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static ANNOTATION_CONTAINERD_LOG_DIRECTORY: &str = "io.kubernetes.cri.sandbox-lo
1818
static ANNOTATION_CONTAINERD_SANDBOX_ID: &str = "io.kubernetes.cri.sandbox-id";
1919

2020
#[derive(thiserror::Error, Debug)]
21-
enum ContainerNamespaceError {
21+
enum ContainerError {
2222
#[error("could not retrieve the runc status")]
2323
Status(#[from] std::io::Error),
2424

@@ -37,7 +37,7 @@ enum ContainerNamespaceError {
3737

3838
fn container_namespace<P: AsRef<std::path::Path>>(
3939
container_bundle: P,
40-
) -> Result<Option<std::string::String>, ContainerNamespaceError> {
40+
) -> Result<Option<std::string::String>, ContainerError> {
4141
let bundle_path = container_bundle.as_ref();
4242
let config_path = bundle_path.join("config.json");
4343
let f = std::fs::File::open(config_path)?;
@@ -79,7 +79,7 @@ fn container_namespace<P: AsRef<std::path::Path>>(
7979
let new_bundle = v.join(sandbox_id);
8080
return container_namespace(new_bundle);
8181
}
82-
None => return Err(ContainerNamespaceError::BundleDirError),
82+
None => return Err(ContainerError::BundleDirError),
8383
}
8484
}
8585
Ok(None)
@@ -132,6 +132,72 @@ async fn policy_label(
132132
}
133133
}
134134

135+
use serde::Deserialize;
136+
137+
#[derive(Debug, Deserialize)]
138+
#[serde(rename_all = "camelCase")]
139+
struct Mount {
140+
destination: String,
141+
r#type: String,
142+
source: String,
143+
options: Vec<String>
144+
}
145+
146+
#[derive(Debug, Deserialize)]
147+
#[serde(rename_all = "camelCase")]
148+
struct Mounts {
149+
mounts: Vec<Mount>
150+
}
151+
152+
fn docker_config<P: AsRef<std::path::Path>>(
153+
container_bundle: P,
154+
) -> Result<std::path::PathBuf, ContainerError> {
155+
let bundle_path = container_bundle.as_ref();
156+
let config_path = bundle_path.join("config.json");
157+
let f = std::fs::File::open(config_path)?;
158+
let r = std::io::BufReader::new(f);
159+
160+
let m: Mounts = serde_json::from_reader(r)?;
161+
162+
for test in m.mounts {
163+
let source: Vec<&str> = test.source.split('/').collect();
164+
if source.len() > 1 && source[ source.len() - 1 ] == "hostname" {
165+
let config_v2= str::replace(&test.source, "hostname", "config.v2.json");
166+
return Ok(std::path::PathBuf::from(config_v2));
167+
}
168+
}
169+
170+
Err(ContainerError::BundleDirError)
171+
}
172+
173+
use serde_json::Value;
174+
175+
fn docker_label<P: AsRef<std::path::Path>>(
176+
docker_bundle: P,
177+
) -> Result<lockc::bpfstructs::container_policy_level, ContainerError> {
178+
let config_path = docker_bundle.as_ref();
179+
let f = std::fs::File::open(config_path)?;
180+
let r = std::io::BufReader::new(f);
181+
182+
let l: Value = serde_json::from_reader(r)?;
183+
184+
let x = l["Config"]["Labels"]["org.lockc.policy"].as_str();
185+
186+
match x {
187+
Some(x) => match x {
188+
"restricted" => {
189+
Ok(lockc::bpfstructs::container_policy_level_POLICY_LEVEL_RESTRICTED)
190+
}
191+
"baseline" => Ok(lockc::bpfstructs::container_policy_level_POLICY_LEVEL_BASELINE),
192+
"privileged" => {
193+
Ok(lockc::bpfstructs::container_policy_level_POLICY_LEVEL_PRIVILEGED)
194+
}
195+
_ => Ok(lockc::bpfstructs::container_policy_level_POLICY_LEVEL_BASELINE)
196+
}
197+
None => Ok(lockc::bpfstructs::container_policy_level_POLICY_LEVEL_BASELINE),
198+
}
199+
}
200+
135201
/// Types of options (prepositioned by `--`).
136202
enum OptParsingAction {
137203
/// Option not followed by a positional argument.
@@ -315,8 +381,17 @@ async fn main() -> anyhow::Result<()> {
315381
Some(v) => std::path::PathBuf::from(v),
316382
None => std::env::current_dir()?,
317383
};
318-
let namespace = container_namespace(container_bundle)?;
319-
let policy = policy_label(namespace).await?;
384+
385+
let mut policy = lockc::bpfstructs::container_policy_level_POLICY_LEVEL_BASELINE;
386+
let runc_bundle = container_bundle.clone();
387+
let namespace = container_namespace(container_bundle);
388+
match namespace {
389+
Ok(n) => policy = policy_label(n).await?,
390+
Err(_) => {
391+
let docker_conf = docker_config(runc_bundle)?;
392+
policy = docker_label(docker_conf)?;
393+
}
394+
};
320395
lockc::add_container(container_key, pid_u, policy)?;
321396
cmd.status().await?;
322397
}

0 commit comments

Comments
 (0)