Bug fixes for database resolution during composition
- Container::stamp function to set new timestamp with compose_handle. - Restructured and refactored trans_ready function. - Fixed bug with progress ticker during an aggregate transaction when one or more lines are printed to std[out|err]. - Do not print containers as up-to-date upon completion of container composition nor creation in aggregate, nor if a container was composed. - TransactionState::Skip state declared and implemented. - Check for UpdateSchema(..) instead of Prepare for marking a container as updated.
This commit is contained in:
parent
5c3b9bdd5d
commit
03d942ad22
8 changed files with 60 additions and 47 deletions
|
@ -105,7 +105,7 @@ pub fn compose_handle<'a>(instance: &'a str, path: Option<&'a str>) -> Result<Co
|
||||||
err!(ConfigError::AlreadyExists(instance.into()))?
|
err!(ConfigError::AlreadyExists(instance.into()))?
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(handle(vars)?.create())
|
Ok(handle(vars)?.stamp().create())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide_new_handle<'a>(instance: &'a str, instype: ContainerType, deps: Vec<&'a str>) -> Result<ContainerHandle<'a>> {
|
pub fn provide_new_handle<'a>(instance: &'a str, instype: ContainerType, deps: Vec<&'a str>) -> Result<ContainerHandle<'a>> {
|
||||||
|
|
|
@ -108,6 +108,11 @@ impl<'a> ContainerHandle<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stamp(mut self) -> Self {
|
||||||
|
self.inner.metadata.meta_version = *UNIX_TIMESTAMP;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn config(&self) -> &ContainerRuntime {
|
pub fn config(&self) -> &ContainerRuntime {
|
||||||
&self.inner.runtime
|
&self.inner.runtime
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub enum SyncError {
|
||||||
InvalidMagicNumber,
|
InvalidMagicNumber,
|
||||||
SignalInterrupt,
|
SignalInterrupt,
|
||||||
AgentVersionMismatch,
|
AgentVersionMismatch,
|
||||||
NothingToDo(bool),
|
NothingToDo,
|
||||||
DependentContainerMissing(String),
|
DependentContainerMissing(String),
|
||||||
RecursionDepthExceeded(isize),
|
RecursionDepthExceeded(isize),
|
||||||
TargetUpstream(String),
|
TargetUpstream(String),
|
||||||
|
@ -108,7 +108,7 @@ impl Display for SyncError {
|
||||||
Self::SignalInterrupt => write!(fmter, "Signal interrupt was triggered."),
|
Self::SignalInterrupt => write!(fmter, "Signal interrupt was triggered."),
|
||||||
Self::UnableToLocateKeyrings => write!(fmter, "Unable to locate pacman keyrings."),
|
Self::UnableToLocateKeyrings => write!(fmter, "Unable to locate pacman keyrings."),
|
||||||
Self::RepoConfError(path, err) => write!(fmter, "'{}': {}", path, err),
|
Self::RepoConfError(path, err) => write!(fmter, "'{}': {}", path, err),
|
||||||
Self::NothingToDo(_) => write!(fmter, "Nothing to do."),
|
Self::NothingToDo => write!(fmter, "Nothing to do."),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
|
|
|
@ -54,15 +54,16 @@ pub type Result<T> = crate::Result<T>;
|
||||||
pub static MAGIC_NUMBER: u32 = 663445956;
|
pub static MAGIC_NUMBER: u32 = 663445956;
|
||||||
|
|
||||||
pub enum TransactionState {
|
pub enum TransactionState {
|
||||||
Complete(bool),
|
|
||||||
Prepare,
|
Prepare,
|
||||||
|
UpdateSchema(Option<SchemaState>),
|
||||||
UpToDate,
|
UpToDate,
|
||||||
PrepareForeign(bool),
|
PrepareForeign(bool),
|
||||||
Stage,
|
Stage,
|
||||||
StageForeign,
|
StageForeign,
|
||||||
UpdateSchema(Option<SchemaState>),
|
|
||||||
Commit(bool),
|
Commit(bool),
|
||||||
CommitForeign,
|
CommitForeign,
|
||||||
|
Skip,
|
||||||
|
Complete(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone)]
|
#[derive(Serialize, Deserialize, Copy, Clone)]
|
||||||
|
@ -71,12 +72,13 @@ pub enum TransactionType {
|
||||||
Remove(bool, bool, bool),
|
Remove(bool, bool, bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Copy, Clone)]
|
||||||
pub enum TransactionMode {
|
pub enum TransactionMode {
|
||||||
Foreign,
|
Foreign,
|
||||||
Local,
|
Local,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
pub enum SyncState {
|
pub enum SyncState {
|
||||||
Required,
|
Required,
|
||||||
NotRequired,
|
NotRequired,
|
||||||
|
@ -97,19 +99,19 @@ pub trait Transaction {
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct TransactionFlags: u8 {
|
pub struct TransactionFlags: u8 {
|
||||||
const NONE = 0;
|
const NONE = 0;
|
||||||
const TARGET_ONLY = 0b0000001;
|
const TARGET_ONLY = 0b0000001;
|
||||||
const PREVIEW = 0b0000010;
|
const PREVIEW = 0b0000010;
|
||||||
const NO_CONFIRM = 0b0000100;
|
const NO_CONFIRM = 0b0000100;
|
||||||
const FORCE_DATABASE = 0b0001000;
|
const FORCE_DATABASE = 0b0001000;
|
||||||
const DATABASE_ONLY = 0b0010000;
|
const DATABASE_ONLY = 0b0010000;
|
||||||
const CREATE = 0b0100000;
|
const CREATE = 0b0100000;
|
||||||
const FILESYSTEM_SYNC = 0b1000000;
|
const FILESYSTEM_SYNC = 0b1000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TransactionHandle<'a> {
|
pub struct TransactionHandle<'a> {
|
||||||
meta: &'a mut TransactionMetadata<'a>,
|
meta: &'a mut TransactionMetadata<'a>,
|
||||||
fail: bool,
|
state: SyncState,
|
||||||
agent: bool,
|
agent: bool,
|
||||||
config: Option<&'a Global>,
|
config: Option<&'a Global>,
|
||||||
alpm: Option<Alpm>,
|
alpm: Option<Alpm>,
|
||||||
|
@ -159,7 +161,7 @@ impl TransactionState {
|
||||||
Self::StageForeign => Stage::new(self, ag),
|
Self::StageForeign => Stage::new(self, ag),
|
||||||
Self::Commit(_) => Commit::new(self, ag),
|
Self::Commit(_) => Commit::new(self, ag),
|
||||||
Self::CommitForeign => Commit::new(self, ag),
|
Self::CommitForeign => Commit::new(self, ag),
|
||||||
Self::Complete(_) => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +250,7 @@ impl<'a> TransactionHandle<'a> {
|
||||||
pub fn new(metadata: &'a mut TransactionMetadata<'a>) -> Self {
|
pub fn new(metadata: &'a mut TransactionMetadata<'a>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
meta: metadata,
|
meta: metadata,
|
||||||
fail: true,
|
state: Required,
|
||||||
agent: false,
|
agent: false,
|
||||||
alpm: None,
|
alpm: None,
|
||||||
deps: None,
|
deps: None,
|
||||||
|
@ -316,11 +318,9 @@ impl<'a> TransactionHandle<'a> {
|
||||||
self.meta
|
self.meta
|
||||||
.queue
|
.queue
|
||||||
.extend(self.meta.foreign_pkgs.iter().map(|p| p.to_owned().into()).collect::<Vec<_>>());
|
.extend(self.meta.foreign_pkgs.iter().map(|p| p.to_owned().into()).collect::<Vec<_>>());
|
||||||
self.fail = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ignore(&mut self) {
|
pub fn ignore(&mut self) {
|
||||||
let mut fail = self.fail;
|
|
||||||
let alpm = self.alpm.as_mut().unwrap();
|
let alpm = self.alpm.as_mut().unwrap();
|
||||||
let config = match self.config {
|
let config = match self.config {
|
||||||
Some(config) => config,
|
Some(config) => config,
|
||||||
|
@ -355,7 +355,7 @@ impl<'a> TransactionHandle<'a> {
|
||||||
{
|
{
|
||||||
let new = match package.sync_new_version(alpm.syncdbs()) {
|
let new = match package.sync_new_version(alpm.syncdbs()) {
|
||||||
Some(new) => {
|
Some(new) => {
|
||||||
fail = false;
|
self.state = NotRequired;
|
||||||
|
|
||||||
match self.agent {
|
match self.agent {
|
||||||
true => break,
|
true => break,
|
||||||
|
@ -373,8 +373,6 @@ impl<'a> TransactionHandle<'a> {
|
||||||
*BOLD, *RESET, *BOLD_YELLOW, *RESET, *BOLD_GREEN, *RESET
|
*BOLD, *RESET, *BOLD_YELLOW, *RESET, *BOLD_GREEN, *RESET
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.fail = fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare(&mut self, trans_type: &TransactionType, flags: &TransactionFlags) -> Result<()> {
|
pub fn prepare(&mut self, trans_type: &TransactionType, flags: &TransactionFlags) -> Result<()> {
|
||||||
|
@ -496,15 +494,19 @@ impl<'a> TransactionHandle<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trans_ready(&mut self, trans_type: &TransactionType) -> Result<()> {
|
pub fn trans_ready(&mut self, trans_type: &TransactionType, trans_flags: &TransactionFlags) -> Result<SyncState> {
|
||||||
if match trans_type {
|
if match trans_type {
|
||||||
Upgrade(..) => self.alpm().trans_add().len(),
|
Upgrade(..) => !self.alpm().trans_add().is_empty(),
|
||||||
Remove(..) => self.alpm().trans_remove().len(),
|
Remove(..) => !self.alpm().trans_remove().is_empty(),
|
||||||
} > 0
|
} {
|
||||||
{
|
Ok(Required)
|
||||||
Ok(())
|
} else if trans_flags.intersects(TransactionFlags::CREATE) {
|
||||||
|
Ok(NotRequired)
|
||||||
} else {
|
} else {
|
||||||
err!(SyncError::NothingToDo(self.fail))
|
match self.state {
|
||||||
|
Required => err!(SyncError::NothingToDo),
|
||||||
|
NotRequired => Ok(NotRequired),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ pub struct TransactionAggregator<'a> {
|
||||||
action: TransactionType,
|
action: TransactionType,
|
||||||
cache: &'a ContainerCache<'a>,
|
cache: &'a ContainerCache<'a>,
|
||||||
keyring: bool,
|
keyring: bool,
|
||||||
|
tracted: bool,
|
||||||
logger: &'a mut Logger,
|
logger: &'a mut Logger,
|
||||||
flags: TransactionFlags,
|
flags: TransactionFlags,
|
||||||
targets: Option<Vec<&'a str>>,
|
targets: Option<Vec<&'a str>>,
|
||||||
|
@ -89,6 +90,7 @@ impl<'a> TransactionAggregator<'a> {
|
||||||
action: action_type,
|
action: action_type,
|
||||||
cache: inscache,
|
cache: inscache,
|
||||||
keyring: false,
|
keyring: false,
|
||||||
|
tracted: false,
|
||||||
logger: log,
|
logger: log,
|
||||||
flags: TransactionFlags::NONE,
|
flags: TransactionFlags::NONE,
|
||||||
lock: None,
|
lock: None,
|
||||||
|
@ -249,7 +251,10 @@ impl<'a> TransactionAggregator<'a> {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
self.signal(&mut handle.alpm)?;
|
self.signal(&mut handle.alpm)?;
|
||||||
|
|
||||||
if let Complete(updated) = result {
|
if let Skip = result {
|
||||||
|
handle.release();
|
||||||
|
return Ok(());
|
||||||
|
} else if let Complete(updated) = result {
|
||||||
if updated {
|
if updated {
|
||||||
self.updated.insert(inshandle.vars().instance());
|
self.updated.insert(inshandle.vars().instance());
|
||||||
|
|
||||||
|
@ -258,23 +263,24 @@ impl<'a> TransactionAggregator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.tracted = !updated;
|
||||||
handle.release();
|
handle.release();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
} else if let Prepare = result {
|
} else if let UpdateSchema(_) = result {
|
||||||
self.updated.insert(inshandle.vars().instance());
|
self.updated.insert(inshandle.vars().instance());
|
||||||
}
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if let Some(progress) = &self.progress {
|
if let Some(progress) = self.progress.as_ref() {
|
||||||
progress.finish_and_clear();
|
progress.set_draw_target(ProgressDrawTarget::hidden());
|
||||||
|
progress.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.release();
|
handle.release();
|
||||||
return match err.downcast::<SyncError>().map_err(|err| error!(SyncError::from(err)))? {
|
return match err.downcast::<SyncError>().map_err(|err| error!(SyncError::from(err)))? {
|
||||||
SyncError::TransactionFailureAgent => exit(err.kind().code()),
|
SyncError::TransactionFailureAgent => exit(err.kind().code()),
|
||||||
SyncError::NothingToDo(bool) => bool.then(|| Err(err)).unwrap_or_else(|| Ok(())),
|
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -286,7 +292,8 @@ impl<'a> TransactionAggregator<'a> {
|
||||||
fn print_complete(&mut self, filesystem_sync: bool, target_amount: u64, target: Option<&&str>) {
|
fn print_complete(&mut self, filesystem_sync: bool, target_amount: u64, target: Option<&&str>) {
|
||||||
if let Some(_) = &self.progress {
|
if let Some(_) = &self.progress {
|
||||||
let are_multiple = target_amount > 1;
|
let are_multiple = target_amount > 1;
|
||||||
let container = if filesystem_sync && self.queried.is_empty() {
|
let flagged = self.flags.intersects(TransactionFlags::PREVIEW | TransactionFlags::CREATE);
|
||||||
|
let container = if filesystem_sync && self.queried.is_empty() || flagged || self.tracted {
|
||||||
None
|
None
|
||||||
} else if are_multiple {
|
} else if are_multiple {
|
||||||
Some("Containers")
|
Some("Containers")
|
||||||
|
|
|
@ -46,6 +46,8 @@ use crate::{
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::SyncState;
|
||||||
|
|
||||||
pub struct Commit {
|
pub struct Commit {
|
||||||
state: TransactionState,
|
state: TransactionState,
|
||||||
keyring: bool,
|
keyring: bool,
|
||||||
|
@ -68,13 +70,12 @@ impl Transaction for Commit {
|
||||||
inshandle: &ContainerHandle,
|
inshandle: &ContainerHandle,
|
||||||
) -> Result<TransactionState> {
|
) -> Result<TransactionState> {
|
||||||
let instance = inshandle.vars().instance();
|
let instance = inshandle.vars().instance();
|
||||||
let ready = handle.trans_ready(&ag.action());
|
|
||||||
let state = self.state.as_str();
|
let state = self.state.as_str();
|
||||||
|
|
||||||
if let Err(_) = ready {
|
if let SyncState::NotRequired = handle.trans_ready(&ag.action(), ag.flags())? {
|
||||||
match ready_state(handle, ag.action(), &self.state) {
|
match ready_state(handle, ag.action(), &self.state) {
|
||||||
Some(result) => return result,
|
Some(result) => return result,
|
||||||
None => ready?,
|
None => return Ok(TransactionState::Complete(false)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +103,7 @@ impl Transaction for Commit {
|
||||||
|
|
||||||
handle.set_alpm(Some(sync::instantiate_alpm(inshandle)));
|
handle.set_alpm(Some(sync::instantiate_alpm(inshandle)));
|
||||||
handle.apply_configuration(inshandle, ag.flags().intersects(TransactionFlags::CREATE))?;
|
handle.apply_configuration(inshandle, ag.flags().intersects(TransactionFlags::CREATE))?;
|
||||||
ag.logger()
|
ag.logger().log(Info, &format!("container {instance}'s {state} transaction complete"))?;
|
||||||
.log(Info, &format!("container {instance}'s {state} transaction complete"))
|
|
||||||
.ok();
|
|
||||||
next_state(handle, ag.action(), &self.state, true)
|
next_state(handle, ag.action(), &self.state, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,11 +115,11 @@ fn confirm(
|
||||||
) -> StdResult<(u64, u64), Result<TransactionState>> {
|
) -> StdResult<(u64, u64), Result<TransactionState>> {
|
||||||
let database = ag.flags().intersects(TransactionFlags::DATABASE_ONLY | TransactionFlags::FORCE_DATABASE);
|
let database = ag.flags().intersects(TransactionFlags::DATABASE_ONLY | TransactionFlags::FORCE_DATABASE);
|
||||||
let foreign = !handle.get_mode().bool();
|
let foreign = !handle.get_mode().bool();
|
||||||
let create_foreign = match handle.get_mode() {
|
let create = match handle.get_mode() {
|
||||||
TransactionMode::Foreign => ag.flags().contains(TransactionFlags::CREATE),
|
TransactionMode::Foreign => ag.flags().intersects(TransactionFlags::CREATE),
|
||||||
TransactionMode::Local => false,
|
TransactionMode::Local => false,
|
||||||
};
|
};
|
||||||
let confirm = foreign || database && !create_foreign;
|
let confirm = foreign || database && !create;
|
||||||
let sum = Summary::new()
|
let sum = Summary::new()
|
||||||
.kind(CONFIG.config().summary(), confirm)
|
.kind(CONFIG.config().summary(), confirm)
|
||||||
.mode(handle.get_mode())
|
.mode(handle.get_mode())
|
||||||
|
|
|
@ -85,10 +85,10 @@ impl Transaction for Prepare {
|
||||||
|
|
||||||
if let Upgrade(upgrade, ..) = action {
|
if let Upgrade(upgrade, ..) = action {
|
||||||
if !upgrade && handle.meta.queue.is_empty() {
|
if !upgrade && handle.meta.queue.is_empty() {
|
||||||
err!(SyncError::NothingToDo(true))?
|
err!(SyncError::NothingToDo)?
|
||||||
}
|
}
|
||||||
} else if handle.meta.queue.is_empty() {
|
} else if handle.meta.queue.is_empty() {
|
||||||
err!(SyncError::NothingToDo(true))?
|
err!(SyncError::NothingToDo)?
|
||||||
}
|
}
|
||||||
|
|
||||||
if handle.meta.queue.is_empty() {
|
if handle.meta.queue.is_empty() {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionAggregator,
|
TransactionAggregator,
|
||||||
TransactionHandle,
|
TransactionHandle,
|
||||||
TransactionState::{self, Complete},
|
TransactionState::{self, Skip},
|
||||||
},
|
},
|
||||||
Result,
|
Result,
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,6 @@ impl Transaction for UpToDate {
|
||||||
None => println!("{} {} is up-to-date!", *ARROW_GREEN, handle.vars().instance()),
|
None => println!("{} {} is up-to-date!", *ARROW_GREEN, handle.vars().instance()),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Complete(false))
|
Ok(Skip)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue