summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2021-06-19 11:00:24 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2021-06-19 14:13:42 +0200
commit204acf18eccd6c3a4dfd6320e9c24bd7c4427d2f (patch)
tree650e384b1c46d130f0b39a3df92c7bb696e365ea /src
parent13f69b021e8e96f6b2e0b3fbd9cbc4b476bb6c59 (diff)
downloadrebel-204acf18eccd6c3a4dfd6320e9c24bd7c4427d2f.tar
rebel-204acf18eccd6c3a4dfd6320e9c24bd7c4427d2f.zip
util: add tar unpack helper
Diffstat (limited to 'src')
-rw-r--r--src/runner/runc/init.rs33
-rw-r--r--src/util.rs2
-rw-r--r--src/util/tar.rs35
3 files changed, 39 insertions, 31 deletions
diff --git a/src/runner/runc/init.rs b/src/runner/runc/init.rs
index 658b318..e574789 100644
--- a/src/runner/runc/init.rs
+++ b/src/runner/runc/init.rs
@@ -1,9 +1,6 @@
use std::{
- ffi::CString,
fs::{DirBuilder, File},
io,
- os::unix::ffi::OsStrExt,
- path::Path,
};
use nix::{
@@ -12,7 +9,7 @@ use nix::{
};
use serde::{Deserialize, Serialize};
-use crate::util::ToIOResult;
+use crate::util::{self, ToIOResult};
fn prepare_buildtmp() -> io::Result<()> {
mount::mount::<_, _, _, str>(
@@ -24,33 +21,7 @@ fn prepare_buildtmp() -> io::Result<()> {
)
.to_io_result()?;
- DirBuilder::new().create("build/tmp/rootfs")?;
-
- {
- let file = File::open("build/rootfs.tar")?;
- let mut archive = tar::Archive::new(file);
- archive.set_preserve_permissions(true);
- archive.set_preserve_mtime(true);
- archive.set_unpack_xattrs(true);
-
- let dst = Path::new("build/tmp/rootfs");
-
- for entry_r in archive.entries()? {
- let mut entry = entry_r?;
- if entry.unpack_in(dst)? {
- let header = entry.header();
- let uid = header.uid()? as libc::uid_t;
- let gid = header.gid()? as libc::gid_t;
-
- let path = CString::new(dst.join(entry.path()?).as_os_str().as_bytes())
- .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
- if unsafe { libc::lchown(path.as_ptr(), uid, gid) } < 0 {
- return Err(io::Error::last_os_error());
- }
- }
- }
- }
-
+ util::tar::unpack(File::open("build/rootfs.tar")?, "build/tmp/rootfs")?;
DirBuilder::new().create("build/tmp/runc")?;
Ok(())
diff --git a/src/util.rs b/src/util.rs
index cbbfb6a..f5bbfaa 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -1,3 +1,5 @@
+pub mod tar;
+
use std::{
io::{Error, ErrorKind, Result},
process::ExitStatus,
diff --git a/src/util/tar.rs b/src/util/tar.rs
new file mode 100644
index 0000000..07ad795
--- /dev/null
+++ b/src/util/tar.rs
@@ -0,0 +1,35 @@
+use std::{
+ ffi::CString,
+ fs::DirBuilder,
+ io::{self, Read},
+ os::unix::ffi::OsStrExt,
+ path::Path,
+};
+
+pub fn unpack<R: Read, P: AsRef<Path>>(archive: R, dest: P) -> io::Result<()> {
+ let dest_path = dest.as_ref();
+
+ DirBuilder::new().recursive(true).create(dest_path)?;
+
+ let mut ar = tar::Archive::new(archive);
+ ar.set_preserve_permissions(true);
+ ar.set_preserve_mtime(true);
+ ar.set_unpack_xattrs(true);
+
+ for entry_r in ar.entries()? {
+ let mut entry = entry_r?;
+ if entry.unpack_in(dest_path)? {
+ let header = entry.header();
+ let uid = header.uid()? as libc::uid_t;
+ let gid = header.gid()? as libc::gid_t;
+
+ let path = CString::new(dest_path.join(entry.path()?).as_os_str().as_bytes())
+ .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+ if unsafe { libc::lchown(path.as_ptr(), uid, gid) } < 0 {
+ return Err(io::Error::last_os_error());
+ }
+ }
+ }
+
+ Ok(())
+}