diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-06-19 22:51:01 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-06-19 23:11:37 +0200 |
commit | 6371cb848bb953a4792a26ea967b17f1402c7d0f (patch) | |
tree | 8c659d05b434920379606bfc63d596f6d5e48a64 | |
parent | cab6abe0c28d3702ad8f4319bc00e2eca00479f2 (diff) | |
download | rebel-6371cb848bb953a4792a26ea967b17f1402c7d0f.tar rebel-6371cb848bb953a4792a26ea967b17f1402c7d0f.zip |
tar: add files in sorted order
-rw-r--r-- | examples/foo.yml | 4 | ||||
-rw-r--r-- | src/runner/runc/run.rs | 2 | ||||
-rw-r--r-- | src/util.rs | 2 | ||||
-rw-r--r-- | src/util/tar.rs | 18 | ||||
-rw-r--r-- | src/util/unix.rs (renamed from src/util/uid.rs) | 25 |
5 files changed, 39 insertions, 12 deletions
diff --git a/examples/foo.yml b/examples/foo.yml index 6f60bbb..a3696fe 100644 --- a/examples/foo.yml +++ b/examples/foo.yml @@ -7,3 +7,7 @@ tasks: ls -lha /proc/self/fd mkdir foo echo foobar > foo/bar + touch foo/bla + touch foo/x + touch foo/z + touch foo/y diff --git a/src/runner/runc/run.rs b/src/runner/runc/run.rs index 5d01908..3fe51e1 100644 --- a/src/runner/runc/run.rs +++ b/src/runner/runc/run.rs @@ -68,7 +68,7 @@ fn output_filename(task: TaskRef) -> PathBuf { } fn collect_output(task: TaskRef, task_def: Task) -> Result<(), io::Error> { - let file = util::uid::create_as( + let file = util::unix::create_as( output_filename(task), Some(unshare::BUILD_UID), Some(unshare::BUILD_GID), diff --git a/src/util.rs b/src/util.rs index 746d5d7..0dbee5b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,6 @@ pub mod ipc; pub mod tar; -pub mod uid; +pub mod unix; use std::{ io::{Error, ErrorKind, Result}, diff --git a/src/util/tar.rs b/src/util/tar.rs index 885663e..1014abc 100644 --- a/src/util/tar.rs +++ b/src/util/tar.rs @@ -1,33 +1,35 @@ use std::{ ffi::CString, fs::DirBuilder, - io::{self, Read, Write}, + io::{self, Read, Result, Write}, os::unix::ffi::OsStrExt, path::Path, }; +use walkdir::WalkDir; + +use super::unix; pub fn pack<W: Write, P: AsRef<Path>, E: AsRef<Path>, I: Iterator<Item = E>>( archive: W, source: P, entries: I, -) -> io::Result<W> { +) -> Result<W> { + let _chdir = unix::chdir(source)?; + let mut ar = tar::Builder::new(archive); ar.mode(tar::HeaderMode::Deterministic); ar.follow_symlinks(false); for entry in entries { - let path = source.as_ref().join(entry.as_ref()); - if path.is_dir() { - ar.append_dir_all(entry.as_ref(), path)?; - } else { - ar.append_path_with_name(path, entry.as_ref())?; + for dir_entry in WalkDir::new(entry).sort_by_file_name() { + ar.append_path(dir_entry?.path())?; } } ar.into_inner() } -pub fn unpack<R: Read, P: AsRef<Path>>(archive: R, dest: P) -> io::Result<()> { +pub fn unpack<R: Read, P: AsRef<Path>>(archive: R, dest: P) -> Result<()> { let dest_path = dest.as_ref(); DirBuilder::new().recursive(true).create(dest_path)?; diff --git a/src/util/uid.rs b/src/util/unix.rs index ee1e16b..ee0507c 100644 --- a/src/util/uid.rs +++ b/src/util/unix.rs @@ -1,6 +1,6 @@ -use std::{fs::File, io::Result, path::Path}; +use std::{fs::File, io::Result, os::unix::prelude::AsRawFd, path::Path}; -use nix::unistd; +use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode, unistd}; use super::ToIOResult; @@ -42,3 +42,24 @@ pub fn create_as<P: AsRef<Path>>( File::create(path) } + +pub struct Chdir(Dir); + +impl Drop for Chdir { + fn drop(&mut self) { + unistd::fchdir(self.0.as_raw_fd()).expect("failed to revert directory change"); + } +} + +pub fn chdir<P: AsRef<Path>>(path: P) -> Result<Chdir> { + let dir = Dir::open( + ".", + OFlag::O_PATH | OFlag::O_CLOEXEC | OFlag::O_NOFOLLOW, + Mode::empty(), + ) + .to_io_result()?; + + unistd::chdir(path.as_ref()).to_io_result()?; + + Ok(Chdir(dir)) +} |