use super::*;
impl Inputs {
pub fn reserve_version_run<P: crate::napcat::doctor::Probe>(
&self,
store: &Store,
refs: &References,
source: &Instance,
evidence: &Evidence<'_, P>,
deadline: Instant,
) -> Result<NextRun> {
let mut tx = store.transaction(deadline)?;
let installation = self.with_revalidated(
&tx,
evidence.release,
evidence.witnesses,
evidence.probe,
deadline,
|_, fresh| Ok(fresh.installation().clone()),
)?;
reserve_to(
&mut tx,
refs,
source,
&installation,
evidence.release.version,
deadline,
)
}
}
pub fn rollback_installation(
store: &Store,
refs: &References,
current: &Instance,
) -> Result<Option<Installation>> {
Ok(known_origin(store, refs, current)?.and_then(|record| record.rollback_installation))
}
pub fn maintenance_operation(
store: &Store,
refs: &References,
current: &Instance,
) -> Result<Option<super::super::version_intent::Operation>> {
let Some(record) = known_origin(store, refs, current)? else {
return Ok(None);
};
let Some(reference) = &record.maintenance_reference else {
return Ok(None);
};
let original = record
.source_installation
.as_ref()
.unwrap_or(&record.installation);
Ok(Some(
super::super::version_intent::validate_transition(
store,
refs,
reference,
&record.source,
original,
&record.installation,
)?
.operation(),
))
}
pub(crate) fn references_installation(
store: &Store,
refs: &References,
current: &Instance,
installation_id: &str,
) -> Result<bool> {
if rollback_installation(store, refs, current)?.is_some_and(|old| old.id == installation_id) {
return Ok(true);
}
let Some(pending) = journal::load(
store,
refs,
false,
&source_key(¤t.id, ¤t.run_id)?,
)?
else {
return Ok(false);
};
if pending.source != *current {
return Err(conflict());
}
Ok(pending.installation.id == installation_id)
}