Refactor/project structure (#3085)

* refactor project structure

* environment-based default registry

* fix tests

* update build container

* use docker platform for iso build emulation

* simplify compat

* Fix docker platform spec in run-compat.sh

* handle riscv compat

* fix bug with dep error exists attr

* undo removal of sorting

* use qemu for iso stage

---------

Co-authored-by: Mariusz Kogen <k0gen@pm.me>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
This commit is contained in:
Aiden McClelland
2025-12-22 13:39:38 -07:00
committed by GitHub
parent eda08d5b0f
commit 96ae532879
389 changed files with 744 additions and 4005 deletions

View File

@@ -0,0 +1,100 @@
use std::str::FromStr;
use clap::builder::ValueParserFactory;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
pub use crate::HealthCheckId;
use crate::util::FromStrParser;
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
pub struct NamedHealthCheckResult {
pub name: String,
#[serde(flatten)]
pub kind: NamedHealthCheckResultKind,
}
// healthCheckName:kind:message OR healthCheckName:kind
impl FromStr for NamedHealthCheckResult {
type Err = color_eyre::eyre::Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let from_parts = |name: &str, kind: &str, message: Option<&str>| {
let message = message.map(|x| x.to_string());
let kind = match kind {
"success" => NamedHealthCheckResultKind::Success { message },
"disabled" => NamedHealthCheckResultKind::Disabled { message },
"starting" => NamedHealthCheckResultKind::Starting { message },
"loading" => NamedHealthCheckResultKind::Loading {
message: message.unwrap_or_default(),
},
"failure" => NamedHealthCheckResultKind::Failure {
message: message.unwrap_or_default(),
},
_ => return Err(color_eyre::eyre::eyre!("Invalid health check kind")),
};
Ok(Self {
name: name.to_string(),
kind,
})
};
let parts = s.split(':').collect::<Vec<_>>();
match &*parts {
[name, kind, message] => from_parts(name, kind, Some(message)),
[name, kind] => from_parts(name, kind, None),
_ => Err(color_eyre::eyre::eyre!(
"Could not match the shape of the result ${parts:?}"
)),
}
}
}
impl ValueParserFactory for NamedHealthCheckResult {
type Parser = FromStrParser<Self>;
fn value_parser() -> Self::Parser {
FromStrParser::new()
}
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "result")]
pub enum NamedHealthCheckResultKind {
Success { message: Option<String> },
Disabled { message: Option<String> },
Starting { message: Option<String> },
Loading { message: String },
Failure { message: String },
}
impl std::fmt::Display for NamedHealthCheckResult {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = &self.name;
match &self.kind {
NamedHealthCheckResultKind::Success { message } => {
if let Some(message) = message {
write!(f, "{name}: Succeeded ({message})")
} else {
write!(f, "{name}: Succeeded")
}
}
NamedHealthCheckResultKind::Disabled { message } => {
if let Some(message) = message {
write!(f, "{name}: Disabled ({message})")
} else {
write!(f, "{name}: Disabled")
}
}
NamedHealthCheckResultKind::Starting { message } => {
if let Some(message) = message {
write!(f, "{name}: Starting ({message})")
} else {
write!(f, "{name}: Starting")
}
}
NamedHealthCheckResultKind::Loading { message } => {
write!(f, "{name}: Loading ({message})")
}
NamedHealthCheckResultKind::Failure { message } => {
write!(f, "{name}: Failed ({message})")
}
}
}
}

143
core/src/status/mod.rs Normal file
View File

@@ -0,0 +1,143 @@
use std::collections::BTreeMap;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::HealthCheckId;
use crate::error::ErrorData;
use crate::prelude::*;
use crate::service::start_stop::StartStop;
use crate::status::health_check::NamedHealthCheckResult;
pub mod health_check;
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
pub struct StatusInfo {
pub health: BTreeMap<HealthCheckId, NamedHealthCheckResult>,
pub error: Option<ErrorData>,
#[ts(type = "string | null")]
pub started: Option<DateTime<Utc>>,
pub desired: DesiredStatus,
}
impl StatusInfo {
pub fn stop(&mut self) {
self.desired = self.desired.stop();
self.health.clear();
}
}
impl Model<StatusInfo> {
pub fn start(&mut self) -> Result<(), Error> {
self.as_desired_mut().map_mutate(|s| Ok(s.start()))?;
Ok(())
}
pub fn started(&mut self) -> Result<(), Error> {
self.as_started_mut()
.map_mutate(|s| Ok(Some(s.unwrap_or_else(|| Utc::now()))))?;
self.as_desired_mut().map_mutate(|s| {
Ok(match s {
DesiredStatus::Restarting => DesiredStatus::Running,
a => a,
})
})?;
Ok(())
}
pub fn stop(&mut self) -> Result<(), Error> {
self.as_desired_mut().map_mutate(|s| Ok(s.stop()))?;
self.as_health_mut().ser(&Default::default())?;
Ok(())
}
pub fn stopped(&mut self) -> Result<(), Error> {
self.as_started_mut().ser(&None)?;
Ok(())
}
pub fn init(&mut self) -> Result<(), Error> {
self.as_started_mut().ser(&None)?;
self.as_desired_mut().map_mutate(|s| {
Ok(match s {
DesiredStatus::BackingUp {
on_complete: StartStop::Start,
} => DesiredStatus::Running,
DesiredStatus::BackingUp {
on_complete: StartStop::Stop,
} => DesiredStatus::Stopped,
DesiredStatus::Restarting => DesiredStatus::Running,
x => x,
})
})?;
Ok(())
}
}
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(tag = "main")]
#[serde(rename_all = "kebab-case")]
#[serde(rename_all_fields = "camelCase")]
pub enum DesiredStatus {
Stopped,
Restarting,
Running,
BackingUp { on_complete: StartStop },
}
impl Default for DesiredStatus {
fn default() -> Self {
Self::Stopped
}
}
impl DesiredStatus {
pub fn running(&self) -> bool {
match self {
Self::Running
| Self::Restarting
| Self::BackingUp {
on_complete: StartStop::Start,
} => true,
Self::Stopped
| Self::BackingUp {
on_complete: StartStop::Stop,
} => false,
}
}
pub fn run_state(&self) -> StartStop {
if self.running() {
StartStop::Start
} else {
StartStop::Stop
}
}
pub fn backing_up(&self) -> Self {
Self::BackingUp {
on_complete: self.run_state(),
}
}
pub fn stop(&self) -> Self {
match self {
Self::BackingUp { .. } => Self::BackingUp {
on_complete: StartStop::Stop,
},
_ => Self::Stopped,
}
}
pub fn start(&self) -> Self {
match self {
Self::BackingUp { .. } => Self::BackingUp {
on_complete: StartStop::Start,
},
Self::Stopped => Self::Running,
x => *x,
}
}
pub fn restart(&self) -> Self {
match self {
Self::Running => Self::Restarting,
x => *x, // no-op: restart is meaningless in any other state
}
}
}