Skip to content

Commit

Permalink
feat: add option to make overlay persistent by default (closes #8)
Browse files Browse the repository at this point in the history
  • Loading branch information
koehlma committed Nov 26, 2023
1 parent 64450ce commit dd8df0e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 16 deletions.
10 changes: 5 additions & 5 deletions crates/rugpi-ctrl/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ pub fn main() -> Anyhow<()> {
reboot(false)?;
}
StateCommand::Overlay(overlay_cmd) => match overlay_cmd {
OverlayCommand::SetPersist { persist } => match persist {
OverlayCommand::ForcePersist { persist } => match persist {
Boolean::True => {
fs::create_dir_all("/run/rugpi/state/.rugpi")?;
fs::write("/run/rugpi/state/.rugpi/persist-overlay", "")?;
fs::write("/run/rugpi/state/.rugpi/force-persist-overlay", "")?;
}
Boolean::False => {
fs::remove_file("/run/rugpi/state/.rugpi/persist-overlay").ok();
if Path::new("/run/rugpi/state/.rugpi/persist-overlay").exists() {
fs::remove_file("/run/rugpi/state/.rugpi/force-persist-overlay").ok();
if Path::new("/run/rugpi/state/.rugpi/force-persist-overlay").exists() {
bail!("Unable to unset `overlay-persist`.");
}
}
Expand Down Expand Up @@ -222,7 +222,7 @@ pub enum StateCommand {
#[derive(Debug, Parser)]
pub enum OverlayCommand {
/// Set the persistency of the overlay.
SetPersist { persist: Boolean },
ForcePersist { persist: Boolean },
}

#[derive(Debug, Parser)]
Expand Down
9 changes: 9 additions & 0 deletions crates/rugpi-ctrl/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
pub struct Config {
/// The size of the system partition(s).
pub system_size: Option<String>,
pub overlay: Overlay,
}

impl Config {
Expand All @@ -13,3 +14,11 @@ impl Config {
self.system_size.as_deref().unwrap_or("4G")
}
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Overlay {
Persist,
#[default]
Discard,
}
23 changes: 16 additions & 7 deletions crates/rugpi-ctrl/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rugpi_common::{
use xscript::{run, Run};

use crate::{
config::Config,
config::{Config, Overlay},
state::{load_state_config, Persist, STATE_CONFIG_DIR},
};

Expand Down Expand Up @@ -88,7 +88,7 @@ fn init() -> Anyhow<()> {
run!([MOUNT, "--bind", &state_profile, STATE_DIR])?;

// 7️⃣ Setup the root filesystem overlay.
setup_root_overlay(state_profile)?;
setup_root_overlay(&config, state_profile)?;

// 8️⃣ Setup the bind mounts for the persistent state.
setup_persistent_state(state_profile)?;
Expand Down Expand Up @@ -126,11 +126,19 @@ pub fn overlay_work_dir() -> &'static Utf8Path {
Utf8Path::new(OVERLAY_WORK_DIR)
}

const CTRL_CONFIG_PATH: &str = "/etc/rugpi/ctrl.toml";

pub fn config_path() -> &'static Utf8Path {
Utf8Path::new(CTRL_CONFIG_PATH)
}

/// Loads the Rugpi Ctrl configuration.
fn load_config() -> Anyhow<Config> {
Ok(toml::from_str(&fs::read_to_string(
"/etc/rugpi/ctrl.toml",
)?)?)
if config_path().exists() {
Ok(toml::from_str(&fs::read_to_string(config_path())?)?)
} else {
Ok(Config::default())
}
}

/// Mounts the essential filesystems `/proc`, `/sys`, and `/run`.
Expand Down Expand Up @@ -165,9 +173,10 @@ fn initialize_partitions(config: &Config) -> Anyhow<()> {
}

/// Sets up the overlay.
fn setup_root_overlay(state_profile: &Utf8Path) -> Anyhow<()> {
fn setup_root_overlay(config: &Config, state_profile: &Utf8Path) -> Anyhow<()> {
let overlay_state = state_profile.join("overlay");
if !state_profile.join(".rugpi/persist-overlay").exists() {
let force_persist = state_profile.join(".rugpi/force-persist-overlay").exists();
if !force_persist && !matches!(config.overlay, Overlay::Persist) {
fs::remove_dir_all(&overlay_state).ok();
}

Expand Down
19 changes: 15 additions & 4 deletions www/docs/guide/state-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@ Rugpi Ctrl can be configured to keep this overlay across reboots or discard it.
By default, the overlay is discarded such that the system is always booted fresh as stored in the root partition.
In addition, by discarding the overlay on each reboot, accidental state, which would get lost by an update, is discovered early as it is being erased by a simple reboot.

To enable persistency of the overlay of the root filesystem, run:
To enable persistency of the overlay, use the following option in `ctrl.toml`:

```toml title="ctrl.toml"
overlay = "persist"
```

Note that you must use a recipe to install `ctrl.toml` to `/etc/rugpi` in the image.

**ℹ️ While enabling persistency of the overlay can be convenient and is useful for certain use cases, you should evaluate its usage carefully. It means that any state is kept making the system less resilient and updates more challenging.**

For development purposes, you can also force persistency of the overlay at runtime.
To this end, run:

```shell
rugpi-ctrl state overlay set-persist true
rugpi-ctrl state overlay force-persist true
```

To disable persistency of the overlay of the root filesystem, run:
To disable force persistency of the overlay, run:

```shell
rugpi-ctrl state overlay set-persist false
rugpi-ctrl state overlay force-persist false
```

Note that this will discard the overlay and thereby any modifications which have been made with persistency set to `true`.
Expand Down

0 comments on commit dd8df0e

Please sign in to comment.