Compare commits

..

No commits in common. "master" and "v0.11.0" have entirely different histories.

18 changed files with 319 additions and 857 deletions

View File

@ -34,7 +34,7 @@ pipeline:
commands: commands:
- dpkg --add-architecture armel - dpkg --add-architecture armel
- apt-get update - apt-get update
- apt-get install -y crossbuild-essential-armel libdbus-1-dev:armel libdbus-1-3:armel --no-install-recommends - apt-get install -y crossbuild-essential-armel libdbus-1-dev:armel --no-install-recommends
- rustup target add arm-unknown-linux-gnueabi - rustup target add arm-unknown-linux-gnueabi
- PKG_CONFIG=arm-linux-gnueabi-pkg-config CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER=arm-linux-gnueabi-gcc cargo build --release --target arm-unknown-linux-gnueabi - PKG_CONFIG=arm-linux-gnueabi-pkg-config CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABI_LINKER=arm-linux-gnueabi-gcc cargo build --release --target arm-unknown-linux-gnueabi
- mv target/arm-unknown-linux-gnueabi/release/alma alma-arm - mv target/arm-unknown-linux-gnueabi/release/alma alma-arm

1071
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
[package] [package]
name = "alma" name = "alma"
version = "0.11.1" version = "0.11.0"
authors = ["Roey Darwish Dror, PurpleCow"] authors = ["Roey Darwish Dror, PurpleCow"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]
which = "7.0.3" which = "4.4"
log = "0.4.27" log = "0.4"
structopt = "0.3.26" structopt = "0.3"
tempfile = "3" tempfile = "3"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
toml = "0.8.22" toml = "0.7"
byte-unit = "5.1.6" byte-unit = "4.0"
nix = { version = "0.30.1", features = ["mount"] } nix = "0.26"
env_logger = "0.11.8" env_logger = "0.10"
pretty_env_logger = "0.5" pretty_env_logger = "0.5"
dialoguer = "0.11" dialoguer = "0.10"
console = "0.15.11" console = "0.15"
anyhow = "1" anyhow = "1"

View File

@ -1,6 +1,5 @@
# ALMA - Arch Linux Mobile Appliance # ALMA - Arch Linux Mobile Appliance
![rust event push](https://git.spaeth.biz/Lila-Kuh/alma/actions/workflows/rust.yml/badge.svg?branch=master&event=push)
---
Almost every live Linux distribution out there is meant for a specific purpose, whether it's data Almost every live Linux distribution out there is meant for a specific purpose, whether it's data
rescue, privacy, penetration testing or anything else. There are some more generic distributions rescue, privacy, penetration testing or anything else. There are some more generic distributions
but all of them are based on squashfs, meaning that changes don't persist reboots. but all of them are based on squashfs, meaning that changes don't persist reboots.
@ -34,6 +33,7 @@ date without having to boot it. Encrypting the root partition is as easy as prov
- [Similar projects](#similar-projects) - [Similar projects](#similar-projects)
- [Useful Resources](#useful-resources) - [Useful Resources](#useful-resources)
--- ---
## Installation ## Installation
You can either build the project using cargo build or install the `alma-aur` package. You can either build the project using cargo build or install the `alma-aur` package.

View File

@ -6,7 +6,7 @@ use structopt::StructOpt;
/// Parse size argument as bytes /// Parse size argument as bytes
/// e.g. 10GB, 10GiB, etc. /// e.g. 10GB, 10GiB, etc.
fn parse_bytes(src: &str) -> Result<Byte, &'static str> { fn parse_bytes(src: &str) -> Result<Byte, &'static str> {
Byte::parse_str(src, false).map_err(|_| "Invalid image size") Byte::from_str(src).map_err(|_| "Invalid image size")
} }
#[derive(StructOpt)] #[derive(StructOpt)]

View File

@ -37,10 +37,10 @@ impl FromStr for AurHelper {
install_command: vec![ install_command: vec![
String::from("yay"), String::from("yay"),
String::from("-S"), String::from("-S"),
String::from("--cleanmenu=false"), String::from("--nocleanmenu"),
String::from("--diffmenu=false"), String::from("--nodiffmenu"),
String::from("--editmenu=false"), String::from("--noeditmenu"),
String::from(""), String::from("--noupgrademenu"),
String::from("--useask"), String::from("--useask"),
String::from("--removemake"), String::from("--removemake"),
String::from("--norebuild"), String::from("--norebuild"),
@ -49,7 +49,7 @@ impl FromStr for AurHelper {
String::from("--answerclean"), String::from("--answerclean"),
String::from("None"), String::from("None"),
String::from("--mflags"), String::from("--mflags"),
String::from(""), String::from("--noconfirm"),
], ],
}), }),
_ => Err(anyhow!("Error parsing AUR helper string: {}", s)), _ => Err(anyhow!("Error parsing AUR helper string: {}", s)),

View File

@ -9,8 +9,8 @@ SystemMaxUse=16M
pub const BASE_PACKAGES: [&str; 9] = [ pub const BASE_PACKAGES: [&str; 9] = [
"base", "base",
"linux612", "linux61",
"linux612-broadcom-wl", "linux61-broadcom-wl",
"linux-firmware", "linux-firmware",
"grub", "grub",
"efibootmgr", "efibootmgr",

View File

@ -78,7 +78,7 @@ fn create_image(path: &Path, size: Byte, overwrite: bool) -> anyhow::Result<Loop
} }
let file = options.open(path).context("Error creating the image")?; let file = options.open(path).context("Error creating the image")?;
file.set_len(size.as_u64()) file.set_len(size.get_bytes() as u64)
.context("Error creating the image")?; .context("Error creating the image")?;
} }
@ -166,7 +166,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
sgdisk sgdisk
.execute() .execute()
.args([ .args(&[
"-Z", "-Z",
"-o", "-o",
&format!("--new=1::+{}M", boot_size), &format!("--new=1::+{}M", boot_size),
@ -175,7 +175,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
"--typecode=1:EF00", "--typecode=1:EF00",
"--typecode=2:EF02", "--typecode=2:EF02",
]) ])
.arg(disk_path) .arg(&disk_path)
.run() .run()
.context("Partitioning error")?; .context("Partitioning error")?;
@ -270,14 +270,14 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["passwd", "-d", "root"]) .args(&["passwd", "-d", "root"])
.run() .run()
.context("Failed to delete the root password")?; .context("Failed to delete the root password")?;
info!("Setting locale"); info!("Setting locale");
fs::OpenOptions::new() fs::OpenOptions::new()
.append(true) .append(true)
//.write(true) .write(true)
.open(mount_point.path().join("etc/locale.gen")) .open(mount_point.path().join("etc/locale.gen"))
.and_then(|mut locale_gen| locale_gen.write_all(b"en_US.UTF-8 UTF-8\n")) .and_then(|mut locale_gen| locale_gen.write_all(b"en_US.UTF-8 UTF-8\n"))
.context("Failed to create locale.gen")?; .context("Failed to create locale.gen")?;
@ -298,7 +298,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["useradd", "-m", "aur"]) .args(&["useradd", "-m", "aur"])
.run() .run()
.context("Failed to create temporary user to install AUR packages")?; .context("Failed to create temporary user to install AUR packages")?;
@ -309,7 +309,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["sudo", "-u", "aur"]) .args(&["sudo", "-u", "aur"])
.arg("git") .arg("git")
.arg("clone") .arg("clone")
.arg(format!( .arg(format!(
@ -323,7 +323,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args([ .args(&[
"bash", "bash",
"-c", "-c",
&format!( &format!(
@ -337,7 +337,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["sudo", "-u", "aur"]) .args(&["sudo", "-u", "aur"])
.args(&command.aur_helper.install_command) .args(&command.aur_helper.install_command)
.args(aur_pacakges) .args(aur_pacakges)
.run() .run()
@ -347,7 +347,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["userdel", "-r", "aur"]) .args(&["userdel", "-r", "aur"])
.run() .run()
.context("Failed to delete temporary aur user")?; .context("Failed to delete temporary aur user")?;
@ -413,7 +413,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["systemctl", "enable", "NetworkManager"]) .args(&["systemctl", "enable", "NetworkManager"])
.run() .run()
.context("Failed to enable NetworkManager")?; .context("Failed to enable NetworkManager")?;
@ -433,7 +433,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["mkinitcpio", "-p", "linux612"]) .args(&["mkinitcpio", "-p", "linux61"])
.run() .run()
.context("Failed to run mkinitcpio - do you have the base and linux packages installed?")?; .context("Failed to run mkinitcpio - do you have the base and linux packages installed?")?;
@ -444,7 +444,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
.expect("No tool for blkid") .expect("No tool for blkid")
.execute() .execute()
.arg(root_partition_base.path()) .arg(root_partition_base.path())
.args(["-o", "value", "-s", "UUID"]) .args(&["-o", "value", "-s", "UUID"])
.run_text_output() .run_text_output()
.context("Failed to run blkid")?; .context("Failed to run blkid")?;
let trimmed = uuid.trim(); let trimmed = uuid.trim();
@ -467,7 +467,7 @@ fn create(command: args::CreateCommand) -> anyhow::Result<()> {
arch_chroot arch_chroot
.execute() .execute()
.arg(mount_point.path()) .arg(mount_point.path())
.args(["bash", "-c"]) .args(&["bash", "-c"])
.arg(format!("grub-install --target=i386-pc --boot-directory /boot {} && grub-install --target=x86_64-efi --efi-directory /boot --boot-directory /boot --removable && grub-mkconfig -o /boot/grub/grub.cfg", disk_path.display())) .arg(format!("grub-install --target=i386-pc --boot-directory /boot {} && grub-install --target=x86_64-efi --efi-directory /boot --boot-directory /boot --removable && grub-mkconfig -o /boot/grub/grub.cfg", disk_path.display()))
.run().context("Failed to install grub")?; .run().context("Failed to install grub")?;

View File

@ -73,7 +73,7 @@ impl<'t, 'o> EncryptedDevice<'t, 'o> {
} }
} }
impl Drop for EncryptedDevice<'_, '_> { impl<'t, 'o> Drop for EncryptedDevice<'t, 'o> {
fn drop(&mut self) { fn drop(&mut self) {
if self._close().is_err() { if self._close().is_err() {
warn!("Error closing {}", self.name); warn!("Error closing {}", self.name);
@ -81,7 +81,7 @@ impl Drop for EncryptedDevice<'_, '_> {
} }
} }
impl BlockDevice for EncryptedDevice<'_, '_> { impl<'t, 'o> BlockDevice for EncryptedDevice<'t, 'o> {
fn path(&self) -> &Path { fn path(&self) -> &Path {
&self.path &self.path
} }

View File

@ -14,7 +14,7 @@ impl LoopDevice {
let losetup = Tool::find("losetup")?; let losetup = Tool::find("losetup")?;
let output = losetup let output = losetup
.execute() .execute()
.args(["--find", "-P", "--show"]) .args(&["--find", "-P", "--show"])
.arg(file) .arg(file)
.output() .output()
.context("Error creating the image")?; .context("Error creating the image")?;

View File

@ -23,7 +23,7 @@ impl<'a> MountStack<'a> {
filesystem: &'a Filesystem, filesystem: &'a Filesystem,
target: PathBuf, target: PathBuf,
options: Option<&str>, options: Option<&str>,
) -> Result<(), nix::Error> { ) -> nix::Result<()> {
let source = filesystem.block().path(); let source = filesystem.block().path();
debug!("Mounting {:?} to {:?}", filesystem, target); debug!("Mounting {:?} to {:?}", filesystem, target);
mount( mount(
@ -42,7 +42,7 @@ impl<'a> MountStack<'a> {
source: PathBuf, source: PathBuf,
target: PathBuf, target: PathBuf,
options: Option<&str>, options: Option<&str>,
) -> Result<(), nix::Error> { ) -> nix::Result<()> {
debug!("Mounting {:?} to {:?}", source, target); debug!("Mounting {:?} to {:?}", source, target);
mount::<_, _, str, _>( mount::<_, _, str, _>(
Some(&source), Some(&source),
@ -78,7 +78,7 @@ impl<'a> MountStack<'a> {
} }
} }
impl Drop for MountStack<'_> { impl<'a> Drop for MountStack<'a> {
fn drop(&mut self) { fn drop(&mut self) {
self._umount().ok(); self._umount().ok();
} }

View File

@ -17,7 +17,7 @@ impl<'a> Partition<'a> {
} }
} }
impl BlockDevice for Partition<'_> { impl<'a> BlockDevice for Partition<'a> {
fn path(&self) -> &Path { fn path(&self) -> &Path {
&self.path &self.path
} }

View File

@ -1,5 +1,5 @@
use anyhow::Context; use anyhow::Context;
use byte_unit::{Byte, UnitType}; use byte_unit::Byte;
use std::{fmt, fs}; use std::{fmt, fs};
#[derive(Debug)] #[derive(Debug)]
@ -17,7 +17,7 @@ impl fmt::Display for Device {
"{} {} ({})", "{} {} ({})",
self.vendor, self.vendor,
self.model, self.model,
self.size.get_appropriate_unit(UnitType::Decimal) self.size.get_appropriate_unit(true)
) )
} }
} }
@ -60,11 +60,11 @@ pub fn get_storage_devices(allow_non_removable: bool) -> anyhow::Result<Vec<Devi
vendor: fs::read_to_string(entry.path().join("device/vendor")) vendor: fs::read_to_string(entry.path().join("device/vendor"))
.map(trimmed) .map(trimmed)
.context("Error querying storage devices")?, .context("Error querying storage devices")?,
size: Byte::from_u64( size: Byte::from_bytes(
fs::read_to_string(entry.path().join("size")) fs::read_to_string(entry.path().join("size"))
.context("Error querying storage devices")? .context("Error querying storage devices")?
.trim() .trim()
.parse::<u64>() .parse::<u128>()
.context("Could not parse block size to unsigned integer (u128)")? .context("Could not parse block size to unsigned integer (u128)")?
* 512, * 512,
), ),

View File

@ -73,9 +73,10 @@ impl<'a> StorageDevice<'a> {
let name = if self let name = if self
.name .name
.chars() .chars()
.next_back() .rev()
.next()
.expect("Storage device name is empty") .expect("Storage device name is empty")
.is_ascii_digit() .is_digit(10)
{ {
format!("{}p{}", self.name, index) format!("{}p{}", self.name, index)
} else { } else {
@ -92,10 +93,10 @@ impl<'a> StorageDevice<'a> {
} }
} }
impl BlockDevice for StorageDevice<'_> { impl<'a> BlockDevice for StorageDevice<'a> {
fn path(&self) -> &Path { fn path(&self) -> &Path {
&self.path &self.path
} }
} }
impl Origin for StorageDevice<'_> {} impl<'a> Origin for StorageDevice<'a> {}

View File

@ -12,7 +12,7 @@ pub fn qemu(command: args::QemuCommand) -> anyhow::Result<()> {
let qemu = Tool::find("qemu-system-x86_64")?; let qemu = Tool::find("qemu-system-x86_64")?;
let mut run = qemu.execute(); let mut run = qemu.execute();
run.args([ run.args(&[
"-m", "-m",
"4G", "4G",
"-netdev", "-netdev",
@ -33,7 +33,7 @@ pub fn qemu(command: args::QemuCommand) -> anyhow::Result<()> {
if PathBuf::from("/dev/kvm").exists() { if PathBuf::from("/dev/kvm").exists() {
debug!("KVM is enabled"); debug!("KVM is enabled");
run.args(["-enable-kvm", "-cpu", "host"]); run.args(&["-enable-kvm", "-cpu", "host"]);
} }
let err = run.exec(); let err = run.exec();