diff --git a/README.md b/README.md index 201e355..536b5ae 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,40 @@ A script to bootstrap a user with git and some auxiliary tools. -## Usage +## Building User Home Download and run the latest `bootstrap.sh`: - cd - git clone https://git.9iron.club/salt/bootstrap - ./bootstrap/bootstrap.sh $HOME +``` +cd +git clone https://git.9iron.club/salt/bootstrap +./bootstrap/bootstrap.sh $HOME +``` In the event that you want to simply test `bootstrap.sh`, simply pass a different argument to it: - ./bootstrap/bootstrap.sh -d /path/to/directory +``` +./bootstrap/bootstrap.sh -d /path/to/directory +``` See `bootstrap.sh -h` for more usage information. +## Building a Gentoo Install + +First, partition out the system and build a filesystem tree in `/mnt`. + +Then, download and run the latest `gentoostrap.sh`: + +``` +cd +git clone https://git.9iron.club/salt/bootstrap +sudo ./bootstrap/gentoostrap.sh +``` + +The script supports a fair few arguments, so it's worth looking into `gentoostrap.sh -h` if you need to customize the system. + +Note that this is highly specific to my environment. Most of the configuration management is done in Ansible, but this will create a user with my own personal setup. + ## Older Versions `build-home.sh` is an older version of the script kept here for legacy compatibility. Do not use it; use `bootstrap.sh`. diff --git a/gentoostrap.sh b/gentoostrap.sh new file mode 100755 index 0000000..f3da4b0 --- /dev/null +++ b/gentoostrap.sh @@ -0,0 +1,184 @@ +#! /bin/bash +# +# gentoostrap +# Build a Gentoo system in /mnt +# Copyright (C) 2020 Vintage Salt +# +# Distributed under terms of the MIT license. +# +set -e + +# Read-only set-once variables +declare -r _name="$(basename -- "$0")" +# Options +declare -i _optchroot +declare _optdest="/mnt" +declare -i _opthelp +declare -i _optverbose +# Working variables +declare -a _args +declare _return + +# Helper functions +log() { + # Print a line to the terminal if _optverbose is greater than $2 + # $2 defaults to 0 + # loglevel 0: Daily-use messages + # loglevel 1: Detailed but not quite debugging + # loglevel 2: Definitely debugging + [ -z "$1" ] && return 1 + if (( _optverbose >= ${2:-0} )); then + printf "%s\\n" "$1" + fi +} +warn() { + # Print a yellow line to the terminal, respecting _optverbose + [ -z "$1" ] && return 1 + if (( _optverbose >= ${2:-0} )); then + if [ -t 1 ]; then + printf "\\e[33m%s\\e[0m\\n" "$1" + else + printf "WARN: %s\\n" "$1" + fi + fi +} +error() { + # Print a red line to the terminal, exit if $2 is specified + [ -z "$1" ] && return 1 + if [ -t 2 ]; then + printf "\\e[31m%s\\e[0m\\n" "$1" 1>&2 + else + printf "ERROR: %s\\n" "$1" 1>&2 + fi + [ -z "$2" ] && return + exit "${2:-1}" +} +has() { + # Parse out all arguments and try to find them in path + # If an argument cannot be found, set _return and fail + for prog in "$@"; do + if ! command -v "$prog" > /dev/null 2>&1; then + _return="$prog" + return 1 + fi + done + return 0 +} + +# Core program functions +printhelp() { + cat << EOF +Usage: $_name [OPTION]... + + -h Print this help text + -c Perform the Gentoo half of installation. Must be invoked from a chroot + -v Print more status messages. Stacks + +Copyright (c) 2020 rehashedsalt@cock.li +Licensed under the MIT license +EOF +} +build-gentoo() { + # Build Gentoo + + # First, get a link to a stage3 tarball + stage3="http://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64-systemd/$( + curl -s http://distfiles.gentoo.org/releases/amd64/autobuilds/current-stage3-amd64-systemd/ \ + | grep -oe 'stage3-amd64-systemd-20.*\.tar\.xz' \ + | sed 's/^stage3.*">//g' \ + | uniq \ + | sort \ + | head -n 1 + )" + stage3file="$(mktemp "tmp.$USER.$_name.XXXXXX-stage3.tar.xz" -p "/tmp")" + trap "cleanup $stage3file" EXIT + log "Getting tarball from: $stage3" + curl -s "$stage3" -o "$stage3file" + log "Decompressing tarball; this will prompt for root privileges" + sudo tar xf "$stage3" -C "$_optdest" + + # Now we do some pre-chroot configuration + pushd "$_optdest" > /dev/null 2>&1 + # These is a very generic make.conf to get the system up and running + # We use march of x86-64 to ensure compatibility if we're bootstrapping on a host other than the target + cat <<-EOF > "$_optdest/etc/portage/make.conf" + COMMON_FLAGS="-march=x86-64 -mtune=generic -O2 -pipe" + CFLAGS="\${COMMON_FLAGS}" + CXXFLAGS="\${COMMON_FLAGS}" + GENTOO_MIRRORS="http://distfiles.gentoo.org" + MAKEOPTS="$(nproc)" + EOF + # Configure default ebuild repositories + mkdir -p "$_optdest/etc/portage/repos.conf" + cp "$_optdest/usr/share/portage/config/repos.conf" \ + "$_optdest/etc/portage/repos.conf/gentoo.conf" + # DNS + cat <<-EOF > "$_optdest/etc/resolv.conf" + nameserver 8.8.8.8 + nameserver 8.8.4.4 + EOF + + # Now we need to pivot into a chroot and finish configuration natively + # Buuuut... since we're using systemd, we get to just spawn a systemd-nspawn container + popd + cp "$0" "$_optdest/gentoostrap.sh" + sudo systemd-nspawn --directory="$_optdest" "/gentoostrap.sh -c" +} +build-gentoo-chroot() { + # Build Gentoo, but from within the chroot environment + : +} + +# Main +main() { + # Parse out arguments + while [ -n "$1" ]; do + # Parse out flags + while getopts ":chv" opt; do + case $opt in + c) + _optchroot=1 + ;; + h) + _opthelp=1 + ;; + v) + _optverbose+=1 + ;; + :) + error "Option requires argument: -$OPTARG" 2 + ;; + *) + error "Invalid option: -$OPTARG" 2 + ;; + esac + done + # Store arguments + shift $((OPTIND - 1)) + if [ -n "$1" ]; then + _args+=("$1") + shift + fi + unset OPTIND + done + # Early hook for help + [ -n "$_opthelp" ] && printhelp && exit 0 + # Validate critical options + # TODO: That + # Validate core program dependencies + log "Validating dependencies" 2 + if ! has basename curl tar; then + error "Failed to find program: $_return" 1 + fi + + # Do the do + if [ -z "$_optchroot" ]; then + build-gentoo + else + build-gentoo-chroot + fi + exit 0 +} + +main "$@" +