Structural simplification, rustfmt configuration applied, and snake_case
for declared modules within tag vars - For the sake of coherency, there are now four types of containers: Symbolic, Base, Slice, and Aggregate. These names better reflect the associated container types. - Global configuration template is now written to disk prior to instantiation - Inclusion of .rustfmt.toml with formatting applied to source files - Breaking format change: SCREAMING_CASE has been replaced with snake_case for tag variables - Simplified data structure in cache module - InstanceCache type within the cache module replaces 'registered_base', 'registered_dep', and 'registered_root', with 'filter'. - Cleaned up argument parsing match statements in the front-end modules. - Specifying dependencies with a comma deliniation is now supported - Manual updated to reflect argument changes. - query module updated to utilise internal APIs - Some minor improvements to error handling. - Removed redundant calls to --clear-env with bubblewrap. - Scripting no longer outputs ANSI charcodes to unsupported terminals
This commit is contained in:
parent
3b5951cea6
commit
9b495390d2
71 changed files with 2781 additions and 2398 deletions
16
.rustfmt.toml
Normal file
16
.rustfmt.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
unstable_features = true
|
||||
indent_style = "Block"
|
||||
imports_indent = "Block"
|
||||
imports_layout = "HorizontalVertical"
|
||||
imports_granularity = "Crate"
|
||||
brace_style = "PreferSameLine"
|
||||
match_arm_leading_pipes = "Never"
|
||||
match_arm_blocks = false
|
||||
condense_wildcard_suffixes = true
|
||||
overflow_delimited_expr = false
|
||||
spaces_around_ranges = true
|
||||
reorder_imports = true
|
||||
hard_tabs = false
|
||||
max_width = 130
|
||||
fn_call_width = 120
|
||||
chain_width = 90
|
|
@ -355,7 +355,7 @@ replicate_instance() {
|
|||
[[ $type != BASE ]] && depend=$(return_dependency)
|
||||
|
||||
case $type in
|
||||
ROOT) params+="r";;
|
||||
ROOT) params+="a";;
|
||||
BASE) params+="b";;
|
||||
DEP) params+="s";;
|
||||
LINK) ln -s "$INSTANCE_ROOT_DIR/$depend" "$INSTANCE_ROOT_DIR/$instance"
|
||||
|
|
11
dist/tools/clean.sh
vendored
11
dist/tools/clean.sh
vendored
|
@ -18,10 +18,13 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
GREEN=$(tput setaf 2)
|
||||
RED=$(tput setaf 1)
|
||||
RESET=$(tput sgr0)
|
||||
if ! [[ -z $COLORTERM ]] || [[ $TERM == "dummy" ]]; then
|
||||
BOLD=$(tput bold)
|
||||
GREEN=$(tput setaf 2)
|
||||
RED=$(tput setaf 1)
|
||||
RESET=$(tput sgr0)
|
||||
fi
|
||||
|
||||
DIST_RUNTIME="./dist/runtime"
|
||||
DIST_BASE="./dist/pacwrap-base-dist"
|
||||
DIST_REPO="./dist/repo"
|
||||
|
|
11
dist/tools/runtime.sh
vendored
11
dist/tools/runtime.sh
vendored
|
@ -21,10 +21,13 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
GREEN=$(tput setaf 2)
|
||||
RESET=$(tput sgr0)
|
||||
if ! [[ -z $COLORTERM ]] || [[ $TERM == "dummy" ]]; then
|
||||
BOLD=$(tput bold)
|
||||
RED=$(tput setaf 1)
|
||||
GREEN=$(tput setaf 2)
|
||||
RESET=$(tput sgr0)
|
||||
fi
|
||||
|
||||
LIB_DIR="/lib"
|
||||
BIN_DIR="/bin"
|
||||
DEST_DIR="./dist/runtime"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-agent
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
fn main() {
|
||||
if ! cfg!(target_os="linux") || ! cfg!(target_family="unix") {
|
||||
if !cfg!(target_os = "linux") || !cfg!(target_family = "unix") {
|
||||
panic!("Unsupported build target. Please refer to the documentation for further information.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-agent
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -16,57 +16,64 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
use std::{fs::{self, File}, io::ErrorKind::NotFound, os::unix::prelude::FileExt, env};
|
||||
use std::{
|
||||
env,
|
||||
fs::{self, File},
|
||||
io::ErrorKind::NotFound,
|
||||
os::unix::prelude::FileExt,
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use pacwrap_core::{err,
|
||||
use pacwrap_core::{
|
||||
config::Global,
|
||||
err,
|
||||
sync::{
|
||||
self,
|
||||
event::{
|
||||
download::{self, DownloadEvent},
|
||||
progress::{self, ProgressEvent},
|
||||
query,
|
||||
},
|
||||
transaction::{TransactionHandle, TransactionMetadata, TransactionParameters, TransactionType, MAGIC_NUMBER},
|
||||
utils::{erroneous_preparation, erroneous_transaction},
|
||||
AlpmConfigData,
|
||||
SyncError,
|
||||
},
|
||||
utils::{print_warning, read_le_32},
|
||||
Error,
|
||||
Result,
|
||||
sync::{self,
|
||||
SyncError,
|
||||
AlpmConfigData,
|
||||
utils::{erroneous_transaction,
|
||||
erroneous_preparation},
|
||||
transaction::{TransactionHandle,
|
||||
TransactionType,
|
||||
TransactionMetadata,
|
||||
TransactionParameters,
|
||||
MAGIC_NUMBER},
|
||||
event::{download::{self, DownloadEvent},
|
||||
progress::{self, ProgressEvent},
|
||||
query}},
|
||||
utils::{print_warning, read_le_32}, config::Global};
|
||||
};
|
||||
|
||||
use crate::error::AgentError;
|
||||
|
||||
static AGENT_PARAMS: &'static str = "/mnt/agent_params";
|
||||
|
||||
pub fn transact() -> Result<()> {
|
||||
let mut header_buffer = vec![0; 7];
|
||||
let mut header_buffer = vec![0; 7];
|
||||
let mut file = match File::open(AGENT_PARAMS) {
|
||||
Ok(file) => file,
|
||||
Err(error) => {
|
||||
if let Ok(var) = env::var("SHELL") {
|
||||
if ! var.is_empty() {
|
||||
if !var.is_empty() {
|
||||
err!(AgentError::DirectExecution)?
|
||||
}
|
||||
}
|
||||
|
||||
err!(AgentError::IOError(AGENT_PARAMS, error.kind()))?
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(error) = file.read_exact_at(&mut header_buffer, 0) {
|
||||
err!(AgentError::IOError(AGENT_PARAMS, error.kind()))?
|
||||
}
|
||||
|
||||
|
||||
decode_header(&header_buffer)?;
|
||||
|
||||
let params: TransactionParameters = deserialize(&mut file)?;
|
||||
let config: Global = deserialize(&mut file)?;
|
||||
let alpm_remotes: AlpmConfigData = deserialize(&mut file)?;
|
||||
let mut metadata: TransactionMetadata = deserialize(&mut file)?;
|
||||
let mut metadata: TransactionMetadata = deserialize(&mut file)?;
|
||||
let alpm = sync::instantiate_alpm_agent(&config, &alpm_remotes);
|
||||
let mut handle = TransactionHandle::new(&config, alpm, &mut metadata);
|
||||
|
||||
|
@ -74,11 +81,11 @@ pub fn transact() -> Result<()> {
|
|||
}
|
||||
|
||||
fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: TransactionParameters) -> Result<()> {
|
||||
let flags = handle.retrieve_flags();
|
||||
let flags = handle.retrieve_flags();
|
||||
let mode = agent.mode();
|
||||
let action = agent.action();
|
||||
let config = config.config();
|
||||
let progress = config.progress();
|
||||
let pkind = config.progress();
|
||||
let bytes = agent.bytes();
|
||||
let files = agent.files();
|
||||
|
||||
|
@ -86,12 +93,12 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
err!(SyncError::InitializationFailure(error.to_string().into()))?
|
||||
}
|
||||
|
||||
handle.ignore(true);
|
||||
handle.ignore(true);
|
||||
|
||||
if let TransactionType::Upgrade(upgrade, downgrade, _) = action {
|
||||
if let TransactionType::Upgrade(upgrade, downgrade, _) = action {
|
||||
if upgrade {
|
||||
handle.alpm().sync_sysupgrade(downgrade).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle.prepare(&action, &flags.0.unwrap())?;
|
||||
|
@ -100,17 +107,12 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
erroneous_preparation(error)?
|
||||
}
|
||||
|
||||
let progress_cb = ProgressEvent::new()
|
||||
.style(progress.0)
|
||||
.configure(&action);
|
||||
let download_cb = DownloadEvent::new()
|
||||
.style(progress.0)
|
||||
.total(bytes, files)
|
||||
.configure(&mode, progress.1);
|
||||
let progress_cb = ProgressEvent::new().style(pkind.0).configure(&action);
|
||||
let download_cb = DownloadEvent::new().style(pkind.0).total(bytes, files).configure(&mode, pkind.1);
|
||||
|
||||
handle.alpm().set_question_cb((), query::callback);
|
||||
handle.alpm().set_progress_cb(progress_cb, progress::callback(&mode, progress.0));
|
||||
handle.alpm().set_dl_cb(download_cb, download::callback(progress.1));
|
||||
handle.alpm().set_progress_cb(progress_cb, progress::callback(&mode, pkind.0));
|
||||
handle.alpm().set_dl_cb(download_cb, download::callback(pkind.1));
|
||||
|
||||
if let Err(error) = handle.alpm_mut().trans_commit() {
|
||||
erroneous_transaction(error)?
|
||||
|
@ -121,7 +123,8 @@ fn conduct_transaction(config: &Global, handle: &mut TransactionHandle, agent: T
|
|||
|
||||
if let Err(error) = fs::copy("/etc/ld.so.cache", "/mnt/fs/etc/ld.so.cache") {
|
||||
match error.kind() {
|
||||
NotFound => (), _ => print_warning(format!("Failed to propagate ld.so.cache: {}", error)),
|
||||
NotFound => (),
|
||||
_ => print_warning(format!("Failed to propagate ld.so.cache: {}", error)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,7 +142,7 @@ fn decode_header(buffer: &Vec<u8>) -> Result<()> {
|
|||
}
|
||||
|
||||
if major.0 != major.1 || minor.0 != minor.1 || patch.0 != patch.1 {
|
||||
err!(AgentError::InvalidVersion(major.0,minor.0,patch.0,major.1,minor.1,patch.1))?;
|
||||
err!(AgentError::InvalidVersion(major.0, minor.0, patch.0, major.1, minor.1, patch.1))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -148,6 +151,6 @@ fn decode_header(buffer: &Vec<u8>) -> Result<()> {
|
|||
fn deserialize<T: for<'de> Deserialize<'de>>(stdin: &mut File) -> Result<T> {
|
||||
match bincode::deserialize_from::<&mut File, T>(stdin) {
|
||||
Ok(meta) => Ok(meta),
|
||||
Err(error) => err!(AgentError::DeserializationError(error.as_ref().to_string()))
|
||||
Err(error) => err!(AgentError::DeserializationError(error.as_ref().to_string())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-agent
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -19,25 +19,30 @@
|
|||
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use pacwrap_core::{ErrorTrait, constants::{RESET, BOLD}};
|
||||
use pacwrap_core::{
|
||||
constants::{BOLD, RESET},
|
||||
ErrorTrait,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AgentError {
|
||||
DeserializationError(String),
|
||||
InvalidVersion(u8,u8,u8,u8,u8,u8),
|
||||
InvalidVersion(u8, u8, u8, u8, u8, u8),
|
||||
InvalidMagic(u32, u32),
|
||||
IOError(&'static str, std::io::ErrorKind),
|
||||
DirectExecution,
|
||||
}
|
||||
|
||||
impl Display for AgentError {
|
||||
fn fmt(&self, fmter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
fn fmt(&self, fmter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
Self::DirectExecution => write!(fmter, "Direct execution of this binary is unsupported."),
|
||||
Self::InvalidMagic(magic, comparator) => write!(fmter, "Magic mismatch {} != {}", magic, comparator),
|
||||
Self::InvalidVersion(a, b, c, d, e, f) => write!(fmter, "Version mismatch {}.{}.{} != {}.{}.{}", a, b, c, d, e, f),
|
||||
Self::InvalidVersion(a, b, c, d, e, f) => {
|
||||
write!(fmter, "Version mismatch {}.{}.{} != {}.{}.{}", a, b, c, d, e, f)
|
||||
}
|
||||
Self::DeserializationError(error) => write!(fmter, "Deserilization error: {}", error),
|
||||
Self::IOError(file, error) => write!(fmter, "'{}{}{}' {}", *BOLD, file, *RESET, error)
|
||||
Self::IOError(file, error) => write!(fmter, "'{}{}{}' {}", *BOLD, file, *RESET, error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +54,7 @@ impl ErrorTrait for AgentError {
|
|||
Self::InvalidVersion(..) => 4,
|
||||
Self::DeserializationError(..) => 3,
|
||||
Self::IOError(..) => 2,
|
||||
_ => 1
|
||||
_ => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-agent
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -17,20 +17,25 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use pacwrap_core::{err, Error, utils::{Arguments, arguments::Operand}};
|
||||
use pacwrap_core::{
|
||||
err,
|
||||
utils::{arguments::Operand, Arguments},
|
||||
Error,
|
||||
};
|
||||
|
||||
use crate::error::AgentError;
|
||||
|
||||
mod error;
|
||||
mod agent;
|
||||
mod error;
|
||||
|
||||
fn main() {
|
||||
let arguments = &mut Arguments::new().populate();
|
||||
let param = arguments.next().unwrap_or_default();
|
||||
let result = match param {
|
||||
Operand::Value("transact") => agent::transact(), _ => err!(AgentError::DirectExecution)
|
||||
Operand::Value("transact") => agent::transact(),
|
||||
_ => err!(AgentError::DirectExecution),
|
||||
};
|
||||
|
||||
|
||||
if let Err(error) = result {
|
||||
error.handle();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -27,7 +27,7 @@ fn dist_repo() -> String {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
if ! cfg!(target_os="linux") || ! cfg!(target_family="unix") {
|
||||
if !cfg!(target_os = "linux") || !cfg!(target_family = "unix") {
|
||||
panic!("Unsupported build target. Please refer to the documentation for further information.")
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -17,35 +17,42 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{fmt::Display,
|
||||
io::{Write, ErrorKind::NotFound},
|
||||
fmt::Formatter,
|
||||
path::Path,
|
||||
fs::File};
|
||||
use std::{
|
||||
fmt::{Display, Formatter},
|
||||
fs::File,
|
||||
io::{ErrorKind::NotFound, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{err, impl_error, ErrorKind, error::*, constants::{BOLD, RESET, CONFIG_FILE}};
|
||||
use crate::{
|
||||
constants::{BOLD, CONFIG_FILE, RESET},
|
||||
err,
|
||||
error::*,
|
||||
impl_error,
|
||||
ErrorKind,
|
||||
};
|
||||
|
||||
pub use self::{cache::InstanceCache,
|
||||
instance::{Instance,
|
||||
InstanceHandle,
|
||||
InstanceType},
|
||||
vars::InsVars,
|
||||
filesystem::{Filesystem, BindError},
|
||||
permission::{Permission, PermError},
|
||||
pub use self::{
|
||||
cache::InstanceCache,
|
||||
dbus::Dbus,
|
||||
global::{Global, CONFIG}};
|
||||
filesystem::{BindError, Filesystem},
|
||||
global::{Global, CONFIG},
|
||||
instance::{Instance, InstanceHandle, InstanceType},
|
||||
permission::{PermError, Permission},
|
||||
vars::InsVars,
|
||||
};
|
||||
|
||||
pub mod vars;
|
||||
pub mod filesystem;
|
||||
pub mod permission;
|
||||
pub mod dbus;
|
||||
pub mod cache;
|
||||
pub mod instance;
|
||||
pub mod init;
|
||||
pub mod register;
|
||||
pub mod dbus;
|
||||
pub mod filesystem;
|
||||
pub mod global;
|
||||
pub mod init;
|
||||
pub mod instance;
|
||||
pub mod permission;
|
||||
pub mod register;
|
||||
pub mod vars;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ConfigError {
|
||||
|
@ -61,13 +68,13 @@ impl_error!(ConfigError);
|
|||
|
||||
impl Display for ConfigError {
|
||||
fn fmt(&self, fmter: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
Self::Filesystem(module, err) => write!(fmter, "Failed to register filesystem {}: {} ", module, err),
|
||||
Self::Permission(module, err) => write!(fmter, "Failed to register permission {}: {} ", module, err),
|
||||
match self {
|
||||
Self::Filesystem(module, err) => write!(fmter, "Failed to register filesystem '{}': {} ", module, err),
|
||||
Self::Permission(module, err) => write!(fmter, "Failed to register permission '{}': {} ", module, err),
|
||||
Self::Load(ins, error) => write!(fmter, "Failed to load '{ins}': {error}"),
|
||||
Self::Save(ins, error) => write!(fmter, "Failed to save '{ins}': {error}"),
|
||||
Self::AlreadyExists(ins) => write!(fmter, "Container {}{ins}{} already exists.", *BOLD, *RESET),
|
||||
Self::ConfigNotFound(ins) => write!(fmter, "Configuration '{}{ins}{}.yml' not found.", *BOLD, *RESET)
|
||||
Self::ConfigNotFound(ins) => write!(fmter, "Configuration '{}{ins}{}' not found.", *BOLD, *RESET),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,10 +86,10 @@ impl From<ConfigError> for String {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn provide_handle(instance: &str) -> Result<InstanceHandle> {
|
||||
pub fn provide_handle(instance: &str) -> Result<InstanceHandle> {
|
||||
let vars = InsVars::new(instance);
|
||||
|
||||
if ! Path::new(vars.root()).exists() {
|
||||
if !Path::new(vars.root()).exists() {
|
||||
err!(ErrorKind::InstanceNotFound(instance.into()))?
|
||||
}
|
||||
|
||||
|
@ -94,19 +101,19 @@ pub fn provide_new_handle(instance: &str) -> Result<InstanceHandle> {
|
|||
handle(instance, InsVars::new(instance))
|
||||
}
|
||||
|
||||
fn save<T: Serialize>(obj: &T, path: &str) -> Result<()> {
|
||||
fn save<T: Serialize>(obj: &T, path: &str) -> Result<()> {
|
||||
let mut f = match File::create(Path::new(path)) {
|
||||
Ok(f) => f,
|
||||
Err(error) => err!(ErrorKind::IOError(path.into(), error.kind()))?
|
||||
Err(error) => err!(ErrorKind::IOError(path.into(), error.kind()))?,
|
||||
};
|
||||
let config = match serde_yaml::to_string(&obj) {
|
||||
Ok(file) => file,
|
||||
Err(error) => err!(ConfigError::Save(path.into(), error.to_string()))?
|
||||
Err(error) => err!(ConfigError::Save(path.into(), error.to_string()))?,
|
||||
};
|
||||
|
||||
|
||||
match write!(f, "{}", config) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(error) => err!(ErrorKind::IOError(path.into(), error.kind()))
|
||||
Err(error) => err!(ErrorKind::IOError(path.into(), error.kind())),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,15 +122,15 @@ fn handle<'a>(instance: &str, vars: InsVars<'a>) -> Result<InstanceHandle<'a>> {
|
|||
Ok(file) => {
|
||||
let config = match serde_yaml::from_reader(&file) {
|
||||
Ok(file) => file,
|
||||
Err(error) => err!(ConfigError::Load(vars.instance().into(), error.to_string()))?
|
||||
Err(error) => err!(ConfigError::Load(vars.instance().into(), error.to_string()))?,
|
||||
};
|
||||
|
||||
Ok(InstanceHandle::new(config, vars))
|
||||
},
|
||||
}
|
||||
Err(error) => match error.kind() {
|
||||
NotFound => err!(ConfigError::ConfigNotFound(instance.into()))?,
|
||||
_ => err!(ErrorKind::IOError(vars.config_path().into(), error.kind()))?,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,11 +140,11 @@ fn config() -> Result<Global> {
|
|||
match File::open(*CONFIG_FILE) {
|
||||
Ok(file) => match serde_yaml::from_reader(&file) {
|
||||
Ok(file) => Ok(file),
|
||||
Err(error) => err!(ConfigError::Load(CONFIG_FILE.to_string(), error.to_string()))?
|
||||
Err(error) => err!(ConfigError::Load(CONFIG_FILE.to_string(), error.to_string()))?,
|
||||
},
|
||||
Err(error) => match error.kind() {
|
||||
NotFound => err!(ConfigError::ConfigNotFound(CONFIG_FILE.to_string()))?,
|
||||
_ => err!(ErrorKind::IOError(CONFIG_FILE.to_string(), error.kind()))?,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -19,33 +19,24 @@
|
|||
|
||||
use std::{collections::HashMap, fs::read_dir};
|
||||
|
||||
use crate::{err,
|
||||
ErrorKind,
|
||||
use crate::{
|
||||
config::{self, InstanceHandle},
|
||||
constants::DATA_DIR,
|
||||
err,
|
||||
error::*,
|
||||
constants::DATA_DIR,
|
||||
config::{self, InstanceHandle}};
|
||||
ErrorKind,
|
||||
};
|
||||
|
||||
use super::{InsVars,
|
||||
ConfigError,
|
||||
Instance,
|
||||
instance::InstanceType};
|
||||
use super::{instance::InstanceType, ConfigError, InsVars, Instance};
|
||||
|
||||
pub struct InstanceCache<'a> {
|
||||
instances: HashMap<&'a str, InstanceHandle<'a>>,
|
||||
registered: Vec<&'a str>,
|
||||
registered_base: Vec<&'a str>,
|
||||
registered_dep: Vec<&'a str>,
|
||||
registered_root: Vec<&'a str>
|
||||
}
|
||||
|
||||
impl <'a>InstanceCache<'a> {
|
||||
impl<'a> InstanceCache<'a> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
instances: HashMap::new(),
|
||||
registered: Vec::new(),
|
||||
registered_base: Vec::new(),
|
||||
registered_dep: Vec::new(),
|
||||
registered_root: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,87 +48,84 @@ impl <'a>InstanceCache<'a> {
|
|||
for dep in deps.iter() {
|
||||
if let None = self.instances.get(dep) {
|
||||
err!(ErrorKind::DependencyNotFound((*dep).into(), ins.into()))?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let deps = deps.iter().map(|a| (*a).into()).collect();
|
||||
let handle = match config::provide_new_handle(ins) {
|
||||
Ok(mut handle) => {
|
||||
handle.metadata_mut().set(deps, vec!());
|
||||
handle
|
||||
},
|
||||
Ok(mut handle) => {
|
||||
handle.metadata_mut().set(deps, vec![]);
|
||||
handle
|
||||
}
|
||||
Err(err) => match err.downcast::<ConfigError>() {
|
||||
Ok(error) => match error {
|
||||
ConfigError::ConfigNotFound(_) => {
|
||||
let vars = InsVars::new(ins);
|
||||
let cfg = Instance::new(instype, deps, vec!());
|
||||
|
||||
InstanceHandle::new(cfg, vars)
|
||||
},
|
||||
let vars = InsVars::new(ins);
|
||||
let cfg = Instance::new(instype, deps, vec![]);
|
||||
|
||||
InstanceHandle::new(cfg, vars)
|
||||
}
|
||||
_ => Err(err)?,
|
||||
}
|
||||
},
|
||||
_ => Err(err)?,
|
||||
},
|
||||
};
|
||||
|
||||
Ok(self.register(ins, handle))
|
||||
Ok(self.register(ins, handle))
|
||||
}
|
||||
|
||||
fn map(&mut self, ins: &'a str) -> Result<()> {
|
||||
fn map(&mut self, ins: &'a str) -> Result<()> {
|
||||
if let Some(_) = self.instances.get(ins) {
|
||||
err!(ConfigError::AlreadyExists(ins.to_owned()))?
|
||||
}
|
||||
|
||||
Ok(self.register(ins, match config::provide_handle(ins) {
|
||||
Ok(ins) => ins,
|
||||
Err(error) => {
|
||||
error.warn();
|
||||
return Ok(())
|
||||
}
|
||||
}))
|
||||
Ok(self.register(
|
||||
ins,
|
||||
match config::provide_handle(ins) {
|
||||
Ok(ins) => ins,
|
||||
Err(error) => {
|
||||
error.warn();
|
||||
return Ok(());
|
||||
}
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn register(&mut self, ins: &'a str, handle: InstanceHandle<'a>) {
|
||||
match handle.metadata().container_type() {
|
||||
InstanceType::BASE => self.registered_base.push(ins),
|
||||
InstanceType::DEP => self.registered_dep.push(ins),
|
||||
InstanceType::ROOT => self.registered_root.push(ins),
|
||||
InstanceType::LINK => return,
|
||||
}
|
||||
if let InstanceType::Symbolic = handle.metadata().container_type() {
|
||||
return;
|
||||
}
|
||||
|
||||
self.instances.insert(ins, handle);
|
||||
self.registered.push(ins);
|
||||
}
|
||||
|
||||
pub fn registered(&self) -> &Vec<&'a str> {
|
||||
&self.registered
|
||||
}
|
||||
|
||||
pub fn registered_base(&self) -> &Vec<&'a str> {
|
||||
&self.registered_base
|
||||
}
|
||||
|
||||
pub fn registered_dep(&self) -> &Vec<&'a str> {
|
||||
&self.registered_dep
|
||||
pub fn registered(&self) -> Vec<&'a str> {
|
||||
self.instances.iter().map(|a| *a.0).collect()
|
||||
}
|
||||
|
||||
pub fn registered_root(&self) -> &Vec<&'a str> {
|
||||
&self.registered_root
|
||||
pub fn filter(&self, filter: Vec<InstanceType>) -> Vec<&'a str> {
|
||||
self.instances
|
||||
.iter()
|
||||
.filter(|a| filter.contains(a.1.metadata().container_type()))
|
||||
.map(|a| *a.0)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn obtain_base_handle(&self) -> Option<&InstanceHandle> {
|
||||
match self.registered_base.get(0) {
|
||||
Some(instance) => self.instances.get(instance), None => None,
|
||||
match self.filter(vec![InstanceType::Base]).get(0) {
|
||||
Some(instance) => self.instances.get(instance),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_instance(&self, ins: &str) -> Result<&InstanceHandle> {
|
||||
pub fn get_instance(&self, ins: &str) -> Result<&InstanceHandle> {
|
||||
match self.instances.get(ins) {
|
||||
Some(ins) => Ok(ins), None => err!(ErrorKind::InstanceNotFound(ins.into())),
|
||||
Some(ins) => Ok(ins),
|
||||
None => err!(ErrorKind::InstanceNotFound(ins.into())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_instance_option(&self, ins: &str) -> Option<&InstanceHandle> {
|
||||
pub fn get_instance_option(&self, ins: &str) -> Option<&InstanceHandle> {
|
||||
self.instances.get(ins)
|
||||
}
|
||||
}
|
||||
|
@ -156,22 +144,25 @@ pub fn populate<'a>() -> Result<InstanceCache<'a>> {
|
|||
populate_from(&roots()?)
|
||||
}
|
||||
|
||||
fn roots<'a>() -> Result<Vec<&'a str>> {
|
||||
fn roots<'a>() -> Result<Vec<&'a str>> {
|
||||
match read_dir(format!("{}/root", *DATA_DIR)) {
|
||||
Ok(dir) => Ok(dir.filter(|f| match f {
|
||||
Ok(f) => match f.metadata() {
|
||||
Ok(meta) => meta.is_dir() | meta.is_symlink(), Err(_) => false
|
||||
},
|
||||
Err(_) => false
|
||||
})
|
||||
.map(|s| match s {
|
||||
Ok(dir) => Ok(dir
|
||||
.filter(|f| match f {
|
||||
Ok(f) => match f.metadata() {
|
||||
Ok(meta) => meta.is_dir() | meta.is_symlink(),
|
||||
Err(_) => false,
|
||||
},
|
||||
Err(_) => false,
|
||||
})
|
||||
.map(|s| match s {
|
||||
Ok(f) => match f.file_name().to_str() {
|
||||
Some(f) => f.to_owned().leak(), None => "",
|
||||
Some(f) => f.to_owned().leak(),
|
||||
None => "",
|
||||
},
|
||||
Err(_) => "",
|
||||
})
|
||||
.filter(|e| ! e.is_empty())
|
||||
.collect()),
|
||||
.filter(|e| !e.is_empty())
|
||||
.collect()),
|
||||
Err(error) => err!(ErrorKind::IOError(format!("{}/root", *DATA_DIR), error.kind())),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -19,13 +19,13 @@
|
|||
|
||||
use crate::exec::args::ExecutionArgs;
|
||||
|
||||
use dyn_clone::{DynClone, clone_trait_object};
|
||||
use dyn_clone::{clone_trait_object, DynClone};
|
||||
|
||||
mod socket;
|
||||
mod appindicator;
|
||||
mod socket;
|
||||
mod xdg_portal;
|
||||
|
||||
#[typetag::serde(tag = "permission")]
|
||||
#[typetag::serde(tag = "module")]
|
||||
pub trait Dbus: DynClone {
|
||||
fn register(&self, args: &mut ExecutionArgs);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::{config::Dbus, exec::args::ExecutionArgs};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct APPINDICATOR;
|
||||
struct AppIndicator;
|
||||
|
||||
#[typetag::serde]
|
||||
impl Dbus for APPINDICATOR {
|
||||
#[typetag::serde(name = "appindicator")]
|
||||
impl Dbus for AppIndicator {
|
||||
fn register(&self, args: &mut ExecutionArgs) {
|
||||
args.dbus("broadcast", "org.kde.StatusNotifierWatcher=@/StatusNotifierWatcher");
|
||||
}
|
||||
|
|
|
@ -3,22 +3,20 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::{config::Dbus, exec::args::ExecutionArgs};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct SOCKET {
|
||||
struct Socket {
|
||||
socket: String,
|
||||
address: Vec<String>
|
||||
address: Vec<String>,
|
||||
}
|
||||
|
||||
#[typetag::serde]
|
||||
impl Dbus for SOCKET {
|
||||
#[typetag::serde(name = "socket")]
|
||||
impl Dbus for Socket {
|
||||
fn register(&self, args: &mut ExecutionArgs) {
|
||||
match self.socket.to_lowercase().as_str() {
|
||||
p if p == "call" || p == "talk" || p == "see" || p == "own" || p == "broadcast" => {
|
||||
p if p == "call" || p == "talk" || p == "see" || p == "own" || p == "broadcast" =>
|
||||
for sock in self.address.iter() {
|
||||
args.dbus(p, sock);
|
||||
}
|
||||
},
|
||||
},
|
||||
&_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::{config::Dbus, exec::args::ExecutionArgs};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct XDG_PORTAL;
|
||||
struct XdgPortal;
|
||||
|
||||
#[typetag::serde]
|
||||
impl Dbus for XDG_PORTAL {
|
||||
fn register(&self, args: &mut ExecutionArgs) {
|
||||
#[typetag::serde(name = "xdg_portal")]
|
||||
impl Dbus for XdgPortal {
|
||||
fn register(&self, args: &mut ExecutionArgs) {
|
||||
args.dbus("call", "org.freedesktop.portal.*=*");
|
||||
args.dbus("broadcast", "org.freedesktop.portal.*=@/org/freedesktop/portal/*");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -19,22 +19,21 @@
|
|||
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::exec::args::ExecutionArgs;
|
||||
use crate::config::InsVars;
|
||||
use crate::{config::InsVars, exec::args::ExecutionArgs};
|
||||
|
||||
use dyn_clone::{DynClone, clone_trait_object};
|
||||
use dyn_clone::{clone_trait_object, DynClone};
|
||||
|
||||
mod dir;
|
||||
pub mod home;
|
||||
pub mod root;
|
||||
mod sys;
|
||||
mod to_home;
|
||||
mod to_root;
|
||||
mod dir;
|
||||
mod sys;
|
||||
|
||||
pub enum Condition {
|
||||
Success,
|
||||
SuccessWarn(String),
|
||||
Nothing
|
||||
Nothing,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -48,7 +47,6 @@ impl Display for BindError {
|
|||
match self {
|
||||
Self::Fail(error) => write!(fmter, "{}", error),
|
||||
Self::Warn(error) => write!(fmter, "{}", error),
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -19,23 +19,27 @@
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{exec::args::ExecutionArgs,
|
||||
config::InsVars,
|
||||
config::filesystem::{Filesystem, BindError}};
|
||||
use crate::{
|
||||
config::{
|
||||
filesystem::{BindError, Filesystem},
|
||||
InsVars,
|
||||
},
|
||||
exec::args::ExecutionArgs,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DIR {
|
||||
pub struct Dir {
|
||||
#[serde(default)]
|
||||
path: Vec<String>
|
||||
path: Vec<String>,
|
||||
}
|
||||
|
||||
#[typetag::serde]
|
||||
impl Filesystem for DIR {
|
||||
#[typetag::serde(name = "dir")]
|
||||
impl Filesystem for Dir {
|
||||
fn check(&self, _vars: &InsVars) -> Result<(), BindError> {
|
||||
if self.path.len() == 0 {
|
||||
Err(BindError::Fail(format!("Path not specified.")))?
|
||||
}
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -46,6 +50,6 @@ impl Filesystem for DIR {
|
|||
}
|
||||
|
||||
fn module(&self) -> &'static str {
|
||||
"DIR"
|
||||
"dir"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -21,18 +21,22 @@ use std::path::Path;
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{exec::args::ExecutionArgs,
|
||||
config::InsVars,
|
||||
config::filesystem::{Filesystem, BindError}};
|
||||
use crate::{
|
||||
config::{
|
||||
filesystem::{BindError, Filesystem},
|
||||
InsVars,
|
||||
},
|
||||
exec::args::ExecutionArgs,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct HOME;
|
||||
pub struct Home;
|
||||
|
||||
#[typetag::serde]
|
||||
impl Filesystem for HOME {
|
||||
#[typetag::serde(name = "home")]
|
||||
impl Filesystem for Home {
|
||||
fn check(&self, vars: &InsVars) -> Result<(), BindError> {
|
||||
if ! Path::new(vars.home()).exists() {
|
||||
Err(BindError::Fail(format!("INSTANCE_HOME not found.")))?
|
||||
if !Path::new(vars.home()).exists() {
|
||||
Err(BindError::Fail(format!("Specified home directory not found.")))?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -40,10 +44,10 @@ impl Filesystem for HOME {
|
|||
fn register(&self, args: &mut ExecutionArgs, vars: &InsVars) {
|
||||
args.bind(vars.home(), vars.home_mount());
|
||||
args.env("HOME", vars.home_mount());
|
||||
args.env("USER", vars.user());
|
||||
args.env("USER", vars.user());
|
||||
}
|
||||
|
||||
fn module(&self) -> &'static str {
|
||||
"HOME"
|
||||
"home"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -21,23 +21,27 @@ use std::path::Path;
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{exec::args::ExecutionArgs,
|
||||
config::InsVars,
|
||||
config::filesystem::{Filesystem, BindError}};
|
||||
use crate::{
|
||||
config::{
|
||||
filesystem::{BindError, Filesystem},
|
||||
InsVars,
|
||||
},
|
||||
exec::args::ExecutionArgs,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ROOT;
|
||||
pub struct Root;
|
||||
|
||||
#[typetag::serde]
|
||||
impl Filesystem for ROOT {
|
||||
#[typetag::serde(name = "root")]
|
||||
impl Filesystem for Root {
|
||||
fn check(&self, vars: &InsVars) -> Result<(), BindError> {
|
||||
if ! Path::new(vars.root()).exists() {
|
||||
if !Path::new(vars.root()).exists() {
|
||||
Err(BindError::Fail(format!("Container {} not found. ", vars.instance())))?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register(&self, args: &mut ExecutionArgs, vars: &InsVars) {
|
||||
fn register(&self, args: &mut ExecutionArgs, vars: &InsVars) {
|
||||
args.robind(format!("{}/usr", vars.root()), "/usr");
|
||||
args.robind(format!("{}/etc", vars.root()), "/etc");
|
||||
args.symlink("/usr/lib", "/lib");
|
||||
|
@ -47,6 +51,6 @@ impl Filesystem for ROOT {
|
|||
}
|
||||
|
||||
fn module(&self) -> &'static str {
|
||||
"ROOT"
|
||||
"root"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -16,41 +16,44 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{exec::args::ExecutionArgs,
|
||||
config::InsVars,
|
||||
config::filesystem::{Filesystem, BindError}};
|
||||
use crate::{
|
||||
config::{
|
||||
filesystem::{BindError, Filesystem},
|
||||
InsVars,
|
||||
},
|
||||
exec::args::ExecutionArgs,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct SYSFS {
|
||||
#[serde(skip_serializing_if = "is_default_path", default = "default_path")]
|
||||
path: Vec<String>
|
||||
struct System {
|
||||
#[serde(skip_serializing_if = "is_default_path", default = "default_path")]
|
||||
path: Vec<String>,
|
||||
}
|
||||
|
||||
#[typetag::serde]
|
||||
impl Filesystem for SYSFS {
|
||||
fn check(&self, _vars: &InsVars) -> Result<(), BindError> {
|
||||
#[typetag::serde(name = "sysfs")]
|
||||
impl Filesystem for System {
|
||||
fn check(&self, _vars: &InsVars) -> Result<(), BindError> {
|
||||
for dir in self.path.iter() {
|
||||
if ! Path::new(&format!("/sys/{}",dir)).exists() {
|
||||
if !Path::new(&format!("/sys/{}", dir)).exists() {
|
||||
Err(BindError::Fail(format!("/sys/{} is inaccessible.", dir)))?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register(&self, args: &mut ExecutionArgs, _: &InsVars) {
|
||||
for dir in self.path.iter() {
|
||||
|
||||
fn register(&self, args: &mut ExecutionArgs, _: &InsVars) {
|
||||
for dir in self.path.iter() {
|
||||
args.robind(format!("/sys/{}", dir), format!("/sys/{}", dir));
|
||||
}
|
||||
}
|
||||
|
||||
fn module(&self) -> &'static str {
|
||||
"SUSFS"
|
||||
"sysfs"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,9 +62,5 @@ fn is_default_path(path: &Vec<String>) -> bool {
|
|||
}
|
||||
|
||||
fn default_path() -> Vec<String> {
|
||||
vec!("block".into(),
|
||||
"bus".into(),
|
||||
"class".into(),
|
||||
"dev".into(),
|
||||
"devices".into())
|
||||
vec!["block".into(), "bus".into(), "class".into(), "dev".into(), "devices".into()]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* pacwrap-core
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2023-2024 Xavier R.M. <sapphirus@azorium.net>
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*
|
||||
|
@ -16,57 +16,48 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{exec::args::ExecutionArgs,
|
||||
config::InsVars,
|
||||
config::filesystem::{Filesystem,
|
||||
BindError,
|
||||
default_permission,
|
||||
is_default_permission},
|
||||
constants::HOME};
|
||||
use crate::{
|
||||
config::{
|
||||
filesystem::{default_permission, is_default_permission, BindError, Filesystem},
|
||||
InsVars,
|
||||
},
|
||||
constants::HOME,
|
||||
exec::args::ExecutionArgs,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct TO_HOME {
|
||||
#[serde(skip_serializing_if = "is_default_permission", default = "default_permission")]
|
||||
permission: String,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
path: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
filesystem: Vec<Mount>
|
||||
pub struct ToHome {
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default, rename = "volumes")]
|
||||
mounts: Vec<Mount>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct Mount {
|
||||
#[serde(skip_serializing_if = "is_default_permission", default = "default_permission")]
|
||||
#[serde(skip_serializing_if = "is_default_permission", default = "default_permission")]
|
||||
permission: String,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
path: Vec<String>
|
||||
#[serde(skip_serializing_if = "String::is_empty", default)]
|
||||
path: String,
|
||||
#[serde(skip_serializing_if = "String::is_empty", default)]
|
||||
dest: String,
|
||||
}
|
||||
|
||||
#[typetag::serde]
|
||||
impl Filesystem for TO_HOME {
|
||||
#[typetag::serde(name = "to_home")]
|
||||
impl Filesystem for ToHome {
|
||||
fn check(&self, _vars: &InsVars) -> Result<(), BindError> {
|
||||
if self.path.len() > 0 {
|
||||
if let Err(e) = check_mount(&self.permission, &self.path[0]) {
|
||||
return Err(e);
|
||||
}
|
||||
} else {
|
||||
if self.filesystem.len() == 0 {
|
||||
Err(BindError::Warn(format!("Filesystem paths are undeclared."))) |