summaryrefslogtreecommitdiffstats
path: root/src/runner/container/tar.rs
blob: 67993c1d2981aea9b7739d3c639636a303c5957c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use std::{
	io::{self, Read, Write},
	path::Path,
	process,
};

use nix::mount::MsFlags;

use crate::{
	paths,
	types::InputHash,
	util::{error::*, fs, Checkable},
};

use super::spec;

pub fn pack<W: Write, P: AsRef<Path>>(
	input_hash: &InputHash,
	archive: &mut W,
	source: P,
) -> Result<()> {
	let task_tmp_dir = paths::task_tmp_dir(input_hash);

	let rootfs_mount_target = paths::join(&[&task_tmp_dir, paths::TASK_TMP_ROOTFS_SUBDIR]);
	let _rootfs_mount = fs::mount(
		paths::ROOTFS_DIR,
		&rootfs_mount_target,
		None,
		MsFlags::MS_BIND,
		None,
	)?;

	let source_mount_target = paths::join(&[&task_tmp_dir, paths::TASK_WORKDIR]);
	let _source_mount = fs::mount(source, &source_mount_target, None, MsFlags::MS_BIND, None)?;

	spec::generate_spec(&[
		"tar",
		"-c",
		"--sort=name",
		"--numeric-owner",
		"--owner=0",
		"--group=0",
		"--mtime=@0",
		".",
	])
	.save(paths::join(&[&task_tmp_dir, "config.json"]))
	.map_err(Error::new)
	.context("Failed to save runtime config")?;

	let mut child = process::Command::new("crun")
		.arg("--root")
		.arg(paths::TASK_TMP_CONTAINERS_ROOT_SUBDIR)
		.arg("run")
		.arg(input_hash.to_string())
		.current_dir(task_tmp_dir)
		.stdin(process::Stdio::null())
		.stdout(process::Stdio::piped())
		.spawn()
		.context("Failed to start container runtime")?;

	io::copy(&mut child.stdout.take().unwrap(), archive).context("Failed to write TAR archive")?;

	child.wait()?.check()?;

	Ok(())
}

pub fn unpack<R: Read, P: AsRef<Path>>(archive: R, dest: P) -> Result<()> {
	fs::mkdir(&dest)?;

	let mut ar = tar::Archive::new(archive);
	ar.set_preserve_permissions(true);
	ar.set_preserve_mtime(true);
	ar.set_unpack_xattrs(true);
	ar.set_overwrite(false);

	ar.unpack(dest).context("Failed to unpack TAR archive")
}