alma/src/tool/chroot.rs
James McMurray 490ab30f4c Refactor main.rs and fix clippy lints
Status: WIP

Completed:
* Fixed flagged clippy lints
* Moved qemu(), main.rs::mount() and chroot() to the tools module.
* Moved constants in main.rs to constants.rs (including base packages
  array)
* Renamed Presets struct to PresetsCollection to avoid confusion with
  Preset struct
* Moved main() to the top of main.rs to highlight general logic path
* Added comments and docstrings to some functions
* Removed some uses of `use foo::*` to make the source of imported functions
  and structs clearer

TODO:
* Move remaining code in main.rs to modules (except main())
* Break up create() function in to separate steps
* Log every command run (with arguments) to debug! when verbose flag is used
* Add docstrings for remaining functions and document constants (e.g.
  why noatime is used)
* Remove remaining uses of `use foo::*`
* Consider renaming/moving tools module to address tool:: vs. Tool::
  confusion
2020-03-06 23:11:56 +01:00

71 lines
2.3 KiB
Rust

use super::mount;
use super::Tool;
use crate::args;
use crate::constants::{BOOT_PARTITION_INDEX, ROOT_PARTITION_INDEX};
use crate::error::{Error, ErrorKind};
use crate::process::CommandExt;
use crate::storage;
use crate::storage::{is_encrypted_device, EncryptedDevice};
use crate::storage::{BlockDevice, Filesystem, FilesystemType, LoopDevice};
use log::info;
use failure::ResultExt;
use tempfile::tempdir;
/// Use arch-chroot to chroot to the given device
/// Also handles encrypted root partitions (detected by checking for the LUKS magic header)
pub fn chroot(command: args::ChrootCommand) -> Result<(), Error> {
let arch_chroot = Tool::find("arch-chroot")?;
let cryptsetup;
let loop_device: Option<LoopDevice>;
let storage_device =
match storage::StorageDevice::from_path(&command.block_device, command.allow_non_removable)
{
Ok(b) => b,
Err(_) => {
loop_device = Some(LoopDevice::create(&command.block_device)?);
storage::StorageDevice::from_path(
loop_device.as_ref().unwrap().path(),
command.allow_non_removable,
)?
}
};
let mount_point = tempdir().context(ErrorKind::TmpDirError)?;
let boot_partition = storage_device.get_partition(BOOT_PARTITION_INDEX)?;
let boot_filesystem = Filesystem::from_partition(&boot_partition, FilesystemType::Vfat);
let root_partition_base = storage_device.get_partition(ROOT_PARTITION_INDEX)?;
let encrypted_root = if is_encrypted_device(&root_partition_base)? {
cryptsetup = Some(Tool::find("cryptsetup")?);
Some(EncryptedDevice::open(
cryptsetup.as_ref().unwrap(),
&root_partition_base,
"alma_root".into(),
)?)
} else {
None
};
let root_partition = if let Some(e) = encrypted_root.as_ref() {
e as &dyn BlockDevice
} else {
&root_partition_base as &dyn BlockDevice
};
let root_filesystem = Filesystem::from_partition(root_partition, FilesystemType::Ext4);
let mount_stack = mount(mount_point.path(), &boot_filesystem, &root_filesystem)?;
arch_chroot
.execute()
.arg(mount_point.path())
.args(&command.command)
.run(ErrorKind::Interactive)?;
info!("Unmounting filesystems");
mount_stack.umount()?;
Ok(())
}