Skip to content

Commit

Permalink
feat: Add unset_mode function
Browse files Browse the repository at this point in the history
Used to reset the boot loader back to the previous boot loader conf
  • Loading branch information
mmstick committed Feb 20, 2020
1 parent 16c36c0 commit 8862eae
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ os-release = "0.1.0"
partition-identity = "0.2.2"
proc-mounts = "0.1.2"
rayon = "1.0.2"
sys-mount = "1.1.0"
sys-mount = "1"
tempdir = "0.3.7"
bitflags = "1.0.4"
err-derive = "0.1.5"
apt-cli-wrappers = { git = "https://github.com/pop-os/apt-cli-wrappers" }
systemd-boot-conf = "0.1.0"
derive_more = "0.99.2"
anyhow = "1"

[dependencies.failure]
version = "0.1.2"
Expand Down
7 changes: 7 additions & 0 deletions ffi/distinst.vapi
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,13 @@ namespace Distinst {

public delegate UserAccountCreate UserAccountCallback ();

/**
* Attempts to unset the active mode
*
* Returns `false` on an error. See distinst logs for details on the cause of the error.
*/
bool unset_mode ();

int log (Distinst.LogCallback callback);

[Compact]
Expand Down
11 changes: 11 additions & 0 deletions ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ pub unsafe extern "C" fn distinst_validate_hostname(hostname: *const libc::c_cha
#[no_mangle]
pub extern "C" fn distinst_minimum_disk_size(size: u64) -> u64 { distinst::minimum_disk_size(size) }

#[no_mangle]
pub extern "C" fn distinst_unset_mode() -> bool {
match distinst::unset_mode() {
Ok(()) => true,
Err(why) => {
error!("unset_mode: {:?}", why);
false
}
}
}

/// Log level
#[repr(C)]
#[derive(Copy, Clone, Debug)]
Expand Down
55 changes: 54 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub extern crate partition_identity;
pub extern crate proc_mounts;
pub extern crate sys_mount;

extern crate anyhow;
extern crate apt_cli_wrappers;
#[macro_use]
extern crate bitflags;
Expand Down Expand Up @@ -68,13 +69,18 @@ pub mod dbus_interfaces {
pub use logind_dbus::*;
}

use external::dmlist;
use std::{
io::{self, Read},
path::{Path, PathBuf},
sync::atomic::AtomicBool,
};

use anyhow::Context;
use external::dmlist;
use partition_identity::PartitionID;
use sys_mount::*;
use systemd_boot_conf::SystemdBootConf;

pub use self::{installer::*, logging::log};

/// When set to true, this will stop the installation process.
Expand Down Expand Up @@ -123,3 +129,50 @@ pub fn minimum_disk_size(default: u64) -> u64 {

casper_size + DEFAULT_ESP_SECTORS + DEFAULT_RECOVER_SECTORS + DEFAULT_SWAP_SECTORS
}

pub fn unset_mode() -> anyhow::Result<()> {
let mut conf = RecoveryEnv::new().context("failed to read recovery.conf")?;

if conf.get("MODE") == Some("refresh") {
let efi_id = conf.get("EFI_UUID").context("EFI_UUID is not set")?;
let prev_boot = conf.get("PREV_BOOT").context("PREV_BOOT is not set")?;

let target_dir = Path::new("target");

let _mount = mount_efi(efi_id, target_dir)?;

let mut boot_loader =
SystemdBootConf::new(target_dir).context("failed to open boot loader conf")?;

boot_loader.loader_conf.default = Some(prev_boot.into());
boot_loader.overwrite_loader_conf().context("failed to overwrite boot loader conf")?;

crate::external::remount_rw("/cdrom")
.context("failed to remount /cdrom with write permissions")?;
conf.remove("MODE");
conf.remove("PREV_BOOT");
conf.write().context("failed to write updated boot loader conf")?;
}

Ok(())
}

fn mount_efi(efi_id: &str, target_dir: &Path) -> anyhow::Result<UnmountDrop<Mount>> {
let efi_pid = if efi_id.starts_with("PARTUUID=") {
PartitionID::new_partuuid(efi_id[9..].to_owned())
} else {
PartitionID::new_uuid(efi_id.to_owned())
};

let efi_path =
efi_pid.get_device_path().context("failed to get device path from EFI partition")?;

if !target_dir.exists() {
std::fs::create_dir(target_dir)
.context("failed to create target directory for EFI mount")?;
}

Mount::new(&efi_path, target_dir, "vfat", MountFlags::empty(), None)
.context("failed to mount EFI partition")
.map(|mount| mount.into_unmount_drop(UnmountFlags::DETACH))
}

0 comments on commit 8862eae

Please sign in to comment.