diff --git a/Makefile b/Makefile index c06d82a5..c07a1b76 100644 --- a/Makefile +++ b/Makefile @@ -408,6 +408,24 @@ release-iso: $(SORTIX_RELEASE_DIR)/$(VERSION)/builds/$(BUILD_NAME).iso .PHONY: release-builds release-builds: release-iso +$(SORTIX_RELEASE_DIR)/$(VERSION)/scripts: $(SORTIX_RELEASE_DIR)/$(VERSION) + mkdir -p $@ + +$(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-add: tix/tix-iso-add $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts + cp $< $@ + +$(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-bootconfig: tix/tix-iso-bootconfig $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts + cp $< $@ + +$(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-liveconfig: tix/tix-iso-liveconfig $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts + cp $< $@ + +.PHONY: release-scripts +release-scripts: \ + $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-add \ + $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-bootconfig \ + $(SORTIX_RELEASE_DIR)/$(VERSION)/scripts/tix-iso-liveconfig \ + $(SORTIX_RELEASE_DIR)/$(VERSION)/README: README $(SORTIX_RELEASE_DIR)/$(VERSION) cp $< $@ @@ -418,7 +436,7 @@ release-readme: $(SORTIX_RELEASE_DIR)/$(VERSION)/README release-arch: release-builds release-readme .PHONY: release-shared -release-shared: release-readme +release-shared: release-readme release-scripts .PHONY: release release: release-arch release-shared diff --git a/build-aux/iso-grub-cfg.sh b/build-aux/iso-grub-cfg.sh index bb66a5f0..fb262a33 100755 --- a/build-aux/iso-grub-cfg.sh +++ b/build-aux/iso-grub-cfg.sh @@ -1,4 +1,24 @@ -#!/bin/sh -e +#!/bin/sh +# Copyright (c) 2018 Jonas 'Sortie' Termansen. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# iso-grub-cfg.sh +# Generate GRUB bootloader configuration for release .iso filesystems. + +# Note: This file has detailed documentation in release-iso-bootconfig(7). + +set -e this=$(which -- "$0") thisdir=$(dirname -- "$this") @@ -67,7 +87,8 @@ maybe_compressed() { } human_size() { - LC_ALL=C du -bh "$1" | grep -Eo '^[^[:space:]]+' + (export LC_ALL=C; du -bh "$1" 2>/dev/null || du -h "$1") | + sed -E 's/^([^[:space:]]+).*/\1/' } portvar() { @@ -99,6 +120,43 @@ ports=$(ls repository | sed 's/\.tix\.tar\.xz//') mkdir -p boot/grub exec > boot/grub/grub.cfg +for hook in \ +advanced_menu_post \ +advanced_menu_pre \ +initrd_post \ +kernel_post \ +kernel_pre \ +menu_post \ +menu_pre \ +ports_menu \ +ports_menu_post \ +ports_menu_pre \ +ports_menu_sets \ +ports_post \ +ports_pre \ +tix_menu \ +tix_menu_post \ +tix_menu_pre \ +tix_menu_sets \ +; do + cat << EOF +function hook_$hook { + true +} +EOF +done +for set in all $sets no; do + cat << EOF +function hook_ports_set_$set { + true +} +function hook_tix_set_$set { + true +} +EOF +done +echo + cat << EOF insmod part_msdos insmod ext2 @@ -106,7 +164,6 @@ EOF find . | grep -Eq '\.gz$' && echo "insmod gzio" find . | grep -Eq '\.xz$' && echo "insmod xzio" -echo cat << EOF insmod all_video if loadfont unicode; then @@ -114,13 +171,25 @@ if loadfont unicode; then terminal_output gfxterm fi -set menu_title="Sortix $version for $machine" +set version="$version" +set machine="$machine" +set base_menu_title="Sortix \$version for \$machine" +set menu_title="\$base_menu_title" set timeout=10 set default="0" +if [ -e /boot/random.seed ]; then + no_random_seed= +else + no_random_seed=--no-random-seed +fi +export version +export machine +export base_menu_title export menu_title export timeout export default +export no_random_seed EOF if [ -n "$ports" ]; then @@ -141,11 +210,55 @@ if [ -n "$ports" ]; then fi echo -cat << EOF -. /boot/grub/main.cfg -EOF +echo 'function select_ports_set_no {' +for port in $ports; do + printf " port_%s=false\n" "$(portvar "$port")" +done +printf " hook_port_set_no\n" +echo "}" +for set in $sets; do + echo + set_content=$(eval echo \$set_$set) + echo "function select_ports_set_$set {" + for port in $ports; do + printf " port_%s=%s\n" "$(portvar "$port")" "$(isinset "$port" "$set_content")" + done + printf " hook_port_set_%s\n" "$set" + echo "}" +done +echo +echo 'function select_ports_set_all {' +for port in $ports; do + printf " port_%s=true\n" "$(portvar "$port")" +done +printf " hook_port_set_all\n" +echo "}" -exec > boot/grub/main.cfg +echo +echo 'function select_tix_set_no {' +for port in $ports; do + printf " tix_%s=false\n" "$(portvar "$port")" +done +printf " hook_tix_set_no\n" +echo "}" +for set in $sets; do + echo + set_content=$(eval echo \$set_$set) + echo "function select_tix_set_$set {" + for port in $ports; do + printf " tix_%s=%s\n" "$(portvar "$port")" "$(isinset "$port" "$set_content")" + done + printf " hook_tix_set_%s\n" "$set" + echo "}" +done +echo +echo 'function select_tix_set_all {' +for port in $ports; do + printf " tix_%s=true\n" "$(portvar "$port")" +done +printf " hook_tix_set_all\n" +echo "}" +echo printf "function load_base {\n" case $platform in @@ -161,10 +274,18 @@ EOF ;; esac cat << EOF + hook_kernel_pre echo -n "Loading /$kernel ($(human_size $kernel)) ... " - multiboot /$kernel --no-random-seed "\$@" + multiboot /$kernel \$no_random_seed "\$@" echo done + hook_kernel_post + if [ \$no_random_seed != --no-random-seed ]; then + echo -n "Loading /boot/random.seed (256) ... " + module /boot/random.seed --random-seed + echo done + fi EOF +# TODO: Make loading of the /src initrd optional. for initrd in $system_initrd $src_initrd $live_initrd $overlay_initrd; do cat << EOF echo -n "Loading /$initrd ($(human_size $initrd)) ... " @@ -172,12 +293,18 @@ for initrd in $system_initrd $src_initrd $live_initrd $overlay_initrd; do echo done EOF done -printf "}\n" +cat << EOF + hook_initrd_post +} +EOF echo -printf "function load_ports {\n" +cat << EOF +function load_ports { + hook_ports_pre +EOF if [ -z "$ports" ]; then -printf "\ttrue\n" + printf " true\n" fi for port in $ports; do tix=repository/$port.tix.tar.xz @@ -194,7 +321,10 @@ for port in $ports; do fi EOF done -printf "}\n" +cat << EOF + hook_ports_post +} +EOF echo cat << EOF @@ -204,85 +334,111 @@ function load_sortix { } EOF +cat << EOF + +if [ -e /boot/grub/hooks.cfg ]; then + . /boot/grub/hooks.cfg +fi + +. /boot/grub/main.cfg +EOF + +exec > boot/grub/main.cfg + menuentry() { echo printf "menuentry \"Sortix (%s)\" {\n" "$1" if [ -n "$2" ]; then - printf "\tload_sortix %s\n" "$2" - #printf "\tload_sortix '" + printf " load_sortix %s\n" "$2" + #printf " load_sortix '" #printf '%s' "$2" | sed "s,','\\'',g" #printf "'\n" else - printf "\tload_sortix\n" + printf " load_sortix\n" fi printf "}\n" } +cat << EOF +menu_title="\$base_menu_title" + +hook_menu_pre +EOF + menuentry "live environment" '-- /sbin/init' menuentry "new installation" '-- /sbin/init --target=sysinstall' menuentry "upgrade existing installation" '-- /sbin/init --target=sysupgrade' -echo cat << EOF + menuentry "Select ports..." { - configfile /boot/grub/ports.cfg + configfile /boot/grub/ports.cfg } menuentry "Advanced..." { - configfile /boot/grub/advanced.cfg + configfile /boot/grub/advanced.cfg } + +hook_menu_post EOF exec > boot/grub/advanced.cfg cat << EOF menuentry "Back..." { - menu=main configfile /boot/grub/main.cfg } +menu_title="\$base_menu_title - Advanced Options" + +hook_advanced_menu_pre + menuentry "Select binary packages..." { - configfile /boot/grub/tix.cfg + configfile /boot/grub/tix.cfg } + +hook_advanced_menu_post EOF exec > boot/grub/ports.cfg cat << EOF menuentry "Back..." { - menu=main configfile /boot/grub/main.cfg } -EOF -echo -printf 'menuentry "Load all ports" {' -for port in $ports; do - printf " port_%s=true\n" "$(portvar "$port")" -done -printf ' configfile /boot/grub/ports.cfg\n' -printf '}\n' +menu_title="\$base_menu_title - Ports" + +hook_ports_menu_pre + +menuentry "Load all ports" { + select_ports_set_all + configfile /boot/grub/ports.cfg +} + +hook_ports_menu_sets +EOF for set in $sets; do echo set_content=$(eval echo \$set_$set) - printf 'menuentry "Load only '"$set"' ports" {' - for port in $ports; do - printf " port_%s=%s\n" "$(portvar "$port")" "$(isinset "$port" "$set_content")" - done + printf 'menuentry "Load only '"$set"' ports" {\n' + printf " select_ports_set_%s\n" "$set" printf ' configfile /boot/grub/ports.cfg\n' printf '}\n' done -echo -printf 'menuentry "Load no ports" {' -for port in $ports; do - printf " port_%s=false\n" "$(portvar "$port")" -done -printf ' configfile /boot/grub/ports.cfg\n' -printf '}\n' +cat << EOF + +menuentry "Load no ports" { + select_ports_set_no + configfile /boot/grub/ports.cfg +} + +hook_ports_menu + +EOF -echo for port in $ports; do cat << EOF if \$port_$(portvar "$port"); then @@ -299,43 +455,50 @@ fi EOF done +cat << EOF + +hook_ports_menu_post +EOF + exec > boot/grub/tix.cfg cat << EOF menuentry "Back..." { - menu=main configfile /boot/grub/advanced.cfg } -EOF -echo -printf 'menuentry "Load all binary packages" {' -for port in $ports; do - printf " tix_%s=true\n" "$(portvar "$port")" -done -printf ' configfile /boot/grub/tix.cfg\n' -printf '}\n' +menu_title="\$base_menu_title - Binary Packages" + +hook_tix_menu_pre + +menuentry "Load all binary packages" { + select_tix_set_all + configfile /boot/grub/tix.cfg +} + +hook_tix_menu_sets +EOF for set in $sets; do echo set_content=$(eval echo \$set_$set) - printf 'menuentry "Load only '"$set"' binary packages" {' - for port in $ports; do - printf " tix_%s=%s\n" "$(portvar "$port")" "$(isinset "$port" "$set_content")" - done + printf 'menuentry "Load only '"$set"' binary packages" {\n' + printf " select_tix_set_%s\n" "$set" printf ' configfile /boot/grub/tix.cfg\n' printf '}\n' done -echo -printf 'menuentry "Load no binary packages" {' -for port in $ports; do - printf " tix_%s=false\n" "$(portvar "$port")" -done -printf ' configfile /boot/grub/tix.cfg\n' -printf '}\n' +cat << EOF + +menuentry "Load no binary packages" { + select_tix_set_no + configfile /boot/grub/tix.cfg +} + +hook_tix_menu + +EOF -echo for port in $ports; do cat << EOF if \$tix_$(portvar "$port"); then @@ -351,3 +514,8 @@ else fi EOF done + +cat << EOF + +hook_tix_menu_post +EOF diff --git a/share/man/man7/installation.7 b/share/man/man7/installation.7 index a0cbdfdc..b16faae8 100644 --- a/share/man/man7/installation.7 +++ b/share/man/man7/installation.7 @@ -72,6 +72,23 @@ medium over any existing operating system installations. After the installation is complete, remove the installation medium and restore the firmware boot order to prioritize the local harddisk. Then power the computer on normally to run the new operating system. +.Ss Release .iso Modification +Optionally, you might want to modification a release .iso to meet your custom +needs per the instructions in +.Xr release-iso-modification 7 . +.Pp +The release modification procedure lets you customize aspects such as the +default bootloader menu option and timeout, the default hostname, the default +keyboard layout, the default graphics resolution, adding files of your choice to +the live environment, and so on. +.Pp +Warning: The live environment does not come with any random entropy and entropy +gathering is not yet implemented. +To keep your system secure, it is recommended to use the release modification +procedure to add a +.Pa /boot/random.seed +file to the release .iso in order to securely seed the cryptographically secure +pseudorandom number generator. .Ss Qemu Virtual machines are a well-supported installation target. For instance, to prepare a 1 GiB harddisk and install the operating system onto @@ -371,6 +388,7 @@ Congratulations on your new Sortix system. .Xr initrd 7 , .Xr kernel 7 , .Xr mbr 7 , +.Xr release-iso-modification 7 , .Xr upgrade 7 , .Xr user-guide 7 , .Xr disked 8 , diff --git a/share/man/man7/release-iso-bootconfig.7 b/share/man/man7/release-iso-bootconfig.7 new file mode 100644 index 00000000..504a0ca0 --- /dev/null +++ b/share/man/man7/release-iso-bootconfig.7 @@ -0,0 +1,554 @@ +.Dd February 24, 2018 +.Dt RELEASE-ISO-BOOTCONFIG 7 +.Os +.Sh NAME +.Nm release-iso-bootconfig +.Nd release .iso bootloader configuration +.Sh DESCRIPTION +You can customize the bootloader configuration of a release .iso by adding your +own +.Pa /boot/grub/hooks.cfg +to the .iso filesystem as part of the +.Xr release-iso-modification 7 +procedure. +This manual page details the programming interface available when writing this +file. +.Pp +Commonly a custom +.Pa /boot/grub/hooks.cfg +would take some actions when loaded (such as setting variables) +and define hook functions as described in the +.Sx Hooks +subsection to inject behavior in certain locations, and otherwise make use of +the facilities described in this manual page. +.Ss Ports and Binary Packages +The release .iso contains binary packages. +The ports menu controls what binary packages are installed in the live +environment. +.Ss Port Sets +The binary packages menu controls what binary packages have a copy stored in the +.Pa /repository +directory inside the live environment. +.Pp +Sets of ports and binary packages are defined by +.Pa build-aux/ports.conf +in the source code: +.Bl -tag -width "12345678" +.It Sy all +All ports. +.It Sy basic +Common software and everything needed to develop the operating system +.It Sy minimal +Ports needed to successfully install and upgrade the operating system. +.It Sy no +No ports. +.El +.Ss Configuration Files +The bootloader configuration consists of these GRUB configuration files that you +can use or overwrite as desired: +.Bl -tag -width "12345678" +.It Pa /boot/grub/grub.cfg +The GRUB bootloader will load its configuration by loading this file. +.Pp +First, this file loads the default bootloader configuration by taking the following +actions: +.Pp +It defining no-operation versions of each of the hook functions defined below. +.Pp +It loads the appropriate GRUB modules. +.Pp +It initializes the global variable described below. +.Pp +It defines functions to select each set of ports and binary package, as +described below loaded above. +.Pp +Secondly, it loads +.Pa /boot/grub/hooks.cfg +(if it exists) +which can take any actions it wants and customize the default configuration. +.Pp +Finally, it loads +.Pa /boot/grub/main.cfg +to display the menu menu. +.It Pa /boot/grub/hooks.cfg +This file provides additional bootloader configuration if it exists. +.Pp +This file is loaded (if it exists) by +.Pa /boot/grub/grub.cfg +after the default bootloader configuration has been loaded. +The bootloader configuration is designed to be customized by setting the +variables defined below, defining any of the hook functions defined below, or +any other desired actions. +.It Pa /boot/grub/main.cfg +This file displays the main bootloader menu by taking the following actions: +.Pp +The +.Sy menu_title +variable is set to the contents of the +.Sy base_menu_title +variable. +.Pp +The +.Sy hook_menu_pre +hook is run. +.Pp +Menu entries are emitted for the live environment, the installer, and the +upgrader. +.Pp +The live environment menu entry runs: +.Li load_sortix -- /sbin/init --target=single-user +.Pp +The installer menu entry runs: +.Li load_sortix -- /sbin/init --target=sysinstall +.Pp +The upgrader menu entry runs: +.Li load_sortix -- /sbin/init --target=sysupgrade +.Pp +Menu entries are emitted for the ports selection bootloader menu (which runs +.Li configfile /boot/grub/ports.cfg ) +and the advanced bootloader menu (which runs +.Li configfile /boot/grub/advanced.cfg ) +.Pp +Finally the +.Sy hook_menu_post +hook is run. +.It Pa /boot/grub/advanced.cfg +This file displays the advanced bootloader menu by taking the following actions: +.Pp +A menu entry is emitted that goes back to the main menu (which runs +.Li configfile /boot/grub/main.cfg ) +.Pp +The +.Sy menu_title +variable is set to the contents of the +.Sy base_menu_title +variable appended with " - Advanced Options". +.Pp +The +.Sy hook_advanced_menu_pre +hook is run. +.Pp +A menu entry is emitted that goes to the binary packages menu (which runs +.Li configfile /boot/grub/tix.cfg ) +.Pp +Finally, the +.Sy hook_advanced_menu_post +hook is run. +.It Pa /boot/grub/ports.cfg +This file displays the port selection bootloader menu by taking the following +actions: +.Pp +A menu entry is emitted that goes back to the main menu (which runs +.Li configfile /boot/grub/main.cfg ) +.Pp +The +.Sy menu_title +variable is set to the contents of the +.Sy base_menu_title +variable appended with " - Ports". +.Pp +The +.Sy hook_ports_menu_pre +hook is run. +.Pp +The following menu entries implicitly run +.Li configfile /boot/grub/ports.cfg +afterwards to return to this menu. +.Pp +A menu entry is emitted that loads all ports by running +.Sy select_ports_set_all . +.Pp +The +.Sy hook_ports_menu_pre +hook is run. +.Pp +Menu entries are emitted for each of the port sets, each of which load only +those ports set by running +.Sy select_ports_set_ Ns Ar $set . +.Pp +A menu entry is emitted that loads no ports by running +.Sy select_ports_set_no . +.Pp +The +.Sy hook_ports_menu +hook is run. +.Pp +Menu entries are emitted for each port, each stating whether that port will be +loaded, and selecting such a menu entry will toggle whether the port is loaded +by setting +.Sy port_ Ns Ar $set +variable to +.Sy true +or +.Sy false . +.Pp +Finally, the +.Sy hook_ports_menu_post +hook is run. +.It Pa /boot/grub/tix.cfg +This file displays the binary packages selection bootloader menu by taking the +following actions: +.Pp +A menu entry is emitted that goes back to the advanced menu (which runs +.Li configfile /boot/grub/advanced.cfg ) +.Pp +The +.Sy menu_title +variable is set to the contents of the +.Sy base_menu_title +variable appended with " - Binary Packages". +.Pp +The +.Sy hook_tix_menu_pre +hook is run. +.Pp +The following menu entries implicitly run +.Li configfile /boot/grub/tix.cfg +afterwards to return to this menu. +.Pp +A menu entry is emitted that loads all binary packages by running +.Sy select_tix_set_all . +.Pp +The +.Sy hook_tix_menu_pre +hook is run. +.Pp +Menu entries are emitted for each of the binary package sets, each of which load +only those binary packages set by running +.Sy select_tix_set_ Ns Ar $set . +.Pp +A menu entry is emitted that loads no binary packages by running +.Sy select_tix_set_no . +.Pp +The +.Sy hook_tix_menu +hook is run. +.Pp +Menu entries are emitted for each binary package, each stating whether that +binary package will be loaded, and selecting such a menu entry will toggle +whether the binary package is loaded +by setting +.Sy tix_ Ns Ar $set +variable to +.Sy true +or +.Sy false . +.Pp +Finally, the +.Sy hook_tix_menu_post +hook is run. +.El +.Ss Variables +In addition to the standard GRUB variables, the following global variables are +set in +.Pa /boot/grub/grub.cfg : +.Bl -tag -width "12345678" +.It Sy base_menu_title +The base menu title which is used to construct the menu titles for each of the +menus by setting the +.Sy menu_title +variable. +The main menu uses this title verbatim, while the other menus will append +" - +.Ar menu_name Ns +" when constructing +.Sy menu_title. +(Default: "Sortix $version for $machine") +.It Sy default +Select this bootloader menu option number by default (counting from 0). +If the selected menu option itself is a submenu, it can be appended with a +.Sy '>' +and another selection to pick a default menu option in that submenu, and so on. +(Default: 0) +.It Sy machine_type +The machine type this release was built for. +.It Sy menu_title +The menu title to display above the bootloader menu. +(Default: "$base_menu_title") +.It Sy no_random_seed +An additional command line parameter passed to the +.Xr kernel 7 +if +.Pa /boot/random.seed +doesn't exist. +This variable defaults to +.Sy --no-random-seed +if +.Pa /boot/random.seed +doesn't exist, otherwise it defaults to the empty string. +.It Sy port_ Ns Ar $port +The +.Ar port +is installed into live environment if this variable is set to +.Sy true +and not if set to +.Sy false . +(Default: +.Sy true ) +.It Sy timeout +The time in seconds before the default menu entry (according to the +.Sy default +variable) is automatically selected. +If set to 0, the default menu entry is loaded instantaneously. +The timeout is disabled if set to -1. +(Default: 10) +.It Sy tix_ Ns Ar $port +A copy of the binary package is stored in +.Pa /repository +in the live environment if this variable is set to +.Sy true +and not if set to +.Sy false . +(Default: +.Sy true ) +.It Sy version +The version number of this release. +.El +.Ss Functions +In addition to the standard GRUB functions, the following functions are set in +.Pa /boot/grub/grub.cfg : +.Bl -tag -width "12345678" +.It Sy load_base +This function loads the base system into the live environment by taking the +following actions: +.Pp +If this is x86_64 system, check using +.Li cpuid -l +whether the processor supports 64-bit mode and error if not. +.Pp +Run the +.Sy hook_kernel_pre +hook. +.Pp +Load +.Pa /boot/sortix.bin.xz +as a multiboot kernel, +with a +.Xr kernel 7 +command line consisting of +.Sy $no_random_seed +followed by the arguments to this function (which should contain +.Li "-- /sbin/init --target=desired-target" ) +followed by any additional options to +.Xr init 8 . +.Pp +Run the +.Sy hook_kernel_post +hook. +.Pp +If +.Sy no_random_seed +is not set to +.Sy --no-random-seed , +load +.Pa /boot/random.seed +as a multiboot module with the +.Li --random-seed +command line. +.Pp +Load +.Pa /boot/system.initrd.xz , +.Pa /boot/src.initrd.xz , +.Pa /boot/live.initrd.xz , +and +.Pa /boot/overlay.initrd.xz +(only if a +.Pa sysroot-overlay +directory existed when making the release .iso) +as multiboot modules without any command line. +.Pp +Run the +.Sy hook_initrd_post +hook. +.It Sy load_ports +Load the ports and binary packages into the live environment by taking the +following actions: +.Pp +Run the +.Sy hook_ports_pre +hook. +.Pp +For each port, if +.Sy tix_ Ns Ar $port +is +.Sy true , +then load the port as a binary package by running: +.Bd -literal + module --nounzip /repository/$port.tix.tar.xz \\ + --to /repository/$port.tix.tar.xz +.Ed +And if +.Sy port_ Ns Ar $port +is +.Sy true , +then install the port into the live environment by running: +.Bd -literal + module /repository/$port.tix.tar.xz --tix +.Ed +.Pp +Run the +.Sy hook_ports_post +hook. +.It Sy load_sortix +Load the base system and ports into the live environment by running +.Sy load_base +with the given arguments and then run +.Sy load_ports . +.It Sy select_ports_set_ Ns Ar $set +Install only the ports that belong to the ports set +.Ar set . +Run the +.Sy hook_port_set Ns Ar $set +hook afterwards. +.It Sy select_tix_set_ Ns Ar $set +Load only the binary packages that belong to the ports set +.Ar set . +Run the +.Sy hook_tix_set Ns Ar $set +hook afterwards. +.El +.Ss Hooks +The following hooks are run by the GRUB bootloader configuration: +.Bl -tag -width "12345678" +.It Sy hook_advanced_menu_post +After the advanced menu entries have been emitted. +.It Sy hook_advanced_menu_pre +Before the advanced menu entries are emitted. +.It Sy hook_initrd_post +After the initrd is loaded. +.It Sy hook_kernel_post +After the kernel has been loaded. +.It Sy hook_kernel_pre +Before the kernel is loaded and before the initrd is loaded. +.It Sy hook_menu_post +After the main menu entries have been emitted. +.It Sy hook_menu_pre +Before the main menu entries are emitted. +.It Sy hook_ports_menu +After the port sets menu entries have been emitted and before the individual +port menu entires are emitted as a way to define additional ports to be loaded +or not. +.It Sy hook_ports_menu_post +After the ports selection menu entries have been emitted. +.It Sy hook_ports_menu_pre +Before the ports selection menu entries are emitted. +.It Sy hook_ports_menu_sets +After the "Load all ports" menu entry has been emitted as a place to define +additional sets to be loaded. +.It Sy hook_ports_post +After the ports and binary packages have been loaded. +.It Sy hook_ports_pre +Before the ports and binary packages are loaded. +.It Sy hook_ports_set_ Ns Ar $set +After the menu entry has been picked that chooses the given +.Ar set +of ports and the port variables have been updated. +.It Sy hook_tix_menu +After the binary packages sets menu entries have been emitted and before the +individual binary packages menu entires are emitted as a way to define +additional binary packages to be loaded or not. +.It Sy hook_tix_menu_post +After the binary packages selection menu entries have been emitted. +.It Sy hook_tix_menu_pre +Before the binary packages selection menu entries are emitted. +.It Sy hook_tix_menu_sets +After the "Load all binary packages" menu entry has been emitted as a place to +define additional sets to be loaded. +.It Sy hook_tix_set_ Ns Ar $set +After the menu entry has been picked that chooses the given +.Ar set +of binary packages and the binary packages variables have been updated. +.El +.Pp +For more information on the GRUB configuration file format and the available +commands, see the GRUB manual. +.Sh EXAMPLES +Adding the port +.Sy foo +to the +.Sy basic +and +.Sy all +port sets can be done with this +.Pa /boot/grub/hooks.cfg : +.Bd -literal +port_foo=true +tix_foo=false +export port_foo +export tix_foo +function hook_ports_menu { + if $port_foo; then + menuentry "foo = true" { + port_foo=false + configfile /boot/grub/ports.cfg + } + else + menuentry "foo = false" { + port_foo=true + configfile /boot/grub/ports.cfg + } + fi +} +function hook_tix_menu { + if $tix_foo; then + menuentry "foo = true" { + tix_foo=false + configfile /boot/grub/tix.cfg + } + else + menuentry "foo = false" { + tix_foo=true + configfile /boot/grub/tix.cfg + } + fi +} +function hook_ports_set_all { + port_foo=true +} +function hook_tix_set_all { + tix_foo=true +} +function hook_ports_set_basic { + port_foo=true +} +function hook_tix_set_basic { + tix_foo=true +} +function hook_ports_set_minimal { + port_foo=false +} +function hook_tix_set_minimal { + tix_foo=false +} +function hook_ports_set_no { + port_foo=false +} +function hook_tix_set_no { + tix_foo=false +} +function hook_ports_pre { + if $tix_foo; then + echo -n "Loading /repository/foo.tix.tar.xz (3.0M) ... " + module --nounzip /repository/foo.tix.tar.xz \\ + --to /repository/foo.tix.tar.xz + echo done + fi + if $port_foo; then + echo -n "Loading /repository/foo.tix.tar.xz (3.0M) ... " + module /repository/foo.tix.tar.xz --tix + echo done + fi +} +.Ed +.Pp +The +.Xr tix-iso-bootconfig 8 +convenience script makes it easy to generate bootloader configuration for +common scenarios. +.Pp +See +.Xr release-iso-modification 7 +for additional examples. +.Sh SEE ALSO +.Xr release-iso-bootconfig 7 , +.Xr tix-iso-bootconfig 8 diff --git a/share/man/man7/release-iso-modification.7 b/share/man/man7/release-iso-modification.7 new file mode 100644 index 00000000..102aabea --- /dev/null +++ b/share/man/man7/release-iso-modification.7 @@ -0,0 +1,404 @@ +.Dd February 5, 2018 +.Dt RELEASE-ISO-MODIFICATION 7 +.Os +.Sh NAME +.Nm release-iso-modification +.Nd instructions on how to modify release .iso filesystems +.Sh DESCRIPTION +This document describes how to modify Sortix .iso releases to meet your custom +needs. +The bootloader configuration in .iso releases is designed with an extensible +hooks system that let's you override it with further configuration and to load +additional files of your choice into the live environment. +The live environment is configurable through the normal operating system +configuration as described in section 5 of the manual. +.Pp +The release modification procedure lets you customize aspects such as the +default bootloader menu option and timeout, the default hostname, the default +keyboard layout, the default graphics resolution, adding files of your choice to +the live environment, and so on. +.Ss Prerequisites +.Bl -bullet -compact +.It +A +.Pa sortix-x.y-arch.iso +release for your architecture. +.It +.Xr xorriso 1 +needs to be installed. +.El +.Ss Overview +The release modification process has three stages: +.Pp +.Bl -bullet -compact +.It +Optionally, creating additional files that will be loaded onto the live +environment (the liveconfig). +.It +Creating additional bootloader configuration (the bootconfig), which will +contain an archived copy of the liveconfig (if any). +.It +Adding the bootconfig to the release .iso. +.El +.Pp +The bootloader menu Install and Upgrade selections will start the live +environment and run the +.Xr sysinstall 8 +installer and +.Xr sysupgrade 8 +upgrader respectively and they are thus also customizable by this procedure. +.Ss Convenience Scripts +The release modification can be done manually by hand, or you can use the +following convenience scripts that make the release modification easy: +.Pp +.Bl -bullet -compact +.It +.Xr tix-iso-liveconfig 8 +that generates additional configuration files for the live environment. +.It +.Xr tix-iso-bootconfig 8 +that generates additional bootloader configuration and optionally configures the +bootloader to load the liveconfig into the live environment. +.It +.Xr tix-iso-add 8 +that adds the bootconfig (and thus the liveconfig if any) to the release .iso. +.El +.Pp +These convenience scripts come with the operating system and are installed in +the +.Pa /sbin +directory. +These scripts are entirely for convenience and you can perform their tasks +yourself if they don't meet your needs. +The scripts are readable shell scripts and you can learn how they work and +extend them with your own features. +.Pp +If you are not on a Sortix system or on a different version of Sortix than the +one you are customizing, you can download the shell scripts matching the latest +stable release: +.Pp +.Bl -bullet -compact +.It +.Lk https://sortix.org/release/stable/scripts/tix-iso-liveconfig +.It +.Lk https://sortix.org/release/stable/scripts/tix-iso-bootconfig +.It +.Lk https://sortix.org/release/stable/scripts/tix-iso-add +.El +.Pp +If you are not customizing the latest stable release, you can find the matching +versions of the scripts in the +.Pa scripts/ +subdirectory of the appropriate release directory, or you can check out the +.Pa tix +directory in the source code from +.Lk https://sortix.org/source/ +matching the release you are currently customizing. +.Ss Additional Live Configuration Configuration +The live environment is a normal instance of the operating system and can be +configured by adding additional files or overwriting existing files. +Section 5 of the manual documents the system and software configuration files. +Additional files can also be added for their own sake. +.Pp +To do so, create a directory that will contain this additional live environment +configuration (liveconfig), whose contents will be extracted on top of the live +environment's root filesystem. +A compressed archive of this directory will be made in the next subsection and +needs to be registered with the bootloader configuration. +.Pp +The +.Xr tix-iso-liveconfig 8 +convenience script is useful as it offers a lot of commonly useful +customizations to the live environment and can populate an initial liveconfig +directory for you. +.Ss Additional Bootloader Configuration +The GRUB bootloader configuration of an release .iso is extensible and allows +additional configuration to hook into it by writing a +.Pa /boot/grub/hooks.cfg +configuration file as described in +.Xr release-iso-bootconfig 7 . +.Pp +To do so, create a directory that will contain this additional bootloader +configuration (bootconfig), whose contents will be added onto the release .iso. +The liveconfig (if any) is normally added to the bootconfig as a compressed +archive and the additional bootloader configuration loads it as an initrd onto +the live environment. +The bootconfig will be overlaid to the release .iso in the next subsection. +.Pp +The +.Xr tix-iso-bootconfig 8 +convenience script makes it easy to generate common additional bootloader +configuration and its documentation has examples of what it can do. +It is commonly used with the +.Fl \-liveconfig +option to generate the bootloader configuration that loads the additional files +from the liveconfig into the live environment. +.Ss Adding Files To The Release +Releases are modified by adding the bootconfig (which contains a compressed copy +of the liveconfig, if any) files to the release .iso. +.Pp +The +.Xr tix-iso-add 8 +convenience script makes it easy to add files to a release .iso while taking +care to keep the release .iso bootable after the modification. +You need +.Xr xorriso 1 +installed to use this script. +Alternatively you can add the files to the release .iso by running +.Xr xorriso 1 +yourself: +.Bd -literal +xorriso \\ + -indev "$input_file" \\ + -outdev "$output_file" \\ + -boot_image grub keep \\ + -pathspecs on \\ + -add \\ + ="$input_directory" +.Ed +.Pp +Your modified release can then be used in place of the original release. +See the +.Sx EXAMPLES +section below for inspiration on what customizations to make, as well as the +manual pages for the +.Xr tix-iso-liveconfig 8 +and +.Xr tix-iso-bootconfig 8 +convenience scripts. +.Sh EXAMPLES +This section contains examples of how one can modify a release .iso. +.Ss "No Change" +To customize a release with no customizations except for the bootloader to say +the release was modified by the current user on the current host: +.Bd -literal +tix-iso-bootconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Add Files to the Live Environment +To customize a release with additional files and directories in the live +environment: +.Bd -literal +mkdir -p liveconfig +mkdir -p liveconfig/root +echo foo > liveconfig/root/foofile +echo bar > liveconfig/root/barfile +tix-iso-bootconfig --liveconfig=liveconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Provide Random Seed +To customize a release with a random seed +.Pa ( /boot/random.seed ) +(which must be kept confidential and +not reused, see the warnings in +.Xr tix-iso-bootconfig 8 ) : +.Bd -literal +tix-iso-bootconfig --random-seed bootconfig +tix-iso-add sortix.iso bootconfig +rm bootconfig/boot/random.seed # When no longer useful. +rm sortix.iso # When no longer useful. +# And erase any media made from sortix.iso when no longer useful. +.Ed +.Ss Hostname, Keyboard Layout, and Graphics Resolution +To customize the live environment of a release with a custom hostname, custom +keyboard layout, and custom graphics resolution: +.Bd -literal +tix-iso-liveconfig \\ + --hostname=dragon \\ + --kblayout=dk \\ + --videomode=1920x1080x32 \\ + liveconfig +tix-iso-bootconfig --liveconfig=liveconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Load Only Basic Ports by Default +To customize a release to only loads basic ports by default: +.Bd -literal +mkdir -p bootconfig/grub +cat > bootconfig/grub/hooks.cfg << EOF +function hook_init { + select_ports_set_basic +} +EOF +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Default Bootloader Menu Option and Timeout +To customize a release so the default bootloader menu option is to run the +installer (bootloader menu option 1, counting from 0) and to change the +bootloader menu timeout to 2 seconds: +.Bd -literal +tix-iso-bootconfig --default=1 --timeout=2 bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Locked Down Multi-User Live Environment +To customize a release so the live environment boots to the login screen by +default with the provided database of users and groups +.Xr ( passwd 5 +and +.Xr group 5 ) , +password protect the +bootloader so only the default live environment option can be chosen by +unauthenticated users: +.Bd -literal +mkdir -p liveconfig/etc +# Each user's username is their password hashed with crypt_newhash(3). +(printf 'root:%s:0:0:root:/root:sh\\n' \\ + '$2b$10$S/fJmYIJSkRdifk61xDYn.w62y.vNu35tZkznR6xa3Ntg0hsbI8tO' && + printf 'alice:%s:1000:1000:alice:/home/alice:sh\\n' \\ + '$2b$10$4xGAf5FyCYedWoNltWvbmOOreXcI5cH/f4Jz/pkWrWxwZ7TQ/WbRC' && + printf 'bob:%s:1001:1001:bob:/home/bob:sh\\n' \\ + '$2b$10$0.IukhbHNy63te6ozVJ7Pu/EvbCcr892981XbqRQ0w16UPhmDdUqa') | +cat > liveconfig/etc/passwd +cat > liveconfig/etc/group << EOF +root::0:root +alice::1000:alice +bob::1001:bob +EOF +mkdir -p liveconfig/home +mkdir -p -m 700 liveconfig/home/alice +mkdir -p -m 700 liveconfig/home/bob +grub-mkpasswd-pbkdf2 | # enter bootloader password +tee /dev/tty | +tail -1 | +sed 's/PBKDF2 hash of your password is //' > liveconfig/etc/grubpw +tix-iso-bootconfig --liveconfig=liveconfig bootconfig +(echo 'insmod password_pbkdf2' + echo 'set superusers="root"' + echo "password_pbkdf2 root $(cat liveconfig/etc/grubpw)") | +cat >> bootconfig/boot/grub/hooks.cfg +cat > bootconfig/boot/grub/main.cfg << \EOF +menu_title="$base_menu_title" +hook_menu_pre +menuentry "Sortix $version" --unrestricted { + load_sortix -- /sbin/init --target=multi-user +} +hook_menu_post +EOF +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Add a new Port +To customize a release with a new port +.Sy foo +in the +.Sy basic +and +.Sy all +port sets and fully integrate it with the bootloader menus: +.Bd -literal +mkdir -p bootconfig/boot/grub +cat > bootconfig/boot/grub/hooks.cfg << \\EOF +port_foo=true +tix_foo=false +export port_foo +export tix_foo +function hook_ports_menu { + if $port_foo; then + menuentry "foo = true" { + port_foo=false + configfile /boot/grub/ports.cfg + } + else + menuentry "foo = false" { + port_foo=true + configfile /boot/grub/ports.cfg + } + fi +} +function hook_tix_menu { + if $tix_foo; then + menuentry "foo = true" { + tix_foo=false + configfile /boot/grub/tix.cfg + } + else + menuentry "foo = false" { + tix_foo=true + configfile /boot/grub/tix.cfg + } + fi +} +function hook_ports_set_all { + port_foo=true +} +function hook_tix_set_all { + tix_foo=true +} +function hook_ports_set_basic { + port_foo=true +} +function hook_tix_set_basic { + tix_foo=true +} +function hook_ports_set_minimal { + port_foo=false +} +function hook_tix_set_minimal { + tix_foo=false +} +function hook_ports_set_no { + port_foo=false +} +function hook_tix_set_no { + tix_foo=false +} +function hook_ports_pre { + if $tix_foo; then + echo -n "Loading /repository/foo.tix.tar.xz (3.0M) ... " + module --nounzip /repository/foo.tix.tar.xz \\ + --to /repository/foo.tix.tar.xz + echo done + fi + if $port_foo; then + echo -n "Loading /repository/foo.tix.tar.xz (3.0M) ... " + module /repository/foo.tix.tar.xz --tix + echo done + fi +} +EOF +mkdir -p bootconfig/repository +cp foo.tix.tar.xz bootconfig/repository/foo.tix.tar.xz +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Add a new Ports Set +To customize a release with your own set of ports that are loaded by +default and fully integrate it with the bootloader menus: +.Bd -literal +mkdir -p bootconfig/boot/grub +cat > bootconfig/boot/grub/hooks.cfg << \\EOF +function hook_ports_menu_sets { + menuentry "Load only recommended ports" { + select_ports_set_recommended + configfile /boot/grub/ports.cfg + } +} +function hook_tix_menu_sets { + menuentry "Load only basic binary packages" { + select_tix_set_recommended + configfile /boot/grub/tix.cfg + } +} +select_ports_set_recommended { + # The basic set can be extended by calling select_ports_set_basic here. + port_foo=false + port_bar=true +} +select_tix_set_recommended { + # The basic set can be extended by calling select_tix_set_basic here. + tix_foo=false + tix_bar=true +} +# Load the recommended set of ports by default. +hook_ports_menu_sets +EOF +tix-iso-add sortix.iso bootconfig +.Ed +.Sh SEE ALSO +.Xr xorriso 1 , +.Xr development 7 , +.Xr installation 7 , +.Xr release-iso-bootconfig 7 , +.Xr upgrade 7 , +.Xr user-guide 7 , +.Xr tix-iso-add 8 , +.Xr tix-iso-bootconfig 8 , +.Xr tix-iso-liveconfig 8 diff --git a/share/man/man7/upgrade.7 b/share/man/man7/upgrade.7 index 05b1de10..ab17698c 100644 --- a/share/man/man7/upgrade.7 +++ b/share/man/man7/upgrade.7 @@ -21,6 +21,23 @@ before that one. If the existing installation is a development snapshot, you must either upgrade to a newer development snapshot of that version, or a the final release of that version. +.Ss Release .iso Modification +Optionally, you might want to modification a release .iso to meet your custom +needs per the instructions in +.Xr release-iso-modification 7 . +.Pp +The release modification procedure lets you customize aspects such as the +default bootloader menu option and timeout, the default hostname, the default +keyboard layout, the default graphics resolution, adding files of your choice to +the live environment, and so on. +.Pp +Warning: The live environment does not come with any random entropy and entropy +gathering is not yet implemented. +To keep your system secure, it is recommended to use the release modification +procedure to add a +.Pa /boot/random.seed +file to the release .iso in order to securely seed the cryptographically secure +pseudorandom number generator. .Ss Bootloader Menu Pick the .Li upgrade existing installation diff --git a/tix/Makefile b/tix/Makefile index efb8204d..e97353e3 100644 --- a/tix/Makefile +++ b/tix/Makefile @@ -27,6 +27,14 @@ tix-rmpatch \ PROGRAMS:=\ $(BINARIES) \ tix-eradicate-libtool-la \ +tix-iso-add \ +tix-iso-bootconfig \ +tix-iso-liveconfig \ + +MANPAGES8=\ +tix-iso-add.8 \ +tix-iso-bootconfig.8 \ +tix-iso-liveconfig.8 \ all: $(PROGRAMS) @@ -40,6 +48,9 @@ $(DESTDIR)$(SBINDIR): install: all $(DESTDIR)$(SBINDIR) install $(PROGRAMS) $(DESTDIR)$(SBINDIR) + mkdir -p $(DESTDIR)$(MANDIR)/man8 + mkdir -p $(DESTDIR)$(MANDIR)/man8 + cp $(MANPAGES8) $(DESTDIR)$(MANDIR)/man8 clean: rm -f $(BINARIES) diff --git a/tix/tix-iso-add b/tix/tix-iso-add new file mode 100755 index 00000000..1fffc427 --- /dev/null +++ b/tix/tix-iso-add @@ -0,0 +1,115 @@ +#!/bin/sh +# Copyright (c) 2017 Jonas 'Sortie' Termansen. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# tix-iso-add +# Add directory to iso filesystem. + +set -e + +directory= +input= +operand=1 +output= + +dashdash= +previous_option= +for argument do + if test -n "$previous_option"; then + eval $previous_option=\$argument + previous_option= + continue + fi + + case $argument in + *=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;; + *=) parameter= ;; + *) parameter=yes ;; + esac + + case $dashdash$argument in + --) dashdash=yes ;; + -o) previous_option=output ;; + --output=*) output=$parameter ;; + --output) previous_option=output ;; + -*) echo "$0: unrecognized option $argument" >&2 + exit 1 ;; + *) + if [ $operand = 1 ]; then + input="$argument" + operand=2 + elif [ $operand = 2 ]; then + directory="$argument" + operand=3 + else + echo "$0: unexpected extra operand $argument" >&2 + exit 1 + fi + ;; + esac +done + +if test -n "$previous_option"; then + echo "$0: option '$argument' requires an argument" >&2 + exit 1 +fi + +if test -z "$input"; then + echo "$0: No input file was specified" >&2 + exit 1 +fi + +if test -z "$output"; then + output="$input" +fi + +tmpdir= +tmpdest= +cleanup() { + if [ -n "$tmpdir" ]; then rm -rf "$tmpdir"; fi + if [ -n "$tmpdest" ]; then rm -rf "$tmpdest"; fi +} +trap cleanup EXIT HUP INT QUIT TERM + +if [ -z "$directory" ]; then + tmpdir=$(mktemp -d) + directory=$tmpdir +fi + +# Use different -indev and -outdev as just xorriso -dev doesn't rewrite the .iso +# in the same manner. +if [ "$input" = "$output" ]; then + tmpdest=$(mktemp -d) + dest=$tmpdest/iso +else + dest=$output + rm -f -- "$dest" +fi + +xorriso \ + -indev "$input" \ + -outdev "$dest" \ + -boot_image grub keep \ + -pathspecs on \ + -add \ + ="$directory" + +# xorriso doesn't write out the destination file if the directory is empty. +if [ ! -e "$dest" ]; then + cp -- "$input" "$dest" +fi + +if [ "$dest" != "$output" ]; then + cp -- "$dest" "$output" +fi diff --git a/tix/tix-iso-add.8 b/tix/tix-iso-add.8 new file mode 100644 index 00000000..af439512 --- /dev/null +++ b/tix/tix-iso-add.8 @@ -0,0 +1,79 @@ +.Dd February 4, 2018 +.Dt TIX-ISO-ADD 8 +.Os +.Sh NAME +.Nm tix-iso-add +.Nd add directory to .iso filesystem +.Sh SYNOPSIS +.Nm +.Op Fl o Ar output-file +.Ar input-file +.Ar input-directory +.Sh DESCRIPTION +.Nm +adds the contents of the +.Ar input-directory +directory to the .iso filesystem at +.Ar input-file , +while keeping the .iso bootable after the modification. +.Pp +.Xr xorriso 1 +must be installed in order to use this script. +.Pp +This script is designed to be convenient when modifying a Sortix release .iso as +part of the +.Xr release-iso-modification 7 +procedure. +The user is free to take all its actions themselves if it doesn't meet their +needs. +.Pp +The options are as follows: +.Bl -tag -width "12345678" +.It Fl o Ar output-file , Fl \-output Ar output-file +Write the modified +.Ar input-file +to +.Ar output-file +instead of modifying +.Ar input-file +in place. +This path must not be the same as the +.Ar input-file . +.El +.Pp +This script works by invoking the +.Xr xorriso 1 +program and essentially boils down to: +.Bd -literal +xorriso \\ + -indev "$input_file" \\ + -outdev "$output_file" \\ + -boot_image grub keep \\ + -pathspecs on \\ + -add \\ + ="$input_directory" +.Ed +.Sh EXIT STATUS +.Nm +will exit 0 on success and non-zero otherwise. +On error, the input file is left alone. +.Sh EXAMPLES +To add some files and directories to an .iso filesystem, one can run: +.Bd -literal +mkdir directory +mkdir directory/foo +mkdir directory/foo/bar +echo qux > directory/foo/bar/qux +echo spam > directory/foo/bar/spam +tix-iso-add sortix.iso directory +.Ed +.Pp +To save the modified iso elsewhere, one can run: +.Bd -literal +tix-iso-add -o sortix-modified.iso sortix.iso directory +.Ed +.Sh SEE ALSO +.Xr xorriso 1 , +.Xr release-iso-modification 7 , +.Xr tix-iso-bootconfig 8 , +.Xr tix-iso-liveconfig 8 diff --git a/tix/tix-iso-bootconfig b/tix/tix-iso-bootconfig new file mode 100755 index 00000000..dce0b1b7 --- /dev/null +++ b/tix/tix-iso-bootconfig @@ -0,0 +1,136 @@ +#!/bin/sh +# Copyright (c) 2017, 2018 Jonas 'Sortie' Termansen. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# tix-iso-bootconfig +# Generate hooks that configure the bootloader of releases iso images. + +set -e + +append_title="modified by $(id -un)@$(hostname)" +default= +directory= +enable_append_title=true +liveconfig= +operand=1 +random_seed=false +timeout= + +dashdash= +previous_option= +for argument do + if test -n "$previous_option"; then + eval $previous_option=\$argument + previous_option= + continue + fi + + case $argument in + *=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;; + *=) parameter= ;; + *) parameter=yes ;; + esac + + case $dashdash$argument in + --) dashdash=yes ;; + --append-title=*) append_title=$parameter ;; + --append-title) previous_option=append_title ;; + --default=*) default=$parameter ;; + --default) previous_option=default ;; + --disable-append-title) enable_append_title=false ;; + --enable-append-title) enable_append_title=true ;; + --liveconfig=*) liveconfig=$parameter ;; + --liveconfig) previous_option=liveconfig ;; + --random-seed) random_seed=true ;; + --timeout=*) timeout=$parameter ;; + --timeout) previous_option=timeout ;; + -*) echo "$0: unrecognized option $argument" >&2 + exit 1 ;; + *) + if [ $operand = 1 ]; then + directory="$argument" + operand=2 + else + echo "$0: unexpected extra operand $argument" >&2 + exit 1 + fi + ;; + esac +done + +if test -n "$previous_option"; then + echo "$0: option '$argument' requires an argument" >&2 + exit 1 +fi + +if test -z "$directory"; then + echo "$0: No directory was specified" >&2 + exit 1 +fi + +human_size() { + (export LC_ALL=C; du -bh -- "$1" 2>/dev/null || du -h -- "$1") | + sed -E 's/^([^[:space:]]+).*/\1/' +} + +print_enable_default() { + if [ "$1" = true ]; then + printf " enable_%s=--enable-%s\n" "$2" "$3" + elif [ "$1" = false ]; then + printf " enable_%s=--disable-%s\n" "$2" "$3" + fi +} + +if $random_seed; then + mkdir -p -- "$directory/boot" + if which dd >/dev/null 2>/dev/null; then + dd if=/dev/urandom of="$directory/boot/random.seed" bs=256 count=1 2>/dev/null + elif which rw >/dev/null 2>/dev/null; then + rw -i /dev/urandom -o "$directory/boot/random.seed" -c 256 -t + else + echo "$0: Neither dd(1) nor rw(1) are installed" >&2 + exit 1 + fi +fi + +if [ -n "$liveconfig" ]; then + mkdir -p -- "$directory/boot" + (cd "$liveconfig" && tar -c -f- -- *) > "$directory/boot/liveconfig.tar" + rm -f -- "$directory/boot/liveconfig.tar.xz" + xz -- "$directory/boot/liveconfig.tar" +fi + +mkdir -p -- "$directory/boot/grub" +(if [ -e "$directory/boot/liveconfig.tar.xz" ]; then + printf 'insmod xzio\n' + fi + if [ -n "$default" ]; then + printf 'default="%s"\n' "$default" + fi + if [ -n "$timeout" ]; then + printf 'timeout="%s"\n' "$timeout" + fi + if $enable_append_title; then + printf "base_menu_title=\"\$base_menu_title - \"'%s'\n" \ + "$(printf '%s\n' "$append_title" | sed "s/'/'\\\\''/g")" + fi + if [ -e "$directory/boot/liveconfig.tar.xz" ]; then + printf 'function hook_initrd_post {\n' + printf ' echo -n "Loading /boot/liveconfig.tar.xz (%s) ... "\n' \ + "$(human_size "$directory/boot/liveconfig.tar.xz")" + printf ' module /boot/liveconfig.tar.xz\n' + printf ' echo done\n' + printf '}\n' + fi + ) > "$directory/boot/grub/hooks.cfg" diff --git a/tix/tix-iso-bootconfig.8 b/tix/tix-iso-bootconfig.8 new file mode 100644 index 00000000..2765a84d --- /dev/null +++ b/tix/tix-iso-bootconfig.8 @@ -0,0 +1,222 @@ +.Dd February 4, 2018 +.Dt TIX-ISO-BOOTCONFIG 8 +.Os +.Sh NAME +.Nm tix-iso-bootconfig +.Nd generate additional bootloader configuration for Sortix .iso releases +.Sh SYNOPSIS +.Nm +.Op Fl \-append-title Ns = Ns Ar text +.Op Fl \-default Ns = Ns Ar default-boot-menu-option +.Op Fl \-disable-append-title +.Op Fl \-enable-append-title +.Op Fl \-liveconfig Ns = Ns Ar liveconfig-directory +.Op Fl \-random-seed +.Op Fl \-timeout Ns = Ns Ar boot-menu-timeout +.Ar output-directory +.Sh DESCRIPTION +.Nm +generates additional bootloader configuration for Sortix .iso releases that can +be overlaid onto the release .iso's filesystem, for instance by using a tool +such as +.Xr tix-iso-add 8 . +.Pp +.Nm +creates the +.Ar output-directory +directory if it doesn't already exist and populates it with the requested +additional configuration. +By default, the only action it takes is to creates a skeleton +.Pa output-directory/boot/grub/hooks.cfg +that appends " - modified by +.Ar username Ns @ Ns Ar hostname Ns +" +to the +.Sy base_menu_title +variable, which changes the boot menu title to say the .iso was modified by the +current username on the local hostname. +.Pp +This script is designed to be convenient when modifying a Sortix release .iso as +part of the +.Xr release-iso-modification 7 +procedure. +Additional bootloader configuration can be provided as described in +.Xr release-iso-bootconfig 7 . +The user is free to take all its actions themselves if it doesn't meet their +needs, or to make changes to the output after running the script. +These configuration changes apply only to the live environment, not to any +installations made from inside it. +.Pp +The options are as follows: +.Bl -tag -width "12345678" +.It Fl \-append-title Ns = Ns Ar text +Append " - " followed by +.Ar text +to the bootloader menu title by appending to the +.Sy base_menu_title +GRUB variable. +If this option is not set, the default value is " - modified by +.Ar username Ns @ Ns Ar hostname Ns +", where +.Ar username +is the output of running +.Li id -un +and +.Ar hostname +is the output of running +.Li hostname . +The bootloader menu title is appended to by default, but can be disabled with +.Fl \-disable-append-title , +and re-enabled with +.Fl \-enable-append-title , +whichever comes last takes precedence. +.It Fl \-default Ns = Ns Ar default-boot-menu-option +Select bootloader menu option number +.Ar default-boot-menu-option +by default (counting from 0). +If the selected menu option itself is a submenu, +.Ar default-boot-menu-option +can be appended with a +.Sy '>' +and another selection to pick a default menu option in that submenu, and so on. +This option sets the +.Sy default +GRUB variable. +.It Fl \-disable-append-title +Don't append anything to the bootloader menu title by appending to the +.Sy base_menu_title +GRUB variable. +.It Fl \-enable-append-title +Enable appending " - " followed by the value set with +.Fl \-append-title +to the bootloader menu title by appending to the +.Sy base_menu_title +GRUB variable. +This option is on by default and can be disabled with +.Fl \-disable-append-title . +.It Fl \-liveconfig Ns = Ns Ar liveconfig-directory +Overlay the +.Ar liveconfig-directory +directory onto the live environment, allowing full customization of the +live environment. +The +.Xr tix-iso-liveconfig 8 +script is convenient for making the +.Ar liveconfig-directory +directory. +This option makes a +.Xr tar 1 +archive compressed with +.Xr xz 1 +of the +.Ar liveconfig-directory +directory and places it at +.Pa output-directory/boot/liveconfig.tar.xz . +Regardless of this option, if a +.Pa output-directory/boot/liveconfig.tar.xz +is found, the +.Sy xzio +GRUB module is loaded and an +.Sy hook_initrd_post +hook is emitted that loads +.Pa output-directory/boot/liveconfig.tar.xz +as a multiboot module. +.It Fl \-random-seed +Copy 256 bytes of randomness from +.Pa /dev/urandom +to +.Pa output-directory/boot/random.seed , +which the existing bootloader configuration will automatically detect and use +to seed the kernel's random number generation. +This option is recommended (but notice the warnings below) as the official +releases do not come with any entropy, as entropy must be secret and only known +to a single installation. +.Pp +Warning: The information in the generated +.Pa output-directory/boot/random.seed +file must be kept confidential and should be securely erased whereever it goes +whenever it is no longer useful in a particular place, otherwise the random +number generation of the system using this entropy might be vulnerable. +This random seed must not be recycled to boot more than a single system once. +Additional systems and boots should be done with different entropy by modifiying +the release again. +An installation live environment booted with such a random seed will use it to +randomly generate secure initial random seeds for each installation made, and +each such installation will take care not to reuse the random seed across boots. +Once the +.Ar output-directory +is no longer useful, the +.Pa output-directory/boot/random.seed +path inside it should be securely erased. +If a release .iso has been made from +.Ar output-directory , +it should be securely erased when no longer useful. +If a release .iso has been burned to a physical media, it should be securely +erased when no longer useful. +.It Fl \-timeout Ns = Ns Ar boot-menu-timeout +Pick the default bootloader menu option after +.Ar boot-menu-timeout +seconds. +If +.Ar boot-menu-timeout +is 0, pick the default menu option immediately. +If +.Ar boot-menu-timeout +is -1, the timeout is disabled. +This option sets the +.Sy timeout +GRUB variable. +.El +.Sh EXIT STATUS +.Nm +will exit 0 on success and non-zero otherwise. +.Sh EXAMPLES +This section contains examples of how one can modify a release .iso. +.Ss "No Change" +To customize a release with no customizations except for the bootloader to say +the release was modified by the current user on the current host: +.Bd -literal +tix-iso-bootconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Provide Random Seed +To customize a release with a random seed (which must be kept confidential and +not reused, see the above warnings): +.Bd -literal +tix-iso-bootconfig --random-seed bootconfig +tix-iso-add sortix.iso bootconfig +rm bootconfig/boot/random.seed # When no longer useful. +rm sortix.iso # When no longer useful. +# And erase any media made from sortix.iso when no longer useful. +.Ed +.Ss Add Files to the Live Environment +To customize a release with additional configuration for the live environment +(a directory that is overlaid onto the live environment) made either manually +or with +.Xr tix-iso-liveconfig 8 : +.Bd -literal +tix-iso-bootconfig --liveconfig=liveconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Default Bootloader Menu Option and Timeout +To customize a release so the default bootloader menu option is to run the +installer (bootloader menu option 1, counting from 0) and to change the +bootloader menu timeout to 2 seconds: +.Bd -literal +tix-iso-bootconfig --default=1 --timeout=2 bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Ss Add to Bootloader Menu Title +To customize a release so the bootloader menu title is appended with a message +of your choice: +.Bd -literal +tix-iso-bootconfig --append-title="Initech Company Edition" bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Sh SEE ALSO +.Xr xorriso 1 , +.Xr kernel 7 , +.Xr release-iso-bootconfig 7 , +.Xr release-iso-modification 7 , +.Xr tix-iso-add 8 , +.Xr tix-iso-liveconfig 8 diff --git a/tix/tix-iso-liveconfig b/tix/tix-iso-liveconfig new file mode 100755 index 00000000..fe902cf7 --- /dev/null +++ b/tix/tix-iso-liveconfig @@ -0,0 +1,89 @@ +#!/bin/sh +# Copyright (c) 2017 Jonas 'Sortie' Termansen. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# tix-iso-liveconfig +# Generate configuration files for customizing the live environment. + +set -e + +directory= +hostname= +kblayout= +operand=1 +videomode= + +dashdash= +previous_option= +for argument do + if test -n "$previous_option"; then + eval $previous_option=\$argument + previous_option= + continue + fi + + case $argument in + *=?*) parameter=$(expr "X$argument" : '[^=]*=\(.*\)' || true) ;; + *=) parameter= ;; + *) parameter=yes ;; + esac + + case $dashdash$argument in + --) dashdash=yes ;; + --hostname=*) hostname=$parameter ;; + --hostname) previous_option=hostname ;; + --kblayout=*) kblayout=$parameter ;; + --kblayout) previous_option=kblayout ;; + --videomode=*) videomode=$parameter ;; + --videomode) previous_option=videomode ;; + -*) echo "$0: unrecognized option $argument" >&2 + exit 1 ;; + *) + if [ $operand = 1 ]; then + directory="$argument" + operand=2 + else + echo "$0: unexpected extra operand $argument" >&2 + exit 1 + fi + ;; + esac +done + +if test -n "$previous_option"; then + echo "$0: option '$argument' requires an argument" >&2 + exit 1 +fi + +if test -z "$directory"; then + echo "$0: No directory was specified" >&2 + exit 1 +fi + +mkdir -p "$directory" + +if [ -n "$hostname" ]; then + mkdir -p -- "$directory/etc" + printf "%s\n" "$hostname" > "$directory/etc/hostname" +else + hostname=sortix +fi + +if [ -n "$kblayout" ]; then + printf "%s\n" "$kblayout" > "$directory/etc/kblayout" +fi + +if [ -n "$videomode" ]; then + printf "%s\n" "$videomode" > "$directory/etc/videomode" +fi diff --git a/tix/tix-iso-liveconfig.8 b/tix/tix-iso-liveconfig.8 new file mode 100644 index 00000000..3f233dfe --- /dev/null +++ b/tix/tix-iso-liveconfig.8 @@ -0,0 +1,92 @@ +.Dd February 4, 2018 +.Dt TIX-ISO-LIVECONFIG 8 +.Os +.Sh NAME +.Nm tix-iso-liveconfig +.Nd generate additional live environment configuration for Sortix .iso releases +.Sh SYNOPSIS +.Nm +.Op Fl \-hostname Ns = Ns Ar hostname +.Op Fl \-kblayout Ns = Ns Ar kblayout +.Op Fl \-videomode Ns = Ns Ar videomode +.Ar output-directory +.Sh DESCRIPTION +.Nm +generates additional live environment configuration for Sortix .iso releases +that can be overlaid onto the live environment filesystem by making an archive +of it and loading it as an initrd in the .iso bootloader configuration. +An release .iso can be modified to contain this additional live environment +configuration by using +.Xr tix-iso-bootconfig 8 +to add an initrd of it in the additional bootloader configuration, and then +using +.Xr tix-iso-add 8 +to add the additional bootloader configuration to the release .iso. +.Pp +.Nm +creates the +.Ar output-directory +directory if it doesn't already exist and populates it with the requested +additional configuration for the live environment. +By default, it doesn't make any directories or files inside the +.Ar output-directory +directory. +.Pp +This script is designed to be convenient when modifying a Sortix release .iso as +part of the +.Xr release-iso-modification 7 +procedure. +The user is free to take all its actions themselves if it doesn't meet their +needs, or to make changes to the output after running the script. +These configuration changes apply only to the live environment, not to any +installations made from inside it. +.Pp +The options are as follows: +.Bl -tag -width "12345678" +.It Fl \-hostname Ns = Ns Ar hostname +Set the live environment's hostname by writing +.Ar hostname +to +.Pa output-directory/etc/hostname . +(See +.Xr hostname 5 ) +.It Fl \-kblayout Ns = Ns Ar kblayout +Set the live environment's keyboard layout by writing +.Ar kblayout +to +.Pa output-directory/etc/kblayout . +(See +.Xr kblayout 5 ) +.It Fl \-videomode Ns = Ns Ar videomode +Set the live environment's graphics resolution by writing +.Ar videomode +to +.Pa output-directory/etc/videomode . +(See +.Xr videomode 5 ) +.El +.Sh EXIT STATUS +.Nm +will exit 0 on success and non-zero otherwise. +.Sh EXAMPLES +This section contains examples of how one can modify a release .iso. +.Ss Hostname, Keyboard Layout, and Graphics Resolution +To customize the live environment of a release with a custom hostname, custom +keyboard layout, and custom graphics resolution: +.Bd -literal +tix-iso-liveconfig \\ + --hostname=dragon \\ + --kblayout=dk \\ + --videomode=1920x1080x32 \\ + liveconfig +tix-iso-bootconfig --liveconfig=liveconfig bootconfig +tix-iso-add sortix.iso bootconfig +.Ed +.Sh SEE ALSO +.Xr xorriso 1 , +.Xr hostname 5 , +.Xr kblayout 5 , +.Xr videomode 5 , +.Xr release-iso-modification 7 , +.Xr tix-iso-add 8 , +.Xr tix-iso-bootconfig 8