Skip to content

Commit

Permalink
Merge pull request #896 from cgwalters/autoexit-custom
Browse files Browse the repository at this point in the history
service: exit and prevent restarts if booted into a container image
  • Loading branch information
cgwalters committed Nov 21, 2022
2 parents ebb241c + de798dd commit 0203478
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 9 deletions.
2 changes: 2 additions & 0 deletions dist/systemd/system/zincati.service
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ Environment=ZINCATI_VERBOSITY="-v"
Type=notify
ExecStart=/usr/libexec/zincati agent ${ZINCATI_VERBOSITY}
Restart=on-failure
# This status signals a non-restartable condition
RestartPreventExitStatus=7
RestartSec=10s

[Install]
Expand Down
15 changes: 11 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,27 @@ fn run() -> i32 {
match cli_opts.run() {
Ok(_) => libc::EXIT_SUCCESS,
Err(e) => {
log_error_chain(e);
libc::EXIT_FAILURE
log_error_chain(&e);
if e.root_cause()
.downcast_ref::<crate::rpm_ostree::FatalError>()
.is_some()
{
7
} else {
libc::EXIT_FAILURE
}
}
}
}

/// Pretty-print a chain of errors, as a series of error-priority log messages.
fn log_error_chain(err_chain: anyhow::Error) {
fn log_error_chain(err_chain: &anyhow::Error) {
let mut chain_iter = err_chain.chain();
let top_err = match chain_iter.next() {
Some(e) => e.to_string(),
None => "(unspecified failure)".to_string(),
};
log::error!("critical error: {}", top_err);
log::error!("error: {}", top_err);
for err in chain_iter {
log::error!(" -> {}", err);
}
Expand Down
30 changes: 26 additions & 4 deletions src/rpm_ostree/cli_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ lazy_static::lazy_static! {
)).unwrap();
}

/// An error which should not result in a retry/restart.
#[derive(Debug, Clone)]
pub struct FatalError(String);

impl std::fmt::Display for FatalError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}

impl std::error::Error for FatalError {}

/// JSON output from `rpm-ostree status --json`
#[derive(Clone, Debug, Deserialize)]
pub struct StatusJson {
Expand All @@ -48,6 +60,7 @@ pub struct StatusJson {
#[serde(rename_all = "kebab-case")]
pub struct DeploymentJson {
booted: bool,
container_image_reference: Option<String>,
base_checksum: Option<String>,
#[serde(rename = "base-commit-meta")]
base_metadata: BaseCommitMetaJson,
Expand All @@ -62,7 +75,7 @@ pub struct DeploymentJson {
#[derive(Clone, Debug, Deserialize)]
struct BaseCommitMetaJson {
#[serde(rename = "fedora-coreos.stream")]
stream: String,
stream: Option<String>,
}

impl DeploymentJson {
Expand All @@ -85,12 +98,21 @@ impl DeploymentJson {

/// Parse the booted deployment from status object.
pub fn parse_booted(status: &StatusJson) -> Result<Release> {
let json = booted_json(status)?;
Ok(json.into_release())
let status = booted_json(status)?;
if let Some(img) = status.container_image_reference.as_ref() {
let msg = format!("Automatic updates disabled; booted into container image {img}");
crate::utils::update_unit_status(&msg);
return Err(anyhow::Error::new(FatalError(msg)));
}
Ok(status.into_release())
}

fn fedora_coreos_stream_from_deployment(deploy: &DeploymentJson) -> Result<String> {
let stream = deploy.base_metadata.stream.as_str();
let stream = deploy
.base_metadata
.stream
.as_ref()
.ok_or_else(|| anyhow!("Missing `fedora-coreos.stream` in commit metadata"))?;
ensure!(!stream.is_empty(), "empty stream value");
Ok(stream.to_string())
}
Expand Down
2 changes: 1 addition & 1 deletion src/rpm_ostree/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod cli_deploy;
mod cli_finalize;
mod cli_status;
pub use cli_status::{invoke_cli_status, parse_booted, parse_booted_updates_stream};
pub use cli_status::{invoke_cli_status, parse_booted, parse_booted_updates_stream, FatalError};

mod actor;
pub use actor::{
Expand Down

0 comments on commit 0203478

Please sign in to comment.