From 6371cb848bb953a4792a26ea967b17f1402c7d0f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 19 Jun 2021 22:51:01 +0200 Subject: tar: add files in sorted order --- examples/foo.yml | 4 ++++ src/runner/runc/run.rs | 2 +- src/util.rs | 2 +- src/util/tar.rs | 18 +++++++------- src/util/uid.rs | 44 ---------------------------------- src/util/unix.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 54 deletions(-) delete mode 100644 src/util/uid.rs create mode 100644 src/util/unix.rs 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, E: AsRef, I: Iterator>( archive: W, source: P, entries: I, -) -> io::Result { +) -> Result { + 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>(archive: R, dest: P) -> io::Result<()> { +pub fn unpack>(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/uid.rs deleted file mode 100644 index ee1e16b..0000000 --- a/src/util/uid.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::{fs::File, io::Result, path::Path}; - -use nix::unistd; - -use super::ToIOResult; - -pub struct SetEUID(unistd::Uid); - -impl Drop for SetEUID { - fn drop(&mut self) { - unistd::seteuid(self.0).expect("failed to reset effective UID"); - } -} - -pub fn seteuid(uid: unistd::Uid) -> Result { - let old_uid = unistd::geteuid(); - unistd::seteuid(uid).to_io_result()?; - Ok(SetEUID(old_uid)) -} - -pub struct SetEGID(unistd::Gid); - -impl Drop for SetEGID { - fn drop(&mut self) { - unistd::setegid(self.0).expect("failed to reset effective GID"); - } -} - -pub fn setegid(gid: unistd::Gid) -> Result { - let old_gid = unistd::getegid(); - unistd::setegid(gid).to_io_result()?; - Ok(SetEGID(old_gid)) -} - -pub fn create_as>( - path: P, - uid: Option, - gid: Option, -) -> Result { - let _setegid = gid.map(setegid).transpose()?; - let _seteuid = uid.map(seteuid).transpose()?; - - File::create(path) -} diff --git a/src/util/unix.rs b/src/util/unix.rs new file mode 100644 index 0000000..ee0507c --- /dev/null +++ b/src/util/unix.rs @@ -0,0 +1,65 @@ +use std::{fs::File, io::Result, os::unix::prelude::AsRawFd, path::Path}; + +use nix::{dir::Dir, fcntl::OFlag, sys::stat::Mode, unistd}; + +use super::ToIOResult; + +pub struct SetEUID(unistd::Uid); + +impl Drop for SetEUID { + fn drop(&mut self) { + unistd::seteuid(self.0).expect("failed to reset effective UID"); + } +} + +pub fn seteuid(uid: unistd::Uid) -> Result { + let old_uid = unistd::geteuid(); + unistd::seteuid(uid).to_io_result()?; + Ok(SetEUID(old_uid)) +} + +pub struct SetEGID(unistd::Gid); + +impl Drop for SetEGID { + fn drop(&mut self) { + unistd::setegid(self.0).expect("failed to reset effective GID"); + } +} + +pub fn setegid(gid: unistd::Gid) -> Result { + let old_gid = unistd::getegid(); + unistd::setegid(gid).to_io_result()?; + Ok(SetEGID(old_gid)) +} + +pub fn create_as>( + path: P, + uid: Option, + gid: Option, +) -> Result { + let _setegid = gid.map(setegid).transpose()?; + let _seteuid = uid.map(seteuid).transpose()?; + + 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>(path: P) -> Result { + 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)) +} -- cgit v1.2.3