diff --git a/builder/src/build.rs b/builder/src/build.rs index f213400..bd09d56 100644 --- a/builder/src/build.rs +++ b/builder/src/build.rs @@ -24,7 +24,7 @@ use common::repository::remote::download_packages; use common::{ anyhow::{anyhow, bail, Result}, flate2::{write::GzEncoder, Compression}, - maestro_utils::{fhs, user::get_euid}, + maestro_utils::user::get_euid, package::{DependencyType, Package}, repository::{ get_package_with_constraint, get_recursive_dependencies, PackagesWithRepositoryMap, @@ -112,7 +112,7 @@ pub struct BuildProcess { /// - `input_path` is the path to the directory containing information to build the package /// - `package` is the package to build async fn create_sysroot(sysroot: &Path, input_path: &Path, package: &Package) -> Result<()> { - if let Err(e) = fhs::create_dirs(sysroot, false) { + if let Err(e) = common::fhs::create_dirs(sysroot, false) { bail!("FHS creation failed: {e}"); } create_dev_nodes(sysroot)?; diff --git a/common/src/fhs.rs b/common/src/fhs.rs new file mode 100644 index 0000000..077bf19 --- /dev/null +++ b/common/src/fhs.rs @@ -0,0 +1,109 @@ +/* + * Copyright 2026 Luc LenĂ´tre + * + * This file is part of Maestro. + * + * Maestro is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Maestro is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * Maestro. If not, see . + */ + +use std::{error::Error, fs, io::ErrorKind, os::unix, path::Path}; + +/// Creates the FHS folder hierarchy on the disk. +/// +/// - `sysroot` is the path to the FHS system root. +/// - `log` is whether to print on creation or not. +pub fn create_dirs(sysroot: &Path, log: bool) -> Result<(), Box> { + let dirs = &[ + "boot", + "dev", + "etc", + "home", + "media", + "mnt", + "opt", + "proc", + "root", + "run", + "srv", + "sys", + "tmp", + "usr", + "var", + "etc/opt", + "etc/sysconfig", + "run/lock", + "run/log", + "usr/bin", + "usr/include", + "usr/lib", + "usr/lib/firmware", + "usr/local", + "usr/sbin", + "usr/share", + "usr/src", + "usr/share/doc", + "usr/share/info", + "usr/share/locale", + "usr/share/man", + "usr/share/misc", + "usr/local/bin", + "usr/local/include", + "usr/local/lib", + "usr/local/sbin", + "usr/local/share", + "usr/local/src", + "usr/local/share/doc", + "usr/local/share/info", + "usr/local/share/locale", + "usr/local/share/man", + "usr/local/share/misc", + "var/cache", + "var/lib", + "var/local", + "var/log", + "var/mail", + "var/opt", + "var/spool", + "var/lib/misc", + ]; + for path in dirs { + if log { + println!("Create directory `{path}`"); + } + let path = sysroot.join(path); + match fs::create_dir(path) { + Ok(_) => {} + Err(e) if e.kind() == ErrorKind::AlreadyExists => {} + Err(e) => return Err(e.into()), + } + } + let links: &[(&str, &str)] = &[ + ("usr/bin", "bin"), + ("usr/sbin", "sbin"), + ("usr/lib", "lib"), + ("usr/lib", "lib64"), + ("lib", "usr/lib64"), + ]; + for (target, link) in links { + if log { + println!("Create symlink `{link}` -> `{target}`"); + } + let path = sysroot.join(link); + match unix::fs::symlink(target, &path) { + Ok(_) => {} + Err(e) if e.kind() == ErrorKind::AlreadyExists => {} + Err(e) => return Err(e.into()), + } + } + Ok(()) +} diff --git a/common/src/lib.rs b/common/src/lib.rs index 448f1da..f05f897 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -27,6 +27,7 @@ pub use utils as maestro_utils; #[cfg(feature = "network")] pub mod download; +pub mod fhs; pub mod lock; pub mod package; pub mod repository;