Skip to content

Commit

Permalink
Support setting timezones and user accounts with the CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
mmstick committed Oct 23, 2018
1 parent 2b39817 commit 48f76ad
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 15 deletions.
64 changes: 62 additions & 2 deletions cli/src/main.rs
Expand Up @@ -12,9 +12,9 @@ mod errors;
use clap::{App, Arg, ArgMatches, Values};
use configure::*;
use distinst::{
Config, DecryptionError, Disk, DiskError, Disks, FileSystemType, Installer,
timezones::Timezones, Config, DecryptionError, Disk, DiskError, Disks, FileSystemType, Installer,
LvmEncryption, PartitionBuilder, PartitionFlag, PartitionInfo, PartitionTable, PartitionType,
Sector, Step, KILL_SWITCH, PARTITIONING_TEST, FORCE_BOOTLOADER, NO_EFI_VARIABLES
Sector, Step, UserAccountCreate, KILL_SWITCH, PARTITIONING_TEST, FORCE_BOOTLOADER, NO_EFI_VARIABLES
};
use errors::DistinstError;

Expand All @@ -29,6 +29,27 @@ use std::sync::atomic::Ordering;

fn main() {
let matches = App::new("distinst")
.arg(
Arg::with_name("username")
.long("username")
.help("specifies a default user account to create")
.takes_value(true)
)
.arg(
Arg::with_name("realname")
.long("realname")
.help("the full name of user to create")
.requires("username")
.takes_value(true)
)
.arg(
Arg::with_name("timezone")
.long("tz")
.help("the timezone to set for the new install")
.value_delimiter("/")
.min_values(2)
.max_values(2)
)
.arg(
Arg::with_name("squashfs")
.short("s")
Expand Down Expand Up @@ -199,6 +220,37 @@ fn main() {
let lang = matches.value_of("lang").unwrap();
let remove = matches.value_of("remove").unwrap();

let tzs_;
let timezone = match matches.values_of("timezone") {
Some(mut tz) => {
let (zone, region) = (tz.next().unwrap(), tz.next().unwrap());
tzs_ = Timezones::new().expect("failed to get timzones");
let zone = tzs_.zones()
.find(|z| z.name() == zone)
.expect(&format!("failed to find zone: {}", zone));
let region = zone.regions()
.find(|r| r.name() == region)
.expect(&format!("failed to find region: {}", region));
Some(region.clone())
},
None => None
};

let user_account = matches.value_of("username").map(|username| {
let username = username.to_owned();
let realname = matches.value_of("realname").map(String::from);
let password = if unsafe { libc::isatty(0) } == 0 {
let mut pass = String::new();
io::stdin().read_line(&mut pass).unwrap();
pass.pop();
Some(pass)
} else {
None
};

UserAccountCreate { realname, username, password }
});

let pb_opt: Rc<RefCell<Option<ProgressBar<io::Stdout>>>> = Rc::new(RefCell::new(None));

let res = {
Expand Down Expand Up @@ -246,6 +298,14 @@ fn main() {
});
}

if let Some(timezone) = timezone {
installer.set_timezone_callback(move || timezone.clone());
}

if let Some(user_account) = user_account {
installer.set_user_callback(move || user_account.clone());
}

let disks = match configure_disks(&matches) {
Ok(disks) => disks,
Err(why) => {
Expand Down
2 changes: 1 addition & 1 deletion ffi/src/installer.rs
Expand Up @@ -156,7 +156,7 @@ pub unsafe extern "C" fn distinst_installer_set_timezone_callback(
user_data: *mut libc::c_void,
) {
(*(installer as *mut Installer)).set_timezone_callback(move || {
&*(callback(user_data) as *const Region)
(&*(callback(user_data) as *const Region)).clone()
});
}

Expand Down
13 changes: 7 additions & 6 deletions src/installer/mod.rs
Expand Up @@ -54,6 +54,7 @@ pub struct Config {
}

/// Credentials for creating a new user account.
#[derive(Clone)]
pub struct UserAccountCreate {
pub username: String,
pub realname: Option<String>,
Expand All @@ -75,14 +76,14 @@ pub struct Status {
}

/// An installer object
pub struct Installer<'a> {
pub struct Installer {
error_cb: Option<Box<FnMut(&Error)>>,
status_cb: Option<Box<FnMut(&Status)>>,
timezone_cb: Option<Box<FnMut() -> &'a Region>>,
timezone_cb: Option<Box<FnMut() -> Region>>,
user_creation_cb: Option<Box<FnMut() -> UserAccountCreate>>
}

impl<'a> Default for Installer<'a> {
impl Default for Installer {
/// Create a new installer object
///
/// ```ignore,rust
Expand All @@ -99,7 +100,7 @@ impl<'a> Default for Installer<'a> {
}
}

impl<'a> Installer<'a> {
impl Installer {
const CHROOT_ROOT: &'static str = "distinst";

/// Get a list of disks, skipping loopback devices
Expand Down Expand Up @@ -172,7 +173,7 @@ impl<'a> Installer<'a> {
mount_dir.path(),
&config,
&iso_os_release,
timezone,
timezone.as_ref(),
user.as_ref(),
&remove_pkgs,
percent!(steps),
Expand Down Expand Up @@ -355,7 +356,7 @@ impl<'a> Installer<'a> {
}

/// Set the timezone callback
pub fn set_timezone_callback<F: FnMut() -> &'a Region + 'static>(&mut self, callback: F) {
pub fn set_timezone_callback<F: FnMut() -> Region + 'static>(&mut self, callback: F) {
self.timezone_cb = Some(Box::new(callback));
}

Expand Down
8 changes: 4 additions & 4 deletions src/installer/state.rs
Expand Up @@ -4,13 +4,13 @@ use std::sync::atomic::Ordering;
use super::{Installer, Status, Error, Step};
use KILL_SWITCH;

pub struct InstallerState<'a, 'b: 'a> {
pub installer: &'a mut Installer<'b>,
pub struct InstallerState<'a> {
pub installer: &'a mut Installer,
pub status: Status,
}

impl<'a, 'b> InstallerState<'a, 'b> {
pub fn new(installer: &'a mut Installer<'b>) -> Self {
impl<'a> InstallerState<'a> {
pub fn new(installer: &'a mut Installer) -> Self {
Self { installer, status: Status { step: Step::Init, percent: 0 }}
}

Expand Down
7 changes: 5 additions & 2 deletions tests/install.sh
Expand Up @@ -25,7 +25,7 @@ done

set -e -x

sudo target/debug/distinst \
echo "system76" | sudo target/debug/distinst \
-s "${FS}" \
-r "${REMOVE}" \
-h "pop-testing" \
Expand All @@ -35,4 +35,7 @@ sudo target/debug/distinst \
-t "$1:gpt" \
-n "$1:primary:start:512M:fat32:mount=/boot/efi:flags=esp" \
-n "$1:primary:512M:-4096M:ext4:mount=/" \
-n "$1:primary:-4096M:end:swap"
-n "$1:primary:-4096M:end:swap" \
--username "oem" \
--realname "System76 OEM Account" \
--tz "America/Denver"

0 comments on commit 48f76ad

Please sign in to comment.