add accidentially ignored folder
This commit is contained in:
parent
515545cd24
commit
47c2c003d1
5 changed files with 316 additions and 0 deletions
14
src/setup/autostart.rs
Normal file
14
src/setup/autostart.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Autostart {
|
||||||
|
pub kiosk: Kiosk
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Kiosk {
|
||||||
|
pub page: String,
|
||||||
|
pub user: String
|
||||||
|
}
|
45
src/setup/mod.rs
Normal file
45
src/setup/mod.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//! This module contains definitions to read the setup files.
|
||||||
|
use anyhow::Context as _;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
path::{Path, PathBuf}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub mod autostart;
|
||||||
|
pub mod network;
|
||||||
|
pub mod os;
|
||||||
|
pub mod packages;
|
||||||
|
|
||||||
|
use autostart::Autostart;
|
||||||
|
use network::Network;
|
||||||
|
use os::Os;
|
||||||
|
use packages::Packages;
|
||||||
|
|
||||||
|
pub struct Setup {
|
||||||
|
pub os: Os,
|
||||||
|
pub network: Network,
|
||||||
|
pub packages: Packages,
|
||||||
|
pub autostart: Autostart
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Setup {
|
||||||
|
fn read<T: DeserializeOwned>(path: &Path, file: &str) -> anyhow::Result<T> {
|
||||||
|
toml::from_slice(&fs::read(path.join(file)).with_context(|| format!("Failed to read {file}"))?)
|
||||||
|
.with_context(|| format!("Failed to deserialize {file}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load() -> anyhow::Result<Self> {
|
||||||
|
let path = PathBuf::from("setup");
|
||||||
|
let os = Self::read(&path, "os.toml")?;
|
||||||
|
let network = Self::read(&path, "network.toml")?;
|
||||||
|
let packages = Self::read(&path, "packages.toml")?;
|
||||||
|
let autostart = Self::read(&path, "autostart.toml")?;
|
||||||
|
Ok(Self {
|
||||||
|
os,
|
||||||
|
network,
|
||||||
|
packages,
|
||||||
|
autostart
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
33
src/setup/network.rs
Normal file
33
src/setup/network.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Network {
|
||||||
|
#[serde(default)]
|
||||||
|
pub tailscale: bool,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub wifi: Vec<Wifi>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
//#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Wifi {
|
||||||
|
pub ssid: String,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub security: WifiSecurity
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(tag = "security")]
|
||||||
|
pub enum WifiSecurity {
|
||||||
|
#[serde(rename = "none")]
|
||||||
|
None,
|
||||||
|
|
||||||
|
#[serde(rename = "WPA-PSK")]
|
||||||
|
WpaPsk { password: String },
|
||||||
|
|
||||||
|
#[serde(rename = "WPA-EAP")]
|
||||||
|
WpaEap { identity: String, password: String }
|
||||||
|
}
|
216
src/setup/os.rs
Normal file
216
src/setup/os.rs
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
use serde::{
|
||||||
|
de::{self, Deserializer, Visitor},
|
||||||
|
Deserialize
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
|
fmt::{self, Display, Formatter}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Os {
|
||||||
|
pub alpine: Alpine,
|
||||||
|
pub rpi: Rpi,
|
||||||
|
pub host: Host,
|
||||||
|
pub user: Vec<User>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Branch {
|
||||||
|
Edge,
|
||||||
|
Version(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Branch {
|
||||||
|
pub fn git_branch(&self) -> Cow<'static, str> {
|
||||||
|
match self {
|
||||||
|
Self::Edge => "master".into(),
|
||||||
|
Self::Version(v) => format!("{v}-stable").into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Branch {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Version("3.17".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Branch {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
struct BranchVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for BranchVisitor {
|
||||||
|
type Value = Branch;
|
||||||
|
|
||||||
|
fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "the alpine branch, either edge or a version like v3.17")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: de::Error
|
||||||
|
{
|
||||||
|
if let Some(version) = v.strip_prefix('v') {
|
||||||
|
Ok(Branch::Version(version.to_owned()))
|
||||||
|
} else if v == "edge" {
|
||||||
|
Ok(Branch::Edge)
|
||||||
|
} else {
|
||||||
|
Err(E::custom("Invalid branch, expected either edge or a version like v3.17"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_str(BranchVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Branch {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Version(v) => write!(f, "v{v}"),
|
||||||
|
Self::Edge => write!(f, "edge")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum Arch {
|
||||||
|
ArmHf,
|
||||||
|
#[default]
|
||||||
|
ArmV7,
|
||||||
|
Aarch64
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arch {
|
||||||
|
pub fn cbuild(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::ArmHf => "armv6-alpine-linux-musleabihf",
|
||||||
|
Self::ArmV7 => "armv7-alpine-linux-musleabihf",
|
||||||
|
Self::Aarch64 => "aarch64-alpine-linux-musl"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::ArmHf => "armhf",
|
||||||
|
Self::ArmV7 => "armv7",
|
||||||
|
Self::Aarch64 => "aarch64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is64bit(&self) -> bool {
|
||||||
|
matches!(self, Self::Aarch64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Arch {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str(self.to_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_mirror() -> String {
|
||||||
|
"https://dl-cdn.alpinelinux.org/alpine".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Alpine {
|
||||||
|
#[serde(default)]
|
||||||
|
pub branch: Branch,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub arch: Arch,
|
||||||
|
|
||||||
|
#[serde(default = "default_mirror")]
|
||||||
|
pub mirror: String,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub extra_repos: Vec<String>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub extra_keys: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_cmdline() -> String {
|
||||||
|
"dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait";
|
||||||
|
"modules=loop,squashfs,sd-mod,usb-storage root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes console=tty1 rootwait"
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_usercfg() -> String {
|
||||||
|
r#"# modify this file instead of config.txt
|
||||||
|
|
||||||
|
# hide raspberry pi logo on startup
|
||||||
|
disable_splash=1
|
||||||
|
boot_delay=0
|
||||||
|
|
||||||
|
# enable uart / disable bluetooth
|
||||||
|
enable_uart=1
|
||||||
|
dtoverlay=disable-bt
|
||||||
|
|
||||||
|
# enable HDMI output
|
||||||
|
dtoverlay=vc4-kms-v3d
|
||||||
|
display_auto_detect=1
|
||||||
|
disable_overscan=1
|
||||||
|
"#
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Rpi {
|
||||||
|
#[serde(default = "default_cmdline")]
|
||||||
|
pub cmdline: String,
|
||||||
|
|
||||||
|
#[serde(default = "default_usercfg")]
|
||||||
|
pub usercfg: String
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_hostname() -> String {
|
||||||
|
"alpi".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_keymap() -> String {
|
||||||
|
"de".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_timezone() -> String {
|
||||||
|
"Europe/Amsterdam".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Host {
|
||||||
|
#[serde(default = "default_hostname")]
|
||||||
|
pub hostname: String,
|
||||||
|
|
||||||
|
#[serde(default = "default_keymap")]
|
||||||
|
pub keymap: String,
|
||||||
|
pub keymap_variant: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default = "default_timezone")]
|
||||||
|
pub timezone: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct User {
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
|
pub password: Option<String>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub sudo: bool,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub groups: Vec<String>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub authorized_keys: Vec<String>
|
||||||
|
}
|
8
src/setup/packages.rs
Normal file
8
src/setup/packages.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub struct Packages {
|
||||||
|
pub install: Vec<String>,
|
||||||
|
pub autostart: Vec<String>
|
||||||
|
}
|
Loading…
Reference in a new issue