Increased log coverage and refactored error
module
- Error logging is now present in pacwrap-agent - Agent error code handling now correctly traps runtime panics. - impl of DisplayTrait for TransactionError no longer handles the display of transaction failure messages. - Error handling for TransactionAggregation is split into three categories: Fatal, Error, and Non-Fatal Error. While two former are immediately trapped and the program is terminated, the latter can safely terminate the program without consequence.
This commit is contained in:
parent
2f45f12b3e
commit
8191764098
12 changed files with 169 additions and 120 deletions
|
@ -29,6 +29,7 @@ use pacwrap_core::{
|
|||
config::Global,
|
||||
constants::{VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH},
|
||||
err,
|
||||
log::{Level, Logger},
|
||||
sync::{
|
||||
self,
|
||||
event::{
|
||||
|
@ -77,16 +78,23 @@ pub fn transact() -> Result<()> {
|
|||
let (transflags, ..) = handle.metadata().retrieve_flags();
|
||||
let alpm = sync::instantiate_alpm_agent(&config, &alpm_remotes, &transflags.expect("TransactionFlags"));
|
||||
let mut handle = handle.alpm_handle(alpm).config(&config).agent();
|
||||
let mut logger = Logger::new("pacwrap-agent").location("/mnt/share/pacwrap.log")?;
|
||||
|
||||
if let Err(err) = conduct_transaction(&config, &mut handle, params) {
|
||||
if let Err(err) = conduct_transaction(&config, &mut logger, &mut handle, params) {
|
||||
handle.release();
|
||||
logger.log(Level::Error, &format!("Transaction Error: {}", err))?;
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: TransactionParameters) -> Result<()> {
|
||||
fn conduct_transaction(
|
||||
config: &Global,
|
||||
logger: &mut Logger,
|
||||
handle: &mut TransactionHandle,
|
||||
agent: TransactionParameters,
|
||||
) -> Result<()> {
|
||||
let flags = handle.metadata().retrieve_flags();
|
||||
let mode = agent.mode();
|
||||
let action = agent.action();
|
||||
|
@ -95,7 +103,7 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
let bytes = agent.bytes();
|
||||
let files = agent.files();
|
||||
|
||||
if let Err(error) = handle.alpm_mut().trans_init(flags.1.unwrap()) {
|
||||
if let Err(error) = handle.alpm_mut().trans_init(flags.1.expect("ALPM TransFlag")) {
|
||||
err!(SyncError::InitializationFailure(error.to_string()))?
|
||||
}
|
||||
|
||||
|
@ -103,11 +111,11 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
|
||||
if let TransactionType::Upgrade(upgrade, downgrade, _) = action {
|
||||
if upgrade {
|
||||
handle.alpm().sync_sysupgrade(downgrade).unwrap();
|
||||
handle.alpm().sync_sysupgrade(downgrade).expect("ALPM sync_sysupgrade")
|
||||
}
|
||||
}
|
||||
|
||||
handle.prepare(&action, &flags.0.unwrap())?;
|
||||
handle.prepare(&action, &flags.0.expect("TransactionFlags"))?;
|
||||
|
||||
if let Err(error) = handle.alpm_mut().trans_prepare() {
|
||||
erroneous_preparation(error)?
|
||||
|
@ -124,12 +132,15 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
erroneous_transaction(error)?
|
||||
}
|
||||
|
||||
handle.alpm_mut().trans_release().unwrap();
|
||||
handle.alpm_mut().trans_release().expect("ALPM trans_release");
|
||||
handle.mark_depends();
|
||||
|
||||
if let Err(error) = fs::copy("/etc/ld.so.cache", "/mnt/fs/etc/ld.so.cache") {
|
||||
if error.kind() != NotFound {
|
||||
print_warning(&format!("Failed to propagate ld.so.cache: {}", error));
|
||||
let message = &format!("Failed to propagate ld.so.cache: {}", error);
|
||||
|
||||
print_warning(message);
|
||||
logger.log(Level::Warn, message)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ use signal_hook::consts::*;
|
|||
|
||||
use crate::{
|
||||
error,
|
||||
utils::{ansi::*, unix_time_as_seconds},
|
||||
utils::{ansi::*, unix_epoch_time},
|
||||
Error,
|
||||
ErrorKind,
|
||||
};
|
||||
|
@ -83,7 +83,7 @@ lazy_static! {
|
|||
pub static ref DBUS_SOCKET: String = format!("/run/user/{}/pacwrap_dbus_{}", *UID, &id());
|
||||
pub static ref WAYLAND_SOCKET: String = format!("{}{}", *XDG_RUNTIME_DIR, *WAYLAND_DISPLAY);
|
||||
pub static ref LOG_LOCATION: &'static str = format_str!("{}/pacwrap.log", *DATA_DIR);
|
||||
pub static ref UNIX_TIMESTAMP: u64 = unix_time_as_seconds();
|
||||
pub static ref UNIX_TIMESTAMP: u64 = unix_epoch_time().as_secs();
|
||||
pub static ref IS_COLOR_TERMINAL: bool = is_color_terminal();
|
||||
pub static ref IS_TRUECOLOR_TERMINLAL: bool = is_truecolor_terminal();
|
||||
pub static ref BOLD: &'static str = bold();
|
||||
|
|
|
@ -121,6 +121,12 @@ impl Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(f, "{}", self.kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ErrorType<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
|
||||
match self {
|
||||
|
|
|
@ -49,7 +49,7 @@ use crate::{
|
|||
seccomp::{provide_bpf_program, FilterType::*},
|
||||
utils::{agent_params, decode_info_json, wait_on_fakeroot, wait_on_process},
|
||||
},
|
||||
sync::transaction::{TransactionMetadata, TransactionParameters},
|
||||
sync::transaction::{TransactionFlags, TransactionMetadata, TransactionParameters},
|
||||
to_static_str,
|
||||
utils::TermControl,
|
||||
Error,
|
||||
|
@ -162,34 +162,34 @@ pub fn fakeroot_container(exec_type: ExecutionType, trap: Option<fn(i32)>, ins:
|
|||
.arg("--info-fd")
|
||||
.arg(info_fd.to_string());
|
||||
|
||||
if let ContainerType::Slice = ins.metadata().container_type() {
|
||||
process.arg("--dir").arg("/root")
|
||||
.arg("--ro-bind").arg(format!("{}/bin", *DIST_IMG)).arg("/mnt/fs/bin")
|
||||
.arg("--ro-bind").arg(format!("{}/lib", *DIST_IMG)).arg("/mnt/fs/lib64")
|
||||
.arg("--dir").arg("/mnt/fs/root") ;
|
||||
if let ContainerType::Slice = ins.metadata().container_type() {
|
||||
process.arg("--dir").arg("/root")
|
||||
.arg("--ro-bind").arg(format!("{}/bin", *DIST_IMG)).arg("/mnt/fs/bin")
|
||||
.arg("--ro-bind").arg(format!("{}/lib", *DIST_IMG)).arg("/mnt/fs/lib64")
|
||||
.arg("--dir").arg("/mnt/fs/root") ;
|
||||
|
||||
if arguments[0] == "ash" {
|
||||
process.arg("--hostname").arg("BusyBox")
|
||||
.arg("--setenv").arg("ENV").arg("/etc/profile")
|
||||
} else {
|
||||
process.arg("--hostname").arg("FakeChroot")
|
||||
.arg("fakeroot").arg("chroot").arg("/mnt/fs")
|
||||
}
|
||||
if arguments[0] == "ash" {
|
||||
process.arg("--hostname").arg("BusyBox")
|
||||
.arg("--setenv").arg("ENV").arg("/etc/profile")
|
||||
} else {
|
||||
process.arg("--hostname").arg("FakeChroot")
|
||||
.arg("--ro-bind").arg("/etc/resolv.conf").arg("/etc/resolv.conf")
|
||||
.arg("--bind").arg(ins.vars().pacman_gnupg()).arg("/mnt/fs/etc/pacman.d/gnupg")
|
||||
.arg("--bind").arg(ins.vars().pacman_cache()).arg("/mnt/fs/var/cache/pacman/pkg")
|
||||
.arg("--bind").arg(ins.vars().home()).arg("/mnt/fs/root")
|
||||
.arg("--setenv").arg("EUID").arg("0")
|
||||
.arg("--setenv").arg("PATH").arg(DEFAULT_PATH)
|
||||
.arg("fakeroot").arg("chroot").arg("/mnt/fs")
|
||||
};
|
||||
}
|
||||
} else {
|
||||
process.arg("--hostname").arg("FakeChroot")
|
||||
.arg("--ro-bind").arg("/etc/resolv.conf").arg("/etc/resolv.conf")
|
||||
.arg("--bind").arg(ins.vars().pacman_gnupg()).arg("/mnt/fs/etc/pacman.d/gnupg")
|
||||
.arg("--bind").arg(ins.vars().pacman_cache()).arg("/mnt/fs/var/cache/pacman/pkg")
|
||||
.arg("--bind").arg(ins.vars().home()).arg("/mnt/fs/root")
|
||||
.arg("--setenv").arg("EUID").arg("0")
|
||||
.arg("--setenv").arg("PATH").arg(DEFAULT_PATH)
|
||||
.arg("fakeroot").arg("chroot").arg("/mnt/fs")
|
||||
};
|
||||
|
||||
match process.args(arguments)
|
||||
.fd_mappings(fd_mappings)
|
||||
.unwrap()
|
||||
.spawn()
|
||||
match process.args(arguments)
|
||||
.fd_mappings(fd_mappings)
|
||||
.expect("FD Mappings")
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => wait_on_fakeroot(exec_type, child, term_control, decode_info_json(info_pipe)?, trap),
|
||||
Err(err) => err!(ErrorKind::ProcessInitFailure(BWRAP_EXECUTABLE, err.kind())),
|
||||
|
@ -197,30 +197,35 @@ pub fn fakeroot_container(exec_type: ExecutionType, trap: Option<fn(i32)>, ins:
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub fn transaction_agent(ins: &ContainerHandle, params: TransactionParameters, metadata: &TransactionMetadata) -> Result<Child> {
|
||||
let params_pipe = os_pipe::pipe().expect("params pipe");
|
||||
pub fn transaction_agent(
|
||||
ins: &ContainerHandle,
|
||||
flags: &TransactionFlags,
|
||||
params: TransactionParameters,
|
||||
metadata: &TransactionMetadata,
|
||||
) -> Result<Child> {
|
||||
let params_pipe = os_pipe::pipe().expect("params pipe");
|
||||
let params_fd = agent_params(¶ms_pipe.0, ¶ms_pipe.1, ¶ms, metadata)?;
|
||||
let sec_pipe = os_pipe::pipe().expect("eBPF pipe");
|
||||
let sec_fd = provide_bpf_program(vec![Standard, Namespaces], &sec_pipe.0, sec_pipe.1).expect("eBPF program");
|
||||
let fd_mappings = vec![
|
||||
FdMapping {
|
||||
parent_fd: sec_fd,
|
||||
child_fd: sec_fd
|
||||
},
|
||||
FdMapping {
|
||||
parent_fd: params_fd,
|
||||
child_fd: params_fd
|
||||
},
|
||||
];
|
||||
|
||||
match Command::new(BWRAP_EXECUTABLE).env_clear()
|
||||
.arg("--bind").arg(ins.vars().root()).arg("/mnt/fs")
|
||||
let fd_mappings = vec![
|
||||
FdMapping {
|
||||
parent_fd: sec_fd,
|
||||
child_fd: sec_fd
|
||||
},
|
||||
FdMapping {
|
||||
parent_fd: params_fd,
|
||||
child_fd: params_fd
|
||||
},
|
||||
];
|
||||
let mut process = Command::new(BWRAP_EXECUTABLE);
|
||||
|
||||
process.arg("--bind").arg(ins.vars().root()).arg("/mnt/fs")
|
||||
.arg("--symlink").arg("/mnt/fs/usr").arg("/usr")
|
||||
.arg("--ro-bind").arg(format!("{}/bin", *DIST_IMG)).arg("/bin")
|
||||
.arg("--ro-bind").arg(format!("{}/lib", *DIST_IMG)).arg("/lib64")
|
||||
.arg("--symlink").arg("lib").arg("/lib")
|
||||
.arg("--ro-bind").arg("/etc/resolv.conf").arg("/etc/resolv.conf")
|
||||
.arg("--ro-bind").arg("/etc/localtime").arg("/etc/localtime")
|
||||
.arg("--ro-bind").arg("/etc/localtime").arg("/etc/localtime")
|
||||
.arg("--ro-bind").arg(*DIST_TLS).arg("/etc/ssl/certs/ca-certificates.crt")
|
||||
.arg("--bind").arg(*LOG_LOCATION).arg("/mnt/share/pacwrap.log")
|
||||
.arg("--bind").arg(ins.vars().pacman_gnupg()).arg("/mnt/share/gnupg")
|
||||
|
@ -228,6 +233,7 @@ pub fn transaction_agent(ins: &ContainerHandle, params: TransactionParameters, m
|
|||
.arg("--dev").arg("/dev")
|
||||
.arg("--dev").arg("/mnt/fs/dev")
|
||||
.arg("--proc").arg("/mnt/fs/proc")
|
||||
.arg("--proc").arg("/proc")
|
||||
.arg("--unshare-all")
|
||||
.arg("--share-net")
|
||||
.arg("--hostname").arg("pacwrap-agent")
|
||||
|
@ -241,7 +247,6 @@ pub fn transaction_agent(ins: &ContainerHandle, params: TransactionParameters, m
|
|||
.arg("--setenv").arg("LD_PRELOAD").arg("/lib64/libfakechroot.so")
|
||||
.arg("--setenv").arg("PACWRAP_REAL_UID").arg(ID.0)
|
||||
.arg("--setenv").arg("PACWRAP_REAL_GID").arg(ID.1)
|
||||
.arg("--setenv").arg("RUST_BACKTRACE").arg("1")
|
||||
.arg("--die-with-parent")
|
||||
.arg("--unshare-user")
|
||||
.arg("--disable-userns")
|
||||
|
@ -249,15 +254,20 @@ pub fn transaction_agent(ins: &ContainerHandle, params: TransactionParameters, m
|
|||
.arg(sec_fd.to_string())
|
||||
.arg("--ro-bind-data")
|
||||
.arg(params_fd.to_string())
|
||||
.arg("/mnt/agent_params")
|
||||
.arg("agent")
|
||||
.arg("/mnt/agent_params");
|
||||
|
||||
if flags.contains(TransactionFlags::DEBUG) {
|
||||
process.arg("--setenv").arg("RUST_BACKTRACE").arg("full");
|
||||
}
|
||||
|
||||
match process.arg("agent")
|
||||
.arg("transact")
|
||||
.fd_mappings(fd_mappings)
|
||||
.unwrap()
|
||||
.expect("FD Mappings")
|
||||
.spawn()
|
||||
{
|
||||
Ok(child) => Ok(child),
|
||||
Err(err) => err!(ErrorKind::ProcessInitFailure(BWRAP_EXECUTABLE, err.kind())),
|
||||
Ok(child) => Ok(child),
|
||||
Err(err) => err!(ErrorKind::ProcessInitFailure(BWRAP_EXECUTABLE, err.kind())),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ use std::{
|
|||
fs::{File, OpenOptions},
|
||||
io::Write,
|
||||
path::Path,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use time::{format_description::FormatItem, macros::format_description, OffsetDateTime, UtcOffset};
|
||||
|
@ -31,8 +30,9 @@ use crate::{
|
|||
constants::{LOG_LOCATION, UNIX_TIMESTAMP},
|
||||
err,
|
||||
impl_error,
|
||||
utils::unix_epoch_time,
|
||||
Error,
|
||||
ErrorKind,
|
||||
ErrorGeneric,
|
||||
ErrorTrait,
|
||||
Result,
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ impl From<i8> for Level {
|
|||
}
|
||||
|
||||
impl Display for Level {
|
||||
fn fmt(&self, fmter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
fn fmt(&self, fmter: &mut Formatter<'_>) -> FmtResult {
|
||||
write!(fmter, "{}", self.to_str())
|
||||
}
|
||||
}
|
||||
|
@ -126,11 +126,15 @@ impl Logger {
|
|||
* between libalpm and the time crate, cache the offset during the
|
||||
* initalisation of this struct.
|
||||
*/
|
||||
let ofs = OffsetDateTime::now_local()
|
||||
.unwrap_or(OffsetDateTime::now_utc())
|
||||
.format(UTC_OFFSET)
|
||||
.unwrap();
|
||||
let ofs = UtcOffset::parse(ofs.as_str(), UTC_OFFSET).unwrap();
|
||||
let ofs = UtcOffset::parse(
|
||||
OffsetDateTime::now_local()
|
||||
.unwrap_or(OffsetDateTime::now_utc())
|
||||
.format(UTC_OFFSET)
|
||||
.expect("Format UTC offset")
|
||||
.as_str(),
|
||||
UTC_OFFSET,
|
||||
)
|
||||
.expect("Parse UTC offset");
|
||||
|
||||
Self {
|
||||
verbosity: 3,
|
||||
|
@ -140,14 +144,16 @@ impl Logger {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init(mut self) -> Result<Self> {
|
||||
let path = Path::new(*LOG_LOCATION);
|
||||
pub fn location(mut self, location: &str) -> Result<Self> {
|
||||
let path = Path::new(location);
|
||||
let file = OpenOptions::new().create(true).append(true).truncate(false).open(path);
|
||||
|
||||
self.file = Some(match file {
|
||||
Ok(file) => file,
|
||||
Err(error) => err!(ErrorKind::IOError(LOG_LOCATION.to_string(), error.kind()))?,
|
||||
});
|
||||
self.file = Some(file.prepend_io(|| location.into())?);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn init(mut self) -> Result<Self> {
|
||||
self = self.location(*LOG_LOCATION)?;
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
|
@ -155,9 +161,10 @@ impl Logger {
|
|||
self.verbosity = verbosity
|
||||
}
|
||||
|
||||
pub fn log(&mut self, level: Level, msg: &str) -> Result<()> {
|
||||
pub fn log(&mut self, level: Level, msg: &str) -> Result<usize> {
|
||||
// Check message verbosity against logger verbosity
|
||||
if level.verbosity() > self.verbosity {
|
||||
return Ok(());
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -168,27 +175,27 @@ impl Logger {
|
|||
* time offset if a change were to occur whilst this application is running.
|
||||
*/
|
||||
if let Ok(local) = OffsetDateTime::now_local() {
|
||||
self.offset = UtcOffset::parse(local.format(UTC_OFFSET).unwrap().as_str(), UTC_OFFSET).unwrap();
|
||||
}
|
||||
let local_time = local.format(UTC_OFFSET).expect("Format localtime");
|
||||
|
||||
let time: OffsetDateTime = OffsetDateTime::now_utc().to_offset(self.offset);
|
||||
let write = if let Some(file) = self.file.as_mut() {
|
||||
file.write(format!("[{}] [{}] [{}] {}\n", time.format(DATE_FORMAT).unwrap(), self.module, level, msg).as_bytes())
|
||||
} else {
|
||||
err!(LoggerError::Uninitialized)?
|
||||
};
|
||||
self.offset = UtcOffset::parse(&local_time, UTC_OFFSET).expect("Offset localtime");
|
||||
}
|
||||
|
||||
if let Level::Debug = level {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("SystemTime now");
|
||||
let now = unix_epoch_time();
|
||||
let nano = format!("{:.6}", now.subsec_nanos().to_string());
|
||||
let time = now.as_secs() as usize - *UNIX_TIMESTAMP as usize;
|
||||
let nano = now.subsec_nanos().to_string();
|
||||
|
||||
eprintln!("[{}.{:.6}] [{}] {}", time, nano, self.module, msg);
|
||||
eprintln!("[{}.{}] [{}] {}", time, nano, self.module, msg);
|
||||
}
|
||||
|
||||
match write {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => err!(ErrorKind::IOError(LOG_LOCATION.to_string(), error.kind())),
|
||||
match self.file.as_mut() {
|
||||
Some(file) => {
|
||||
let time = OffsetDateTime::now_utc().to_offset(self.offset).format(DATE_FORMAT).expect("Format time");
|
||||
let log = format!("[{}] [{}] [{}] {}\n", time, self.module, level, msg);
|
||||
|
||||
file.write(log.as_bytes()).generic()
|
||||
}
|
||||
None => err!(LoggerError::Uninitialized)?,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ use std::{
|
|||
os::unix::fs::symlink,
|
||||
path::Path,
|
||||
sync::OnceLock,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use alpm::{Alpm, LogLevel, SigLevel, Usage};
|
||||
|
@ -30,16 +29,22 @@ use pacmanconf::{self, Config, Repository};
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
config::{global, global::ProgressKind, ContainerHandle, ContainerType::*, ContainerVariables, Global},
|
||||
config::{
|
||||
global::{global, ProgressKind},
|
||||
ContainerHandle,
|
||||
ContainerType::*,
|
||||
ContainerVariables,
|
||||
Global,
|
||||
},
|
||||
constants::{ARROW_RED, BAR_GREEN, BOLD, CACHE_DIR, CONFIG_DIR, DATA_DIR, RESET, UNIX_TIMESTAMP, VERBOSE},
|
||||
err,
|
||||
exec::pacwrap_key,
|
||||
impl_error,
|
||||
sync::{
|
||||
event::download::{self, DownloadEvent},
|
||||
filesystem::{create_blank_state, create_hard_link},
|
||||
transaction::{TransactionAggregator, TransactionFlags},
|
||||
},
|
||||
utils::unix_epoch_time,
|
||||
Error,
|
||||
ErrorGeneric,
|
||||
ErrorTrait,
|
||||
|
@ -91,6 +96,8 @@ impl Display for SyncError {
|
|||
write!(fmter, "Target package {}{pkg}{}: Not available in sync databases.", *BOLD, *RESET),
|
||||
Self::TargetUpstream(pkg) =>
|
||||
write!(fmter, "Target package {}{pkg}{}: Installed in upstream container.", *BOLD, *RESET),
|
||||
Self::TransactionAgentError | Self::TransactionAgentFailure =>
|
||||
write!(fmter, "Agent process terminated due to upstream error."),
|
||||
Self::RecursionDepthExceeded(u) => write!(fmter, "Recursion depth exceeded maximum of {}{u}{}.", *BOLD, *RESET),
|
||||
Self::NoCompatibleRemotes => write!(fmter, "No compatible containers available to synchronize remote database."),
|
||||
Self::InvalidMagicNumber => write!(fmter, "Deserialization of input parameters failed: Invalid magic number."),
|
||||
|
@ -104,23 +111,23 @@ impl Display for SyncError {
|
|||
Self::InternalError(msg) => write!(fmter, "Internal failure: {msg}"),
|
||||
Self::SignalInterrupt => write!(fmter, "Signal interrupt was triggered."),
|
||||
Self::UnableToLocateKeyrings => write!(fmter, "Unable to locate pacman keyrings."),
|
||||
Self::TransactionAgentError => write!(fmter, "Agent process terminated due to upstream error."),
|
||||
Self::RepoConfError(path, err) => write!(fmter, "'{}': {}", path, err),
|
||||
Self::NothingToDo => write!(fmter, "Nothing to do."),
|
||||
_ => Ok(()),
|
||||
}?;
|
||||
|
||||
if let Self::TransactionFailure(_) = self {
|
||||
Ok(())
|
||||
} else if let Self::SignalInterrupt = self {
|
||||
write!(fmter, "\n{} Transaction aborted.", *ARROW_RED)
|
||||
} else {
|
||||
write!(fmter, "\n{} Transaction failed.", *ARROW_RED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_error!(SyncError);
|
||||
impl ErrorTrait for SyncError {
|
||||
fn code(&self) -> i32 {
|
||||
match self {
|
||||
Self::TransactionFailure(_) => (),
|
||||
Self::SignalInterrupt => eprintln!("{} Transaction aborted.", *ARROW_RED),
|
||||
_ => eprintln!("{} Transaction failed.", *ARROW_RED),
|
||||
}
|
||||
|
||||
1
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Error> for SyncError {
|
||||
fn from(error: &Error) -> SyncError {
|
||||
|
@ -255,7 +262,7 @@ fn alpm_handle(
|
|||
}
|
||||
|
||||
fn alpm_log_callback(level: LogLevel, msg: &str, counter: &mut usize) {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
|
||||
let now = unix_epoch_time();
|
||||
let time = now.as_secs() as usize - *counter;
|
||||
let nano = now.subsec_nanos().to_string();
|
||||
let log_level = level.bits() / 4;
|
||||
|
|
|
@ -287,12 +287,18 @@ impl<'a> TransactionAggregator<'a> {
|
|||
|
||||
handle.release();
|
||||
return match err.downcast::<SyncError>().map_err(|err| error!(SyncError::from(err)))? {
|
||||
SyncError::TransactionAgentFailure => {
|
||||
self.logger().log(Level::Fatal, &format!("Transaction error: {:?}", err))?;
|
||||
SyncError::TransactionAgentFailure
|
||||
| SyncError::ParameterAcquisitionFailure
|
||||
| SyncError::DeserializationFailure => {
|
||||
self.logger().log(Level::Fatal, &format!("Transaction error: {}", err))?;
|
||||
err.fatal()
|
||||
}
|
||||
SyncError::AgentVersionMismatch | SyncError::InvalidMagicNumber => {
|
||||
self.logger().log(Level::Error, &format!("Transaction error: {}", err))?;
|
||||
err.error()
|
||||
}
|
||||
_ => {
|
||||
self.logger().log(Level::Error, &format!("Transaction error: {:?}", err))?;
|
||||
self.logger().log(Level::Error, &format!("Transaction error: {}", err))?;
|
||||
Err(err)
|
||||
}
|
||||
};
|
||||
|
|
|
@ -87,19 +87,15 @@ impl Transaction for Commit {
|
|||
erroneous_preparation(error)?
|
||||
}
|
||||
|
||||
let result = confirm(&self.state, ag, handle, global()?);
|
||||
let result = match result {
|
||||
Err(result) => return result,
|
||||
Ok(result) => result,
|
||||
let trans_state = match confirm(&self.state, ag, handle, global()?) {
|
||||
Err(error) => return error,
|
||||
Ok(state) => state,
|
||||
};
|
||||
let params = TransactionParameters::new(*ag.action(), *handle.get_mode(), trans_state);
|
||||
|
||||
handle.set_alpm(None);
|
||||
ag.lock()?.assert()?;
|
||||
wait_on_agent(transaction_agent(
|
||||
inshandle,
|
||||
TransactionParameters::new(*ag.action(), *handle.get_mode(), result),
|
||||
handle.meta,
|
||||
)?)?;
|
||||
wait_on_agent(transaction_agent(inshandle, ag.flags(), params, handle.meta)?)?;
|
||||
|
||||
if self.keyring {
|
||||
ag.keyring_update(inshandle)?;
|
||||
|
@ -203,7 +199,7 @@ fn wait_on_agent(mut agent: Child) -> Result<()> {
|
|||
Ok(status) => match status.code().unwrap_or(-1) {
|
||||
0 => Ok(()),
|
||||
1 => err!(SyncError::TransactionAgentError),
|
||||
2 => err!(SyncError::TransactionAgentFailure),
|
||||
2 | 101 => err!(SyncError::TransactionAgentFailure),
|
||||
3 => err!(SyncError::ParameterAcquisitionFailure),
|
||||
4 => err!(SyncError::DeserializationFailure),
|
||||
5 => err!(SyncError::InvalidMagicNumber),
|
||||
|
|
|
@ -20,7 +20,14 @@
|
|||
use std::thread::Builder;
|
||||
|
||||
use alpm::{
|
||||
Alpm, CommitData, CommitError, Error::{ConflictingDeps, FileConflicts, PkgInvalid, PkgInvalidArch, PkgInvalidChecksum, PkgInvalidSig, UnsatisfiedDeps}, FileConflictType, Package, PrepareData, PrepareError
|
||||
Alpm,
|
||||
CommitData,
|
||||
CommitError,
|
||||
Error::{ConflictingDeps, FileConflicts, PkgInvalid, PkgInvalidArch, PkgInvalidChecksum, PkgInvalidSig, UnsatisfiedDeps},
|
||||
FileConflictType,
|
||||
Package,
|
||||
PrepareData,
|
||||
PrepareError,
|
||||
};
|
||||
use signal_hook::iterator::Signals;
|
||||
|
||||
|
@ -109,7 +116,6 @@ pub fn erroneous_transaction(error: CommitError) -> Result<()> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err!(SyncError::TransactionFailure("Conflict within container filesystem".into()))?
|
||||
|
|
|
@ -21,7 +21,7 @@ use std::{
|
|||
env::var,
|
||||
os::unix::net::UnixStream,
|
||||
path::Path,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
@ -55,8 +55,8 @@ pub fn check_socket(socket: &String) -> bool {
|
|||
UnixStream::connect(Path::new(socket)).is_ok()
|
||||
}
|
||||
|
||||
pub fn unix_time_as_seconds() -> u64 {
|
||||
SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs()
|
||||
pub fn unix_epoch_time() -> Duration {
|
||||
SystemTime::now().duration_since(UNIX_EPOCH).expect("SystemTime")
|
||||
}
|
||||
|
||||
pub fn whitespace(amt: usize) -> String {
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn remove(args: &mut Arguments) -> Result<()> {
|
|||
return remove_containers(args);
|
||||
}
|
||||
|
||||
let mut logger = Logger::new("pacwrap-sync").init().unwrap();
|
||||
let mut logger = Logger::new("pacwrap-sync").init()?;
|
||||
let action = action(args);
|
||||
let lock = Lock::new().lock()?;
|
||||
let result = engage_aggregator(action, args, &mut logger, &lock);
|
||||
|
|
|
@ -44,7 +44,7 @@ pub fn synchronize(args: &mut Arguments) -> Result<()> {
|
|||
check_root()?;
|
||||
init()?;
|
||||
|
||||
let mut logger = Logger::new("pacwrap-sync").init().unwrap();
|
||||
let mut logger = Logger::new("pacwrap-sync").init()?;
|
||||
let mut cache = cache::populate()?;
|
||||
let (action, create) = action(args);
|
||||
let lock = Lock::new().lock()?;
|
||||
|
|
Loading…
Reference in a new issue