21-assist-in-env-setup #23
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
archzbm_settings.env
|
38
README.md
38
README.md
@ -99,7 +99,9 @@ The script will create a single ZFS zpool `zpool` on the zpool partition with da
|
||||
|
||||
## Options
|
||||
|
||||
The following options can be given either by exporting them as shell variables prior to script execution or in a file named `archzbm_settings.env` that lives in your current working directory where you're about to execute the script. File format is identical to shell variable assignments of the form `VAR=value` or `VAR='value'`.
|
||||
The following options can be given either by exporting them as shell variables prior to script execution or in a file named `archzbm_settings.env` that lives in your current working directory where you're about to execute the script. You can walk yourself through an interactive questionnaire that helps create a valid `archzbm_settings.env` file. Check out [Command line setup help](#command-line-setup-help) for details on the questionnaire.
|
||||
|
||||
If you instead want to define settings yourself with an `archzbm_settings.env` file its file format is identical to shell variable assignments of the form `VAR=value` or `VAR='value'`.
|
||||
|
||||
If `./archzbm_settings.env` exists the script will `source` its content and `export` all variables for use in future steps.
|
||||
|
||||
@ -149,6 +151,8 @@ By default the script configures plain ZFSBootMenu without networking nor an SSH
|
||||
|
||||
#### IP address
|
||||
|
||||
> IPv6 addresses are untested. Script has been confirmed working with IPv4 addresses.
|
||||
|
||||
```
|
||||
ARCHZBM_NET_CLIENT_IP=''
|
||||
ARCHZBM_NET_SERVER_IP=''
|
||||
@ -203,6 +207,18 @@ ARCHZBM_NET_DEVICE='eth0'
|
||||
ARCHZBM_NET_AUTOCONF='dhcp'
|
||||
```
|
||||
|
||||
> In ZFSBootMenu the device names that go into `ARCHZBM_NET_DEVICE` are raw unchanged kernel device names such as `eth0`. If you're unsure which device name to use in your Arch Linux live CD ISO image check `dmesg` output. During boot typically a kernel module will first assign the raw kernel device name then later `systemd` will enforce [Predictable Network Interface Names](https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/).
|
||||
>
|
||||
> In `dmesg | grep` on a physical PC with an MSI B550-A Pro mainboard from 2020 that comes with one onboard Realtek RTL8111H network adapter governed by the Realtek RTL-8169 Gigabit Ethernet driver from the `r8169` kernel module you will for example see:
|
||||
> ```
|
||||
> # dmesg -T | grep eth
|
||||
> [time] r8169 0000:2a:00.0 eth0: RTL8168h/8111h, 04:7c:16:00:01:02, XID 541, IRQ 95
|
||||
> [time] r8169 0000:2a:00.0 eth0: jumbo features [frames: 9194 bytes, tx checksumming: ko]
|
||||
> [time] r8169 0000:2a:00.0 enp42s0: renamed from eth0
|
||||
> ```
|
||||
>
|
||||
> Notice how a Predictable Network Interface Name comes in on line 3. What *__you__* need here is the `eth0` part.
|
||||
|
||||
#### SSH
|
||||
|
||||
If you want networking indicated by the fact that at least one of the `ARCHZBM_NET_*` variables is set or one of the `ARCHZBM_SSH_*` vars we assume that you want an SSH daemon as well. This comes in the form of a `dropbear` daemon with minimal configurability. Use the following variables to define Dropbear's behavior.
|
||||
@ -223,6 +239,24 @@ ssh-rsa Eahajei8,,ssh-ed25519 kaeD0mas ...
|
||||
|
||||
This syntax crutch allows you to use the full range of Dropbear-supported `authorized_keys` stanzas, see [man 8 dropbear](https://man.archlinux.org/man/extra/dropbear/dropbear.8.en) for what's available. Whether or not this is useful to you is another topic :) At least the functionality for stanzas is there by separating values in `ARCHZBM_SSH_AUTH_KEYS` with double-commas.
|
||||
|
||||
## Command line setup help
|
||||
|
||||
An interactive questionnaire can guide you through settings and goes like this:
|
||||
|
||||

|
||||
|
||||
To do the questionnaire yourself start this script with the `setup` argument:
|
||||
|
||||
```
|
||||
export SCRIPT_URL='https://quico.space/quico-os-setup/arch-zbm/raw/branch/main/setup.sh' && curl -s "${SCRIPT_URL}" | bash -s -- setup
|
||||
```
|
||||
|
||||
When done rerun it without that argument:
|
||||
|
||||
```
|
||||
export SCRIPT_URL='https://quico.space/quico-os-setup/arch-zbm/raw/branch/main/setup.sh' && curl -s "${SCRIPT_URL}" | bash
|
||||
```
|
||||
|
||||
# Steps
|
||||
|
||||
The script takes the following installation steps.
|
||||
@ -286,7 +320,7 @@ After installation you're going to want to at least touch these points in your n
|
||||
- Unless you had a settings file or exported shell env vars per [Passwords](#passwords) you're going to want to change passwords now:
|
||||
- ZFS: The password for all datasets underneath `zpool` is `password`.
|
||||
- Local `root` account: The local `root` account's password is `password`.
|
||||
- Arch User Repository (AUR) helper: We installed [paru](https://github.com/Morganamilo/paru) as our AUR helper, we installed from GitHub via `makepkg -si` then replaced it with its [paru-bin](https://aur.archlinux.org/packages/paru-bin) version from AUR.
|
||||
- Arch User Repository (AUR) helper: We installed [paru](https://github.com/Morganamilo/paru) as our AUR helper, we installed from AUR as [paru-bin](https://aur.archlinux.org/packages/paru-bin).
|
||||
- In `/etc/systemd/network/50-wired.network` instead of a DHCP-based network config you can get a static one. The DHCP-based one for reference looks like:
|
||||
```
|
||||
...
|
||||
|
285
setup.sh
285
setup.sh
@ -19,9 +19,10 @@ exec 3>&1
|
||||
declare this_script_url
|
||||
this_script_url="${SCRIPT_URL:?}"
|
||||
|
||||
declare zpool_name zfs_arch_dataset_name
|
||||
declare zpool_name zfs_arch_dataset_name settings_file
|
||||
zpool_name='zpool'
|
||||
zfs_arch_dataset_name='archlinux'
|
||||
settings_file='archzbm_settings.env'
|
||||
|
||||
declare -A partition_types
|
||||
partition_types[gpt_zfs]='6a85cf4d-1dd2-11b2-99a6-080020736631'
|
||||
@ -35,6 +36,230 @@ trap '[ "$?" -ne 77 ] || exit 77' ERR
|
||||
|
||||
declare zpool_drive efi_drive boot_drive part_schema
|
||||
|
||||
function setup_env_vars () {
|
||||
printf -- '%s\n' \
|
||||
'We will go over a series of questions to create an answer file with' \
|
||||
'options you want the script to use.' \
|
||||
'' \
|
||||
'Current working directory is:'\
|
||||
"$(pwd)" \
|
||||
'' \
|
||||
'After we'"'"'re done answer file will be written to current working dir:' \
|
||||
'./'"${settings_file}" \
|
||||
'' \
|
||||
'Press <Ctrl>+C to abort this process. No answer file will' \
|
||||
'be written to ./'"${settings_file}"' if you abort the script.' \
|
||||
'' \
|
||||
'When done rerun the same command you just did without '"'"'setup'"'"' argument.' \
|
||||
''
|
||||
read -u3 -n 1 -s -r -p "Press any key to begin questionnaire"
|
||||
echo
|
||||
echo '----------------------------------------'
|
||||
echo
|
||||
|
||||
echo "Do you want compressed datasets?"
|
||||
select arg_compressed in "Compressed" "Uncompressed"; do
|
||||
case "${arg_compressed}" in
|
||||
Compressed)
|
||||
break
|
||||
;;
|
||||
Uncompressed)
|
||||
ARCHZBM_ZFSPROPS_NO_COMPRESSION='true'
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
echo "Do you want encrypted datasets?"
|
||||
select arg_encrypted in "Encrypted" "Unencrypted"; do
|
||||
case "${arg_encrypted}" in
|
||||
Encrypted)
|
||||
break
|
||||
;;
|
||||
Unencrypted)
|
||||
ARCHZBM_ZFSPROPS_NO_ENCRYPTION='true'
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${arg_encrypted}" = 'Encrypted' ]]; then
|
||||
echo "Do you want a custom dataset decryption password?"
|
||||
select arg_custom_dataset_pw in "Yes" "No"; do
|
||||
case "${arg_custom_dataset_pw}" in
|
||||
Yes)
|
||||
want_custom_dataset_pw='true'
|
||||
break
|
||||
;;
|
||||
No)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${want_custom_dataset_pw}" ]]; then
|
||||
read -u3 -p 'Please type password, confirm with <Enter>: ' -s ARCHZBM_ZPOOL_PASSWORD
|
||||
echo
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Do you want a custom 'root' user password?"
|
||||
select arg_custom_root_pw in "Yes" "No"; do
|
||||
case "${arg_custom_root_pw}" in
|
||||
Yes)
|
||||
want_custom_root_pw='true'
|
||||
break
|
||||
;;
|
||||
No)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${want_custom_root_pw}" ]]; then
|
||||
read -u3 -p 'Please type password, confirm with <Enter>: ' -s ARCHZBM_ROOT_PASSWORD
|
||||
echo
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "Do you want an SSH daemon in ZFSBootMenu?"
|
||||
select arg_ssh_in_zbm in "Yes" "No"; do
|
||||
case "${arg_ssh_in_zbm}" in
|
||||
Yes)
|
||||
want_ssh_in_zbm='true'
|
||||
break
|
||||
;;
|
||||
No)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${want_ssh_in_zbm}" ]]; then
|
||||
echo "How do you want to assign an IP address in ZFSBootMenu?"
|
||||
select arg_ip_autoconf_method in "Statically" "Dynamically, DHCP" "Dynamically, BOOTP" "Dynamically, RARP"; do
|
||||
case "${arg_ip_autoconf_method}" in
|
||||
'Statically')
|
||||
ARCHZBM_NET_AUTOCONF='none'
|
||||
break
|
||||
;;
|
||||
'Dynamically, DHCP')
|
||||
ARCHZBM_NET_AUTOCONF='dhcp'
|
||||
break
|
||||
;;
|
||||
'Dynamically, BOOTP')
|
||||
ARCHZBM_NET_AUTOCONF='bootp'
|
||||
break
|
||||
;;
|
||||
'Dynamically, RARP')
|
||||
ARCHZBM_NET_AUTOCONF='rarp'
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
read -u3 -p 'Which device to configure (eth0 is a good guess): ' ARCHZBM_NET_DEVICE
|
||||
echo
|
||||
|
||||
if [[ "${arg_ip_autoconf_method}" = 'Statically' ]]; then
|
||||
read -u3 -p 'Interface IP address: ' ARCHZBM_NET_CLIENT_IP
|
||||
echo
|
||||
|
||||
read -u3 -p 'Netmask: ' ARCHZBM_NET_NETMASK
|
||||
echo
|
||||
|
||||
read -u3 -p 'Gateway IP address: ' ARCHZBM_NET_GATEWAY_IP
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "Do you want a custom SSH listening port?"
|
||||
select arg_custom_ssh_port in "Yes (let me specify)" "No (keep port 22)"; do
|
||||
case "${arg_custom_ssh_port}" in
|
||||
'Yes (let me specify)')
|
||||
want_custom_ssh_port='true'
|
||||
break
|
||||
;;
|
||||
'No (keep port 22)')
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${want_custom_ssh_port}" ]]; then
|
||||
read -u3 -p 'Please type SSH port, confirm with <Enter>: ' ARCHZBM_SSH_PORT
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "Do you want the SSH daemon to use a custom keepalive send interval?"
|
||||
select arg_custom_ssh_keepalive_intvl in "Yes (let me specify)" "No (keep 1)"; do
|
||||
case "${arg_custom_ssh_keepalive_intvl}" in
|
||||
'Yes (let me specify)')
|
||||
want_custom_keepalive_intvl='true'
|
||||
break
|
||||
;;
|
||||
'No (keep 1)')
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done <&3 && echo
|
||||
|
||||
if [[ "${want_custom_keepalive_intvl}" ]]; then
|
||||
read -u3 -p 'Please type server keepalive send interval, confirm with <Enter>: ' ARCHZBM_SSH_KEEPALIVE_INTVL
|
||||
echo
|
||||
fi
|
||||
|
||||
read -u3 -p 'Please type SSH pub keys on one line separated by double-commas (,,) and confirm with <Enter>: ' ARCHZBM_SSH_AUTH_KEYS
|
||||
echo
|
||||
fi
|
||||
|
||||
for env_var in 'ARCHZBM_ZFSPROPS_NO_COMPRESSION' 'ARCHZBM_ZFSPROPS_NO_ENCRYPTION' 'ARCHZBM_ZPOOL_PASSWORD' 'ARCHZBM_ROOT_PASSWORD' 'ARCHZBM_NET_AUTOCONF' 'ARCHZBM_NET_DEVICE' 'ARCHZBM_NET_CLIENT_IP' 'ARCHZBM_NET_NETMASK' 'ARCHZBM_NET_GATEWAY_IP' 'ARCHZBM_SSH_PORT' 'ARCHZBM_SSH_KEEPALIVE_INTVL' 'ARCHZBM_SSH_AUTH_KEYS'; do
|
||||
if [[ "${!env_var}" ]]; then
|
||||
printf -- '%s='"'"'%s'"'"'\n' \
|
||||
"${env_var}" "${!env_var}" \
|
||||
>> "${settings_file}"
|
||||
fi
|
||||
done
|
||||
|
||||
printf -- '%s\n' \
|
||||
'Done, please rerun script now with just' \
|
||||
'... | bash' \
|
||||
'so without the '"'"'setup'"'"' argument's
|
||||
exit 77
|
||||
}
|
||||
|
||||
function arg_parse () {
|
||||
[[ "${1}" ]] && while :; do
|
||||
case "${1}" in
|
||||
-[[:alnum:]]*)
|
||||
>&3 printf -- '%s\n' \
|
||||
'Short options '"'${1}'"' detected. Only known option is' \
|
||||
'literal string '"'"'setup'"'"'. No idea what '"'${1}'"' is.' \
|
||||
'Exiting ...'
|
||||
exit 77
|
||||
;;
|
||||
--*)
|
||||
>&3 printf -- '%s\n' \
|
||||
'Long-form option '"'${1}'"' detected. Only known option is' \
|
||||
'literal string '"'"'setup'"'"'. No idea what '"'${1}'"' is.' \
|
||||
'Exiting ...'
|
||||
exit 77
|
||||
;;
|
||||
setup)
|
||||
setup_env_vars
|
||||
return
|
||||
;;
|
||||
*)
|
||||
>&3 printf -- '%s\n' \
|
||||
'Argument '"'${1}'"' detected. Only known option is literal' \
|
||||
'string '"'"'setup'"'"'. No idea what '"'${1}'"' is.' \
|
||||
'Exiting ...'
|
||||
exit 77
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function we_are_changerooted () {
|
||||
if [ "$(stat -c '%d:%i' '/')" != "$(stat -c '%d:%i' '/proc/1/root/.')" ]; then
|
||||
return 0
|
||||
@ -328,9 +553,8 @@ function export_pool () {
|
||||
|
||||
function load_settings_file () {
|
||||
#1.8
|
||||
local working_dir settings_file settings_abs
|
||||
local working_dir settings_abs
|
||||
working_dir="$(pwd)"
|
||||
settings_file='archzbm_settings.env'
|
||||
settings_abs="${working_dir}"'/'"${settings_file}"
|
||||
if [[ -r "${settings_abs}" ]]; then
|
||||
set -a
|
||||
@ -677,56 +901,17 @@ function get_aur_helper () {
|
||||
usermod --append --groups 'wheel' 'build'
|
||||
printf -- '%s\n' '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' > '/etc/sudoers.d/10-wheel-group-no-passwd-prompt'
|
||||
pushd /tmp
|
||||
git clone 'https://aur.archlinux.org/paru.git'
|
||||
chown -R 'build:' 'paru'
|
||||
pushd 'paru'
|
||||
git clone https://aur.archlinux.org/paru-bin.git
|
||||
chown -R 'build:' 'paru-bin'
|
||||
pushd 'paru-bin'
|
||||
sudo --user 'build' makepkg -si --noconfirm
|
||||
popd
|
||||
rm -rf 'paru'
|
||||
rm -rf 'paru-bin'
|
||||
popd
|
||||
}
|
||||
|
||||
function paru_install () {
|
||||
declare -a paru_install_packages
|
||||
[[ "${1}" ]] && while :; do
|
||||
case "${1}" in
|
||||
-[[:alnum:]]*)
|
||||
>&3 printf -- '%s\n' \
|
||||
'Short-form argument '"'${1}'"' not supported for function '"'${FUNCNAME[0]}()'"'. Only known accepted argument' \
|
||||
'is '"'"'--replace-conflicting'"'"' without a value given. Exiting ...'
|
||||
exit 77
|
||||
;;
|
||||
--replace-conflicting)
|
||||
pacman_force_yes='true'
|
||||
shift
|
||||
continue
|
||||
;;
|
||||
--*)
|
||||
>&3 printf -- '%s\n' \
|
||||
'Long-form argument '"'${1}'"' not supported for function '"'${FUNCNAME[0]}()'"'. Only known accepted argument' \
|
||||
'is '"'"'--replace-conflicting'"'"' without a value given. Exiting ...'
|
||||
exit 77
|
||||
;;
|
||||
'')
|
||||
# All arguments processed
|
||||
break
|
||||
;;
|
||||
*)
|
||||
paru_install_packages+=("${1}")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done || {
|
||||
>&3 printf -- '%s\n' \
|
||||
'No argument '"'${1}'"' given for function '"'${FUNCNAME[0]}'"'. Exiting ...'
|
||||
exit 77
|
||||
}
|
||||
if [[ "${pacman_force_yes}" ]]; then
|
||||
yes 'y' | sudo --user 'build' paru -S "${paru_install_packages[@]}"
|
||||
unset -v pacman_force_yes
|
||||
else
|
||||
sudo --user 'build' paru -S --noconfirm "${paru_install_packages[@]}"
|
||||
fi
|
||||
sudo --user build paru -S --noconfirm "${@}"
|
||||
}
|
||||
|
||||
function configure_syslinux () {
|
||||
@ -988,7 +1173,6 @@ function install_os_in_chroot () {
|
||||
unleash_makepkg #2.5
|
||||
add_motd_getting_started_msg #2.6
|
||||
get_aur_helper #2.7
|
||||
paru_install --replace-conflicting 'paru-bin'
|
||||
paru_install 'zfs-dkms' 'zfs-utils' 'jq'
|
||||
hwclock --systohc
|
||||
mkinitcpio -P
|
||||
@ -1137,6 +1321,9 @@ function finalize_os_setup () {
|
||||
}
|
||||
|
||||
function main () {
|
||||
if [[ "${#@}" -gt '0' ]]; then
|
||||
arg_parse "${@}"
|
||||
fi
|
||||
if we_are_changerooted; then
|
||||
install_os_in_chroot #2.2
|
||||
else
|
||||
@ -1164,4 +1351,4 @@ function main () {
|
||||
fi
|
||||
}
|
||||
|
||||
main
|
||||
main "${@}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user