Files
start-os/core/src/status/mod.rs
Aiden McClelland 99871805bd hardware acceleration and support for NVIDIA cards on nonfree images (#3089)
* add nvidia packages

* add nvidia deps to nonfree

* gpu_acceleration flag & nvidia hacking

* fix gpu_config & /tmp/lxc.log

* implement hardware acceleration more dynamically

* refactor OpenUI

* use mknod

* registry updates for multi-hardware-requirements

* pluralize

* handle new registry types

* remove log

* migrations and driver fixes

* wip

* misc patches

* handle nvidia-container differently

* chore: comments (#3093)

* chore: comments

* revert some sizing

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* Revert "handle nvidia-container differently"

This reverts commit d708ae53df.

* fix debian containers

* cleanup

* feat: add empty array placeholder in forms (#3095)

* fixes from testing, client side device filtering for better fingerprinting resistance

* fix mac builds

---------

Co-authored-by: Sam Sartor <me@samsartor.com>
Co-authored-by: Matt Hill <mattnine@protonmail.com>
Co-authored-by: Alex Inkin <alexander@inkin.ru>
2026-01-15 11:42:17 -08:00

150 lines
4.1 KiB
Rust

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)?;
self.as_health_mut().ser(&Default::default())?;
Ok(())
}
pub fn restart(&mut self) -> Result<(), Error> {
self.as_desired_mut().map_mutate(|s| Ok(s.restart()))?;
self.as_health_mut().ser(&Default::default())?;
Ok(())
}
pub fn init(&mut self) -> Result<(), Error> {
self.stopped()?;
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
}
}
}