diff --git a/.gitignore b/.gitignore index 2fb323c..566031c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ *~ *.swp util/ +dist.tar.gz diff --git a/README.md b/README.md index 2ded3b2..d5f4935 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,6 @@ you can quote the argument, e.g.: `-p "gimp blender inkscape"`. `chrx -d ubuntu -e standard -r 16.04 -H hal -U dave -p admin-misc` - ## compatibility diff --git a/chrx b/chrx index ef35c41..ae212a0 100644 --- a/chrx +++ b/chrx @@ -6,6 +6,7 @@ # : ${CHRX_WEB_ROOT:="https://chrx.org"} +export DEBIAN_FRONTEND=noninteractive CHRX_CACHE0_DIR="/var/tmp/chrx" CHRX_LOG_FILE="${CHRX_CACHE0_DIR}/chrx-install.log" diff --git a/chrx-install b/chrx-install index 5a6db5a..bb54ddd 100644 --- a/chrx-install +++ b/chrx-install @@ -5,7 +5,7 @@ # chromebook unix installer # -CHRX_VERSION="3.0.2" +CHRX_VERSION="3.1" CHRX_OS_DISTRO="galliumos" CHRX_OS_ENVIRONMENT="desktop" @@ -13,6 +13,7 @@ CHRX_OS_RELEASE="latest" CHRX_OS_ARCH="amd64" CHRX_OS_MIRROR="primary" CHRX_TARGET_DISK="" +CHRX_BOOTLOADER="grub-pc" CHRX_ADD_PKGS= CHRX_OS="linux" CHRX_HOSTNAME="chrx" @@ -57,6 +58,7 @@ Options -m MIRROR distribution-specific download mirror [${CHRX_OS_MIRROR}] galliumos: ny1.us, va1.us, rb1.fr -t TARGETDISK target disk (/dev/mmcblk1, /dev/sdb, etc) [${CHRX_TARGET_DISK}] + -b BOOTLOADER bootloader (grub-pc, grub-efi-amd64) [${CHRX_BOOTLOADER}] -p PACKAGE additional packages to install, may repeat [${CHRX_ADD_PKGS}] kodi, minecraft, steam, etc, see chrx.org for more (not yet supported on fedora) @@ -652,9 +654,16 @@ setup_storage() #curl -Os -A "${CHRX_UA}" ${CHRX_WEB_ROOT}/chrx-setup-storage #[ -r ./chrx-setup-storage ] && . ./chrx-setup-storage + # Export all variables/functions for subshells + set -a . /usr/local/bin/chrx-setup-storage + set +a - if [ "${SETUP_STORAGE_ERROR}" ]; then + declare -f get_disk_plus_partition + declare -f prep_install + prep_install + SETUP_STORAGE_ERROR=$? + if [ "${SETUP_STORAGE_ERROR}" -ne 0 ]; then echo_fail "fatal error from chrx-setup-storage. exiting!" exit 1 fi @@ -744,6 +753,17 @@ validate_config() if [ "$CHRX_OS_DISTRO" != "galliumos" -a ! -z "$CHRX_OS_MIRROR" ]; then msg_os_mirror="${ANSI_RED}unknown, will use primary${ANSI_RST}" fi + + case "${CHRX_CPUF}" in + GLK|WHL|CML) CHRX_BOOTLOADER="grub-efi-amd64" ;; + esac + + [ -n "$CHRX_BOOTLOADER_ARG" ] && CHRX_BOOTLOADER=$CHRX_BOOTLOADER_ARG + + case "${CHRX_BOOTLOADER}" in + grub-pc|grub-efi*) ;; + *) msg_bootloader="${ANSI_RED}invalid${ANSI_RST}" ; FAIL=1 ;; + esac } confirm_config() @@ -757,10 +777,11 @@ confirm_config() distribution (-d): ${CHRX_OS_DISTRO} ${msg_os_dist} environment (-e): ${CHRX_OS_ENVIRONMENT} ${msg_os_env} release (-r): ${CHRX_OS_RELEASE} ${msg_os_release} - version: ${CHRX_OS_VERSION} ${msg_os_version} + version: ${CHRX_OS_VERSION} ${msg_os_version} architecture (-a): ${CHRX_OS_ARCH} ${msg_os_arch} mirror (-m): ${CHRX_OS_MIRROR} ${msg_os_mirror} target_disk (-t): ${CHRX_TARGET_DISK} + bootloader (-b): ${CHRX_BOOTLOADER} ${msg_bootloader} packages (-p): ${CHRX_ADD_PKGS}${msg_os_pkgs} System Configuration @@ -899,6 +920,7 @@ do_install() export CHRX_TZ CHRX_LOCALE CHRX_USERNAME export CHRX_TARGET_DISK CHRX_ROOT_PARTITION CHRX_CACHE_DIR CHRX_INSTALL_ROOT export CHRX_OS_RELEASE CHRX_ADD_PKGS CHRX_CONFIGURE_GRUB_ENABLED + export CHRX_BOOTLOADER export VERBOSITY VERBOSITY_APTGET VERBOSITY_CURL VERBOSITY_DNF export ANSI_RED ANSI_YEL ANSI_GRN ANSI_VIO ANSI_BLU ANSI_WHT ANSI_RST export -f echo_info ## this does not reach the chroot @@ -912,6 +934,8 @@ do_install() # | tee -a ${CHRX_LOGFILE} echo "<< exiting chroot" + # Copy the keyboard mapping from ChromeOS to installed OS so keyboard is immediately useful *IF* they exist + (ls -A /etc/udev/hwdb.d/* >/dev/null 2>&1) && cp /etc/udev/hwdb.d/* ${CHRX_INSTALL_ROOT}/etc/udev/hwdb.d/ ## set eeprom bits #crossystem dev_boot_legacy=1 dev_boot_signed_only=1 [ "$CHRX_HOST_IS_CHROMEOS" ] && crossystem dev_boot_legacy=1 @@ -953,7 +977,7 @@ parse_opts() { ## parse command line options ## TODO: lubuntu[-desktop[-latest]] should be parseable - while getopts ":d:e:r:a:m:t:p:H:U:L:Z:nsyvh" OPTION + while getopts ":d:e:r:a:m:t:b:p:H:U:L:Z:nsyvh" OPTION do case "$OPTION" in d) CHRX_OS_DISTRO=$(downcase $OPTARG) ;; @@ -962,6 +986,7 @@ parse_opts() a) CHRX_OS_ARCH=$(downcase $OPTARG) ;; m) CHRX_OS_MIRROR=$(downcase $OPTARG) ;; t) CHRX_TARGET_DISK=$OPTARG ;; + b) CHRX_BOOTLOADER_ARG=$OPTARG ;; p) CHRX_ADD_PKGS="${CHRX_ADD_PKGS}$(downcase $OPTARG) " ;; H) CHRX_HOSTNAME=$OPTARG ;; U) CHRX_USERNAME=$OPTARG ;; @@ -1016,5 +1041,5 @@ main() } #set -e -main "$@" +(return 0 2>/dev/null) && sourced=1 || sourced=0 main "$@" diff --git a/chrx-setup-storage b/chrx-setup-storage index ba9e9d5..2dc9284 100644 --- a/chrx-setup-storage +++ b/chrx-setup-storage @@ -8,18 +8,20 @@ # It cannot be run directly from the commandline. # -eval_try umount -R ${CHRX_INSTALL_ROOT} 2>/dev/null ## be safe. - -set_root_partition() { +get_disk_plus_partition() { pnum=$1 case "$CHRX_TARGET_DISK" in - /dev/sd*) CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}${pnum}" ;; - /dev/mmcblk*) CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}p${pnum}" ;; - /dev/nvme*) CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}p${pnum}" ;; + /dev/sd*) echo "${CHRX_TARGET_DISK}${pnum}" ;; + /dev/mmcblk*|/dev/nvme*) echo "${CHRX_TARGET_DISK}p${pnum}" ;; *) echo_fail "\nunrecognized disk device: \"$CHRX_TARGET_DISK\"!"; exit 1 ;; esac } +# Export this so we can call it from subshells to capture values instead of setting globals +export -f get_disk_plus_partition + +# Wrap all direct executions in functions to be called from chrx-install for easier testing and ordering +eval_try umount -R ${CHRX_INSTALL_ROOT} 2>/dev/null ## be safe. if [ "${CHRX_TARGET_DISK}" ]; then echo_info "Installing to target disk ${ANSI_WHT}${CHRX_TARGET_DISK}${ANSI_RST}" @@ -35,11 +37,7 @@ if [ "${CHRX_TARGET_DISK}" ]; then echo_info "Setting up target disk ${CHRX_TARGET_DISK} formatting..." - #CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}1" - #if [[ "${CHRX_TARGET_DISK}" =~ "mmcblk" ]]; then - # CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}p1" - #fi - set_root_partition 1 + CHRX_ROOT_PARTITION=$(get_disk_plus_partition 1) #dd if=/dev/zero of="${CHRX_ROOT_PARTITION}" bs=512 count=1 #printf ",,L,*\n" | sfdisk "${CHRX_TARGET_DISK}" @@ -58,7 +56,7 @@ else state_size="`cgpt show -i 1 -n -s -q ${CHRX_TARGET_DISK}`" max_os_size=$((${state_size}/1024/1024/2)) - rec_os_size=$((${max_os_size} - 1)) + rec_os_size=$((${max_os_size} - 10)) # If KERN-C and ROOT-C are one, we partition, otherwise assume they're what they need to be... if [ "${ckern_size}" = "1" -o "${croot_size}" = "1" ]; then while : @@ -137,14 +135,9 @@ fi ## set targets if [ -z "$CHRX_ROOT_PARTITION" ]; then - #CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}7" - #if [[ "${CHRX_TARGET_DISK}" =~ "mmcblk" ]]; then - # CHRX_ROOT_PARTITION="${CHRX_TARGET_DISK}p7" - #fi - set_root_partition 7 + CHRX_ROOT_PARTITION=$(get_disk_plus_partition 7) fi -echo_info "\nInstalling to ${CHRX_ROOT_PARTITION}..." eval_try umount -R ${CHRX_ROOT_PARTITION} 2>/dev/null eval_try umount -R ${CHRX_INSTALL_ROOT} 2>/dev/null @@ -155,6 +148,10 @@ if [ "`mount | grep ${CHRX_ROOT_PARTITION}`" ]; then exit 1 fi +prep_install() { +# TODO: since this is sourced this could define a command or function to run that gets executed in the chrx-install only after the user confirms they are good with losing data, and after it does a test mount to examine whether there is already something in partition 7 +# set_partitions { +echo_info "\nInstalling to ${CHRX_ROOT_PARTITION}..." eval_crit mkfs.ext4 ${VERBOSITY_MKFS} ${CHRX_ROOT_PARTITION} echo_info "Preparing installation root directory ${CHRX_INSTALL_ROOT}" @@ -166,7 +163,4 @@ if [ ! -d "${CHRX_INSTALL_ROOT}" ]; then fi eval_crit mount -t ext4 ${CHRX_ROOT_PARTITION} ${CHRX_INSTALL_ROOT} - -## clear error variable, which is checked in the calling script -SETUP_STORAGE_ERROR="" - +} diff --git a/dist/chrx-install-chroot b/dist/chrx-install-chroot old mode 100644 new mode 100755 index a1407b7..4b7d792 --- a/dist/chrx-install-chroot +++ b/dist/chrx-install-chroot @@ -32,7 +32,15 @@ apt_get_update_if_needed() ubuntu_update_core_image() { echo_title "Upgrading Ubuntu core image." + set_locale apt_get_update_if_needed + cat > /etc/apt/apt.conf.d/local <<-'EO_DPKG' +Dpkg::Options { + "--force-confdef"; + "--force-confold"; +} +EO_DPKG + apt-get -y ${VERBOSITY_APTGET} dist-upgrade apt_get_install ubuntu-minimal apt_get_install software-properties-common @@ -47,11 +55,17 @@ install_curl() install_utilities() { apt_get_update_if_needed - apt_get_install zram-config grub-pc + apt_get_install zram-config ${CHRX_BOOTLOADER} } apt_get_install() { + cat > /etc/apt/apt.conf.d/local <<-'EO_DPKG' +Dpkg::Options { + "--force-confdef"; + "--force-confold"; +} +EO_DPKG apt-get -y ${VERBOSITY_APTGET} install $* } @@ -405,6 +419,14 @@ install_language_support() set_locale() { echo_title "Setting locale to \"${CHRX_LOCALE}\"." + echo "LC_ALL=en_US.UTF-8" >> /etc/environment + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + echo "LANG=en_US.UTF-8" > /etc/locale.conf + locale-gen en_US.UTF-8 + export LANG=${CHRX_LOCALE} LC_ALL=${CHRX_LOCALE} + apt_get_install locales && \ + dpkg-reconfigure --frontend=noninteractive locales && \ + localedef -i en_US -f UTF-8 en_US.UTF-8 && \ update-locale LANG=${CHRX_LOCALE} LC_MESSAGES=${CHRX_LOCALE} } @@ -612,8 +634,21 @@ install_grub() echo_title_yel "(skipping chrx grub config)" fi - grub-mkconfig -o /boot/grub/grub.cfg - grub-install ${CHRX_TARGET_DISK} --force + BOOT_DIR=/boot/ + # Need to gracefully handle if the EFI partition is CSM (compatibility mode) only for SeaBIOS + # Need to check if CHRX_TARGET_DISK contains /dev/sd* or /dev/nvme* + if [[ "${CHRX_BOOTLOADER}" == *efi* ]]; then + ESP_DIR=$BOOT_DIR/efi/ + mkdir -p ${ESP_DIR} + # Assumes the root partition is 7, it mounts partition 12 EFI-SYSTEM + # Currently only supports ChromeOS partitioned internal drive + mount ${CHRX_ROOT_PARTITION/%[7]/12} ${ESP_DIR} + # Removable avoids efibootmgr warnings + EFI_GRUB_OPTS="--target=x86_64-efi --efi-directory=${ESP_DIR}" + fi + # Grub can figure out target if we aren't forcing EFI + grub-install ${EFI_GRUB_OPTS:-} --boot-directory=${BOOT_DIR} --recheck --removable ${CHRX_TARGET_DISK} + grub-mkconfig -o ${BOOT_DIR}/grub/grub.cfg #echo -e "\n${ANSI_GRN}Purging unwanted pkgs.${ANSI_RST}" #apt-get -y ${VERBOSITY_APTGET} purge openjade openjade1.3 jade tex-common sgml-base @@ -648,6 +683,7 @@ fedora_set_selinux_autolabel() ## begin #echo debug ; bash +do_install() { case "${CHRX_OS_DISTRO}" in *ubuntu) export DEBIAN_FRONTEND=noninteractive @@ -741,4 +777,6 @@ esac add_first_user +} +(return 0 2>/dev/null) && sourced=1 || sourced=0 do_install diff --git a/dist/chrx-install-extras b/dist/chrx-install-extras old mode 100644 new mode 100755 diff --git a/dist/chrx-mount b/dist/chrx-mount new file mode 100755 index 0000000..4f08d79 --- /dev/null +++ b/dist/chrx-mount @@ -0,0 +1,25 @@ +#!/bin/bash +# Manual Grub fixing for Chrx +# This exports any variables set between -a/+a +# while the := allows passing in an alternate path to mount/ +. ./chrx-setup-storage +set -a +: ${CHRX_INSTALL_ROOT:=/tmp/chrxroot} # \ + ${CHRX_ROOT_PARTITION:=$(get_disk_plus_partition 7)} \ + ${CHRX_EFI_PARTITION:=$(get_disk_plus_partition 12)} +set +a +# Need to use chrx-setup-storage if we can source it without setting the world on fire +# Or borrow the conditional that checks for the ROOT_DISK+partition +sudo mkdir -p ${CHRX_INSTALL_ROOT}/efi +sudo mount ${CHRX_ROOT_PARTITION} ${CHRX_INSTALL_ROOT} +sudo mount -o bind /proc ${CHRX_INSTALL_ROOT}/proc +sudo mount -o bind /dev ${CHRX_INSTALL_ROOT}/dev +sudo mount -o bind /dev/pts ${CHRX_INSTALL_ROOT}/dev/pts +sudo mount -o bind /sys ${CHRX_INSTALL_ROOT}/sys +sudo mount -o bind /run ${CHRX_INSTALL_ROOT}/run +sudo mkdir -p ${CHRX_INSTALL_ROOT}/run/resolvconf +sudo mkdir -p ${CHRX_INSTALL_ROOT}/run/systemd/resolve +cat /etc/resolv.conf | sudo tee ${CHRX_INSTALL_ROOT}/etc/resolv.conf +sudo mount ${CHRX_EFI_PARTITION} ${CHRX_INSTALL_ROOT}/efi + +sudo chroot ${CHRX_INSTALL_ROOT} /bin/bash diff --git a/fetch-install-from-local.sh b/fetch-install-from-local.sh new file mode 100644 index 0000000..1d860eb --- /dev/null +++ b/fetch-install-from-local.sh @@ -0,0 +1,13 @@ +#!/bin/bash +cleanup() { pkill python3; } +# Don't want previous `pkill -P $$` which would kill parent session if sourced? +# trap cleanup EXIT +export CHRX_WEB_ROOT="http://localhost:8000/" +python3 -m http.server & +sleep 3 # Lets the webserver start +curl $CHRX_WEB_ROOT/dist.tar.gz | sudo tar xzfC - /usr/local +# Only necessary if tar doesn't preserve permissions +# && sudo chmod +x /usr/local/bin/chrx* +chrx -h +chrx -h | grep -E 'installer.*version' +cleanup diff --git a/make-dist.sh b/make-dist.sh new file mode 100755 index 0000000..9baaa58 --- /dev/null +++ b/make-dist.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +# If you specify a version it will get packed into the chrx-install otherwise we append a string to denote it isn't a release build +# NEED_TEST +# pseudo TEST chrx -h | grep -E 'installer.*version' +: ${CHRX_VERSION:=$(grep -E '^CHRX_VERSION=' ./chrx-install | cut -f 2 -d '='| sed -e 's/"//g')-dev} +chrx_src=$(pwd) +build_dir=$(mktemp -d -t chrx.XXX) +cleanup() { rm -rf $build_dir; } +trap cleanup EXIT +echo $build_dir +cd $build_dir +mkdir bin +cp $chrx_src/chrx* ./bin +cp $chrx_src/dist/chrx* ./bin +# NEED_TEST +# Tweak the CHRX_VERSION in chrx-install +sed -i -e '/CHRX_VERSION=/ s/CHRX_VERSION=.*/CHRX_VERSION='$CHRX_VERSION'/' ./bin/chrx-install +# Debug print updated version +grep -E '^CHRX_VERSION=' ./bin/chrx-install +# Make sure they are executable as tar should preserve this on extract +chmod -R +x ./bin +mkdir -p etc/chrx-files +mv ./bin/chrx-devices ./etc/ +rm -rf $chrx_src/dist/etc/etc/ +cp -r -t ./etc/chrx-files/ $chrx_src/dist/etc/ +cd $chrx_src +# NEED_TEST +tar czf dist.tar.gz -C $build_dir $(ls -A $build_dir) +# Debug print contents for comparison to official chrx.org version +echo "Confirm contents" +tar tf dist.tar.gz