Updated creation code with new --dep parameter.
- New --dep parameter to be used in place of --target to specify container dependencies to configure a container on creation, allowing for multiple containers to be created in one invocation. - Bug fix applied to creation of base containers - pacwrap-utils updated to be compatible with the proceeding changes.
This commit is contained in:
parent
728185d960
commit
8b588c4ee8
3 changed files with 89 additions and 80 deletions
|
@ -334,14 +334,10 @@ invoke_replication() {
|
||||||
|
|
||||||
for dep in ${deps[@]}; do replicate_instance $dep; done
|
for dep in ${deps[@]}; do replicate_instance $dep; done
|
||||||
|
|
||||||
for depr in $deps_return; do
|
|
||||||
[[ ! -d "$INSTANCE_ROOT_DIR/$depr" ]] &&
|
|
||||||
log_error "Dependency $depr not fulfilled for $instance." 1
|
|
||||||
done
|
|
||||||
|
|
||||||
replicate_instance $instance
|
replicate_instance $instance
|
||||||
done
|
done
|
||||||
|
|
||||||
|
$CREATE_SCRIPT -Syu --create $REPLICATE_CMD --noconfirm
|
||||||
}
|
}
|
||||||
|
|
||||||
replicate_instance() {
|
replicate_instance() {
|
||||||
|
@ -353,7 +349,7 @@ replicate_instance() {
|
||||||
|
|
||||||
local depend=
|
local depend=
|
||||||
local type=$(return_type)
|
local type=$(return_type)
|
||||||
local params="c"
|
local params="-"
|
||||||
|
|
||||||
[[ $SWITCH == *v* ]] && params+="v"
|
[[ $SWITCH == *v* ]] && params+="v"
|
||||||
[[ $type != BASE ]] && depend=$(return_dependency)
|
[[ $type != BASE ]] && depend=$(return_dependency)
|
||||||
|
@ -361,7 +357,7 @@ replicate_instance() {
|
||||||
case $type in
|
case $type in
|
||||||
ROOT) params+="r";;
|
ROOT) params+="r";;
|
||||||
BASE) params+="b";;
|
BASE) params+="b";;
|
||||||
DEP) params+="d";;
|
DEP) params+="s";;
|
||||||
LINK) ln -s "$INSTANCE_ROOT_DIR/$depend" "$INSTANCE_ROOT_DIR/$instance"
|
LINK) ln -s "$INSTANCE_ROOT_DIR/$depend" "$INSTANCE_ROOT_DIR/$instance"
|
||||||
mkdir -p "$INSTANCE_HOME_DIR/$instance"
|
mkdir -p "$INSTANCE_HOME_DIR/$instance"
|
||||||
echo 'PS1="'$instance'> "' > "$INSTANCE_HOME_DIR/$instance/.bashrc"
|
echo 'PS1="'$instance'> "' > "$INSTANCE_HOME_DIR/$instance/.bashrc"
|
||||||
|
@ -375,16 +371,10 @@ replicate_instance() {
|
||||||
local depend_params
|
local depend_params
|
||||||
|
|
||||||
for dep in $(return_dependencies); do
|
for dep in $(return_dependencies); do
|
||||||
depend_params+="-t $dep "
|
depend_params+="--dep=$dep "
|
||||||
done
|
done
|
||||||
|
|
||||||
$CREATE_SCRIPT -Syu$params -t $instance $(return_packages) $foreign_targets $depend_params --noconfirm
|
REPLICATE_CMD+="$params -t $instance $(return_packages) $foreign_targets $depend_params "
|
||||||
|
|
||||||
if [[ $? == 0 ]]; then
|
|
||||||
printf " %s$RESET\n" "Replication of $BOLD$instance$RESET complete!"
|
|
||||||
log_to_file "Replication of $instance complete!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
completed[$instance]=1
|
completed[$instance]=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ fn ascertain_help<'a>(args: &mut Arguments) -> Result<(IndexSet<&'a HelpTopic>,
|
||||||
=> topic.extend(HELP_ALL.iter()),
|
=> topic.extend(HELP_ALL.iter()),
|
||||||
Operand::ShortPos('h', topic)
|
Operand::ShortPos('h', topic)
|
||||||
| Operand::LongPos("help", topic)
|
| Operand::LongPos("help", topic)
|
||||||
=> Err(ErrorKind::TopicUnavailable(topic.to_string()))?,
|
=> Err(ErrorKind::Message(format!("Topic '{topic}' is not available.").leak()))?,
|
||||||
_ => Err(args.invalid_operand())?,
|
_ => Err(args.invalid_operand())?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ fn sync(buf: &mut String, layout: &HelpLayout) -> Result<(), std::fmt::Error> {
|
||||||
|
|
||||||
{sub}-u, --upgrade{reset_bold}
|
{sub}-u, --upgrade{reset_bold}
|
||||||
{tab}{tab}Execute aggregate upgrade routine on all or specified containers. Use {bold}-t, --target=TARGET{reset_bold} to limit
|
{tab}{tab}Execute aggregate upgrade routine on all or specified containers. Use {bold}-t, --target=TARGET{reset_bold} to limit
|
||||||
{tab}{tab}package synhronization operations to the specified target containers. Packages applicable to
|
{tab}{tab}package synchronization operations to the specified target containers. Packages applicable to
|
||||||
{tab}{tab}a target {bold}must{reset_bold} be specified only after the target operand.
|
{tab}{tab}a target {bold}must{reset_bold} be specified only after the target operand.
|
||||||
{tab}{tab}e.g. '-t electron element-desktop -t mozilla firefox thunderbird'
|
{tab}{tab}e.g. '-t electron element-desktop -t mozilla firefox thunderbird'
|
||||||
|
|
||||||
|
@ -341,9 +341,9 @@ fn sync(buf: &mut String, layout: &HelpLayout) -> Result<(), std::fmt::Error> {
|
||||||
{tab}{tab}dependency per slice or per root is supported. Filesystem and package deduplication via slices
|
{tab}{tab}dependency per slice or per root is supported. Filesystem and package deduplication via slices
|
||||||
{tab}{tab}and root containers is recommended, but optional.
|
{tab}{tab}and root containers is recommended, but optional.
|
||||||
|
|
||||||
{sub}-d, --slice{reset_bold}
|
{sub}-s, --slice{reset_bold}
|
||||||
{tab}{tab}Slice container type. Specify alongside {bold}-c, --create{reset_bold} to assign this container type during creation.
|
{tab}{tab}Slice container type. Specify alongside {bold}-c, --create{reset_bold} to assign this container type during creation.
|
||||||
{tab}{tab}Requires a base dependency target, and optionally sliced dependency target(s), in order to ascertain
|
{tab}{tab}Requires a base dependency be specified, and one or more sliced dependencies, in order to ascertain
|
||||||
{tab}{tab}foreign packages and influence ordering of downstream synchronization target(s). Container slicing
|
{tab}{tab}foreign packages and influence ordering of downstream synchronization target(s). Container slicing
|
||||||
{tab}{tab}provides the ability to install packages in a lightweight, sliced filesytem, which aid in the
|
{tab}{tab}provides the ability to install packages in a lightweight, sliced filesytem, which aid in the
|
||||||
{tab}{tab}deduplication of common downstream package and filesystem dependencies e.g. graphics drivers,
|
{tab}{tab}deduplication of common downstream package and filesystem dependencies e.g. graphics drivers,
|
||||||
|
@ -351,13 +351,16 @@ fn sync(buf: &mut String, layout: &HelpLayout) -> Result<(), std::fmt::Error> {
|
||||||
|
|
||||||
{sub}-r, --root{reset_bold}
|
{sub}-r, --root{reset_bold}
|
||||||
{tab}{tab}Root container type. Specify alongside {bold}-c, --create{reset_bold} to this assign container type during creation.
|
{tab}{tab}Root container type. Specify alongside {bold}-c, --create{reset_bold} to this assign container type during creation.
|
||||||
{tab}{tab}Requires a base dependency target, and optionally sliced dependency targets, in order to ascertain
|
{tab}{tab}Requires a base dependency be specified, and optionally one or more sliced dependencies, in order
|
||||||
{tab}{tab}foreign packages and influence ordering of this target. These containers are ideal for installing
|
{tab}{tab}to ascertain foreign packages and influence ordering of this target. These containers are ideal
|
||||||
{tab}{tab}software in with the least amount of filesystem and package synchronization overhead.
|
{tab}{tab}for installing software in with the least amount of filesystem and package synchronization overhead.
|
||||||
|
|
||||||
{sub}-t, --target=TARGET{reset_bold}
|
{sub}-t, --target=TARGET{reset_bold}
|
||||||
{tab}{tab}Specify a target container for the specified operation.
|
{tab}{tab}Specify a target container for the specified operation.
|
||||||
|
|
||||||
|
{sub}-d, --dep=DEPEND{reset_bold}
|
||||||
|
{tab}{tab}Specify a dependency container for the specified operation.
|
||||||
|
|
||||||
{sub}-o, --target-only{reset_bold}
|
{sub}-o, --target-only{reset_bold}
|
||||||
{tab}{tab}Apply specified operation on the specified target only.
|
{tab}{tab}Apply specified operation on the specified target only.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
use std::{collections::HashMap, fs::File};
|
use std::{collections::HashMap, fs::File};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::process::exit;
|
|
||||||
|
|
||||||
|
use indexmap::IndexMap;
|
||||||
use pacwrap_core::{ErrorKind,
|
use pacwrap_core::{ErrorKind,
|
||||||
log::Logger,
|
log::Logger,
|
||||||
sync::transaction::TransactionType,
|
sync::transaction::TransactionType,
|
||||||
utils::{arguments::{Arguments,
|
utils::arguments::{Arguments,
|
||||||
InvalidArgument,
|
InvalidArgument,
|
||||||
Operand},
|
Operand},
|
||||||
print_error},
|
|
||||||
config::{self,
|
config::{self,
|
||||||
InstanceType,
|
InstanceType,
|
||||||
InsVars,
|
InsVars,
|
||||||
|
@ -37,7 +36,7 @@ pub fn synchronize(mut args: &mut Arguments) -> Result<(), ErrorKind> {
|
||||||
|
|
||||||
config::init::init();
|
config::init::init();
|
||||||
|
|
||||||
if let Some(instype) = create(&mut args)? {
|
if create(&mut args) {
|
||||||
if let TransactionType::Upgrade(upgrade, refresh, _) = action {
|
if let TransactionType::Upgrade(upgrade, refresh, _) = action {
|
||||||
if ! refresh {
|
if ! refresh {
|
||||||
Err(ErrorKind::Argument(InvalidArgument::UnsuppliedOperand("--refresh", "Required for container creation.")))?
|
Err(ErrorKind::Argument(InvalidArgument::UnsuppliedOperand("--refresh", "Required for container creation.")))?
|
||||||
|
@ -46,64 +45,84 @@ pub fn synchronize(mut args: &mut Arguments) -> Result<(), ErrorKind> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate(instype, args.targets())?
|
instantiate(acquire_depends(args)?)?
|
||||||
}
|
}
|
||||||
|
|
||||||
engage_aggregator(action, &mut args, &mut logger)
|
engage_aggregator(action, &mut args, &mut logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create<'a>(args: &mut Arguments) -> Result<Option<InstanceType>, ErrorKind> {
|
fn acquire_depends<'a>(args: &'a mut Arguments) -> Result<IndexMap<&'a str, (InstanceType, Vec<&'a str>)>, ErrorKind> {
|
||||||
|
let mut deps: IndexMap<&'a str, (InstanceType, Vec<&'a str>)> = IndexMap::new();
|
||||||
|
let mut current_target = "";
|
||||||
let mut instype = None;
|
let mut instype = None;
|
||||||
let mut create = false;
|
|
||||||
|
|
||||||
args.set_index(1);
|
args.set_index(1);
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match arg {
|
match arg {
|
||||||
Operand::Short('c') | Operand::Long("create") => create = true,
|
Operand::ShortPos('d', dep)
|
||||||
Operand::Short('b') | Operand::Long("base") => match instype {
|
| Operand::LongPos("dep", dep) => match deps.get_mut(current_target) {
|
||||||
None => instype = Some(InstanceType::BASE),
|
Some(d) => {
|
||||||
Some(_) => Err(ErrorKind::DuplicateType)?,
|
if let Some(instype) = instype {
|
||||||
|
if let InstanceType::BASE = instype {
|
||||||
|
Err(ErrorKind::Message("Dependencies cannot be assigned to base containers."))?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
d.1.push(dep);
|
||||||
},
|
},
|
||||||
Operand::Short('d') | Operand::Long("slice") => match instype {
|
None => Err(ErrorKind::Argument(InvalidArgument::TargetUnspecified))?
|
||||||
None => instype = Some(InstanceType::DEP),
|
|
||||||
Some(_) => Err(ErrorKind::DuplicateType)?,
|
|
||||||
},
|
},
|
||||||
Operand::Short('r') | Operand::Long("root") => match instype {
|
Operand::Short('b')
|
||||||
None => instype = Some(InstanceType::ROOT),
|
| Operand::Long("base") => instype = Some(InstanceType::BASE),
|
||||||
Some(_) => Err(ErrorKind::DuplicateType)?,
|
Operand::Short('s')
|
||||||
|
| Operand::Long("slice") => instype = Some(InstanceType::DEP),
|
||||||
|
Operand::Short('r')
|
||||||
|
| Operand::Long("root") => instype = Some(InstanceType::ROOT),
|
||||||
|
Operand::ShortPos('t', target)
|
||||||
|
| Operand::LongPos("target", target) => match instype {
|
||||||
|
Some(instype) => {
|
||||||
|
current_target = target;
|
||||||
|
deps.insert(current_target, (instype, vec!()));
|
||||||
|
},
|
||||||
|
None => Err(ErrorKind::Message("Container type not specified."))?,
|
||||||
},
|
},
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match create {
|
if current_target.len() == 0 {
|
||||||
true => match instype {
|
|
||||||
None => Err(ErrorKind::Message("Container type unspecified."))?, Some(_) => Ok(instype),
|
|
||||||
},
|
|
||||||
false => Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn instantiate(instype: InstanceType, mut targets: Vec<&str>) -> Result<(), ErrorKind> {
|
|
||||||
if targets.len() == 0 {
|
|
||||||
Err(ErrorKind::Argument(InvalidArgument::TargetUnspecified))?
|
Err(ErrorKind::Argument(InvalidArgument::TargetUnspecified))?
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = targets.remove(0);
|
Ok(deps)
|
||||||
|
}
|
||||||
|
|
||||||
if let InstanceType::ROOT | InstanceType::DEP = instype {
|
|
||||||
if target.len() == 0 {
|
fn create(args: &mut Arguments) -> bool {
|
||||||
Err(ErrorKind::Message("Dependencies not specified."))?
|
args.set_index(1);
|
||||||
|
|
||||||
|
while let Some(arg) = args.next() {
|
||||||
|
match arg {
|
||||||
|
Operand::Short('c') | Operand::Long("create") => return true,
|
||||||
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
instantiate_container(target, targets, instype)
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instantiate_container(ins: &str, deps: Vec<&str>, instype: InstanceType) -> Result<(), ErrorKind> {
|
fn instantiate<'a>(targets: IndexMap<&'a str, (InstanceType, Vec<&'a str>)>) -> Result<(), ErrorKind> {
|
||||||
println!("{} {}Instantiating container {ins}{}", *BAR_GREEN, *BOLD, *RESET);
|
println!("{} {}Instantiating container{}{}", *BAR_GREEN, *BOLD, if targets.len() > 1 { "s" } else { "" }, *RESET);
|
||||||
|
|
||||||
|
for target in targets {
|
||||||
|
instantiate_container(target.0, target.1.0, target.1.1)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate_container(ins: &str, instype: InstanceType, deps: Vec<&str>) -> Result<(), ErrorKind> {
|
||||||
let deps = deps.iter().map(|a| { let a = *a; a.into() }).collect();
|
let deps = deps.iter().map(|a| { let a = *a; a.into() }).collect();
|
||||||
let mut logger = Logger::new("pacwrap").init().unwrap();
|
let mut logger = Logger::new("pacwrap").init().unwrap();
|
||||||
let instance = match config::provide_new_handle(ins) {
|
let instance = match config::provide_new_handle(ins) {
|
||||||
|
@ -120,7 +139,7 @@ fn instantiate_container(ins: &str, deps: Vec<&str>, instype: InstanceType) -> R
|
||||||
|
|
||||||
if let Err(err) = std::fs::create_dir(instance.vars().root()) {
|
if let Err(err) = std::fs::create_dir(instance.vars().root()) {
|
||||||
if let std::io::ErrorKind::AlreadyExists = err.kind() {
|
if let std::io::ErrorKind::AlreadyExists = err.kind() {
|
||||||
Err(ErrorKind::Message("Container root already exists."))?
|
Err(ErrorKind::Message(format!("Container {ins} already exists.").leak()))?
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::IOError(instance.vars().root().into(), err.kind()))?
|
Err(ErrorKind::IOError(instance.vars().root().into(), err.kind()))?
|
||||||
}
|
}
|
||||||
|
@ -129,8 +148,7 @@ fn instantiate_container(ins: &str, deps: Vec<&str>, instype: InstanceType) -> R
|
||||||
if let InstanceType::ROOT | InstanceType::BASE = instype {
|
if let InstanceType::ROOT | InstanceType::BASE = instype {
|
||||||
if let Err(err) = std::fs::create_dir(instance.vars().home()) {
|
if let Err(err) = std::fs::create_dir(instance.vars().home()) {
|
||||||
if err.kind() != std::io::ErrorKind::AlreadyExists {
|
if err.kind() != std::io::ErrorKind::AlreadyExists {
|
||||||
print_error(format!("'{}': {}", instance.vars().root(), err));
|
Err(ErrorKind::IOError(instance.vars().root().into(), err.kind()))?
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +165,7 @@ fn instantiate_container(ins: &str, deps: Vec<&str>, instype: InstanceType) -> R
|
||||||
config::save_handle(&instance).ok();
|
config::save_handle(&instance).ok();
|
||||||
logger.log(format!("Configuration file created for {ins}")).unwrap();
|
logger.log(format!("Configuration file created for {ins}")).unwrap();
|
||||||
drop(instance);
|
drop(instance);
|
||||||
println!("{} Instantiation complete.", *ARROW_GREEN);
|
println!("{} Instantiation of {ins} complete.", *ARROW_GREEN);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +185,9 @@ fn engage_aggregator<'a>(
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match arg {
|
match arg {
|
||||||
Operand::Short('d') | Operand::Long("slice")
|
Operand::Short('d')
|
||||||
|
| Operand::Long("dep") | Operand::LongPos("dep", _)
|
||||||
|
| Operand::Short('s') | Operand::Long("slice")
|
||||||
| Operand::Short('r') | Operand::Long("root")
|
| Operand::Short('r') | Operand::Long("root")
|
||||||
| Operand::Short('t') | Operand::Long("target")
|
| Operand::Short('t') | Operand::Long("target")
|
||||||
| Operand::Short('y') | Operand::Long("refresh")
|
| Operand::Short('y') | Operand::Long("refresh")
|
||||||
|
@ -197,20 +217,16 @@ fn engage_aggregator<'a>(
|
||||||
| Operand::LongPos("target", target) => {
|
| Operand::LongPos("target", target) => {
|
||||||
current_target = target;
|
current_target = target;
|
||||||
targets.push(target);
|
targets.push(target);
|
||||||
|
|
||||||
|
if base {
|
||||||
|
queue.insert(current_target.into(), vec!("base", "pacwrap-base-dist"));
|
||||||
|
base = false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Operand::Value(package) => if current_target != "" {
|
Operand::Value(package) => if current_target != "" {
|
||||||
match queue.get_mut(current_target.into()) {
|
match queue.get_mut(current_target.into()) {
|
||||||
Some(vec) => vec.push(package.into()),
|
Some(vec) => vec.push(package.into()),
|
||||||
None => {
|
None => { queue.insert(current_target.into(), vec!(package)); },
|
||||||
let packages = if base {
|
|
||||||
base = false;
|
|
||||||
vec!(package, "base", "pacwrap-base-dist")
|
|
||||||
} else {
|
|
||||||
vec!(package)
|
|
||||||
};
|
|
||||||
|
|
||||||
queue.insert(current_target.into(), packages);
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => Err(args.invalid_operand())?
|
_ => Err(args.invalid_operand())?
|
||||||
|
|
Loading…
Reference in a new issue