Support setting more variables in profiledef.sh and rework the way overrides are applied
- Apply overrides before validating the options. - Parse all paths with realpath. Fixes https://gitlab.archlinux.org/archlinux/archiso/-/issues/84 .
This commit is contained in:
parent
e7306a309c
commit
0f20a11bb7
@ -9,34 +9,28 @@ umask 0022
|
|||||||
export LANG="C"
|
export LANG="C"
|
||||||
export SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-"$(date +%s)"}"
|
export SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-"$(date +%s)"}"
|
||||||
|
|
||||||
# mkarchiso defaults
|
# Set application name from the script's file name
|
||||||
app_name="${0##*/}"
|
app_name="${0##*/}"
|
||||||
pkg_list=()
|
|
||||||
quiet="y"
|
|
||||||
work_dir="work"
|
|
||||||
out_dir="out"
|
|
||||||
img_name="${app_name}.iso"
|
|
||||||
gpg_key=""
|
|
||||||
override_gpg_key=""
|
|
||||||
|
|
||||||
# profile defaults
|
# Define global variables. All of them will be overwritten later
|
||||||
profile=""
|
pkg_list=()
|
||||||
iso_name="${app_name}"
|
quiet=""
|
||||||
iso_label="${app_name^^}"
|
work_dir=""
|
||||||
override_iso_label=""
|
out_dir=""
|
||||||
iso_publisher="${app_name}"
|
img_name=""
|
||||||
override_iso_publisher=""
|
gpg_key=""
|
||||||
iso_application="${app_name} iso"
|
iso_name=""
|
||||||
override_iso_application=""
|
iso_label=""
|
||||||
|
iso_publisher=""
|
||||||
|
iso_application=""
|
||||||
iso_version=""
|
iso_version=""
|
||||||
install_dir="${app_name}"
|
install_dir=""
|
||||||
override_install_dir=""
|
arch=""
|
||||||
arch="$(uname -m)"
|
pacman_conf=""
|
||||||
pacman_conf="/etc/pacman.conf"
|
packages=""
|
||||||
override_pacman_conf=""
|
|
||||||
bootmodes=()
|
bootmodes=()
|
||||||
airootfs_image_type="squashfs"
|
airootfs_image_type=""
|
||||||
airootfs_image_tool_options=('-comp' 'xz')
|
airootfs_image_tool_options=()
|
||||||
declare -A file_permissions=()
|
declare -A file_permissions=()
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +97,8 @@ usage: ${app_name} [options] <profile_dir>
|
|||||||
-h This message
|
-h This message
|
||||||
-o <out_dir> Set the output directory
|
-o <out_dir> Set the output directory
|
||||||
Default: '${out_dir}'
|
Default: '${out_dir}'
|
||||||
-p PACKAGE(S) Package(s) to install, can be used multiple times
|
-p PACKAGE(S) Package(s) to install.
|
||||||
|
Multiple packages are provided as quoted, space delimited list.
|
||||||
-v Enable verbose output
|
-v Enable verbose output
|
||||||
-w <work_dir> Set the working directory
|
-w <work_dir> Set the working directory
|
||||||
Default: '${work_dir}'
|
Default: '${work_dir}'
|
||||||
@ -160,6 +155,11 @@ _cleanup_airootfs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_run_mksquashfs() {
|
_run_mksquashfs() {
|
||||||
|
# Set default mksquashfs options
|
||||||
|
if (( ${#airootfs_image_tool_options[@]} < 1 )); then
|
||||||
|
airootfs_image_tool_options=('-comp' 'xz')
|
||||||
|
fi
|
||||||
|
|
||||||
local image_path="${isofs_dir}/${install_dir}/${arch}/airootfs.sfs"
|
local image_path="${isofs_dir}/${install_dir}/${arch}/airootfs.sfs"
|
||||||
if [[ "${quiet}" == "y" ]]; then
|
if [[ "${quiet}" == "y" ]]; then
|
||||||
mksquashfs "$@" "${image_path}" -noappend "${airootfs_image_tool_options[@]}" -no-progress > /dev/null
|
mksquashfs "$@" "${image_path}" -noappend "${airootfs_image_tool_options[@]}" -no-progress > /dev/null
|
||||||
@ -266,7 +266,7 @@ _make_custom_airootfs() {
|
|||||||
for filename in "${!file_permissions[@]}"; do
|
for filename in "${!file_permissions[@]}"; do
|
||||||
IFS=':' read -ra permissions <<< "${file_permissions["${filename}"]}"
|
IFS=':' read -ra permissions <<< "${file_permissions["${filename}"]}"
|
||||||
# Prevent file path traversal outside of $airootfs_dir
|
# Prevent file path traversal outside of $airootfs_dir
|
||||||
if [[ "$(realpath -q -- "${airootfs_dir}${filename}")" != "$(realpath -q -- "${airootfs_dir}")"* ]]; then
|
if [[ "$(realpath -q -- "${airootfs_dir}${filename}")" != "${airootfs_dir}"* ]]; then
|
||||||
_msg_error "Failed to set permissions on '${airootfs_dir}${filename}'. Outside of valid path." 1
|
_msg_error "Failed to set permissions on '${airootfs_dir}${filename}'. Outside of valid path." 1
|
||||||
# Warn if the file does not exist
|
# Warn if the file does not exist
|
||||||
elif [[ ! -e "${airootfs_dir}${filename}" ]]; then
|
elif [[ ! -e "${airootfs_dir}${filename}" ]]; then
|
||||||
@ -749,10 +749,6 @@ _build_iso() {
|
|||||||
|
|
||||||
# Read profile's values from profiledef.sh
|
# Read profile's values from profiledef.sh
|
||||||
_read_profile() {
|
_read_profile() {
|
||||||
local validation_error=0
|
|
||||||
local bootmode
|
|
||||||
|
|
||||||
_msg_info "Reading profile..."
|
|
||||||
if [[ -z "${profile}" ]]; then
|
if [[ -z "${profile}" ]]; then
|
||||||
_msg_error "No profile specified!" 1
|
_msg_error "No profile specified!" 1
|
||||||
fi
|
fi
|
||||||
@ -767,24 +763,34 @@ _read_profile() {
|
|||||||
# shellcheck source=configs/releng/profiledef.sh
|
# shellcheck source=configs/releng/profiledef.sh
|
||||||
. "${profile}/profiledef.sh"
|
. "${profile}/profiledef.sh"
|
||||||
|
|
||||||
# Resolve paths
|
# Resolve paths of files that are expected to reside in the profile's directory
|
||||||
packages="$(realpath -- "${profile}/packages.${arch}")"
|
[[ -n "$packages" ]] || packages="${profile}/packages.${arch}"
|
||||||
|
packages="$(realpath -- "${packages}")"
|
||||||
pacman_conf="$(realpath -- "${pacman_conf}")"
|
pacman_conf="$(realpath -- "${pacman_conf}")"
|
||||||
|
|
||||||
cd -- "${OLDPWD}"
|
cd -- "${OLDPWD}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# Validate profile
|
# Validate set options
|
||||||
|
_validate_options() {
|
||||||
|
local validation_error=0 bootmode
|
||||||
|
local pkg_list_from_file=()
|
||||||
|
_msg_info "Validating options..."
|
||||||
# Check if the package list file exists and read packages from it
|
# Check if the package list file exists and read packages from it
|
||||||
if [[ -e "${packages}" ]]; then
|
if [[ -e "${packages}" ]]; then
|
||||||
mapfile -t pkg_list < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
|
mapfile -t pkg_list_from_file < <(sed '/^[[:blank:]]*#.*/d;s/#.*//;/^[[:blank:]]*$/d' "${packages}")
|
||||||
if (( ${#pkg_list} < 1 )); then
|
pkg_list+=("${pkg_list_from_file[@]}")
|
||||||
|
if (( ${#pkg_list_from_file} < 1 )); then
|
||||||
(( validation_error=validation_error+1 ))
|
(( validation_error=validation_error+1 ))
|
||||||
_msg_error "No package specified in '${packages}'." 0
|
_msg_error "No package specified in '${packages}'." 0
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
(( validation_error=validation_error+1 ))
|
(( validation_error=validation_error+1 ))
|
||||||
_msg_error "File '${packages}' does not exist." 0
|
_msg_error "File '${packages}' does not exist." 0
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if pacman configuration file exists
|
# Check if pacman configuration file exists
|
||||||
if [[ ! -e "${pacman_conf}" ]]; then
|
if [[ ! -e "${pacman_conf}" ]]; then
|
||||||
(( validation_error=validation_error+1 ))
|
(( validation_error=validation_error+1 ))
|
||||||
@ -817,21 +823,63 @@ _read_profile() {
|
|||||||
if (( validation_error )); then
|
if (( validation_error )); then
|
||||||
_msg_error "${validation_error} errors were encountered while validating the profile. Aborting." 1
|
_msg_error "${validation_error} errors were encountered while validating the profile. Aborting." 1
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
_msg_info "Done!"
|
_msg_info "Done!"
|
||||||
}
|
}
|
||||||
|
|
||||||
# set overrides from mkarchiso option parameters, if present
|
# Set defaults and, if present, overrides from mkarchiso command line option parameters
|
||||||
_set_overrides() {
|
_set_overrides() {
|
||||||
_msg_info "Setting overrides..."
|
# Set variables that have command line overrides
|
||||||
[[ -n "$override_iso_label" ]] && iso_label="$override_iso_label"
|
if [[ -v override_work_dir ]]; then
|
||||||
[[ -n "$override_iso_publisher" ]] && iso_publisher="$override_iso_publisher"
|
work_dir="$override_work_dir"
|
||||||
[[ -n "$override_iso_application" ]] && iso_application="$override_iso_application"
|
elif [[ -z "$work_dir" ]]; then
|
||||||
[[ -n "$override_install_dir" ]] && install_dir="$override_install_dir"
|
work_dir='./work'
|
||||||
[[ -n "$override_pacman_conf" ]] && pacman_conf="$override_pacman_conf"
|
fi
|
||||||
[[ -n "$override_gpg_key" ]] && gpg_key="$override_gpg_key"
|
work_dir="$(realpath -- "$work_dir")"
|
||||||
# NOTE: the call to _msg_info() conveniently guards this function from evaluating to false
|
if [[ -v override_out_dir ]]; then
|
||||||
_msg_info "Done!"
|
out_dir="$override_out_dir"
|
||||||
|
elif [[ -z "$out_dir" ]]; then
|
||||||
|
out_dir='./out'
|
||||||
|
fi
|
||||||
|
out_dir="$(realpath -- "$out_dir")"
|
||||||
|
if [[ -v override_pacman_conf ]]; then
|
||||||
|
pacman_conf="$override_pacman_conf"
|
||||||
|
elif [[ -z "$pacman_conf" ]]; then
|
||||||
|
pacman_conf="/etc/pacman.conf"
|
||||||
|
fi
|
||||||
|
pacman_conf="$(realpath -- "$pacman_conf")"
|
||||||
|
[[ ! -v override_pkg_list ]] || pkg_list+=("${override_pkg_list[@]}")
|
||||||
|
if [[ -v override_iso_label ]]; then
|
||||||
|
iso_label="$override_iso_label"
|
||||||
|
elif [[ -z "$iso_label" ]]; then
|
||||||
|
iso_label="${app_name^^}"
|
||||||
|
fi
|
||||||
|
if [[ -v override_iso_publisher ]]; then
|
||||||
|
iso_publisher="$override_iso_publisher"
|
||||||
|
elif [[ -z "$iso_publisher" ]]; then
|
||||||
|
iso_publisher="${app_name}"
|
||||||
|
fi
|
||||||
|
if [[ -v override_iso_application ]]; then
|
||||||
|
iso_application="$override_iso_application"
|
||||||
|
elif [[ -z "$iso_application" ]]; then
|
||||||
|
iso_application="${app_name} iso"
|
||||||
|
fi
|
||||||
|
if [[ -v override_install_dir ]]; then
|
||||||
|
install_dir="$override_install_dir"
|
||||||
|
elif [[ -z "$install_dir" ]]; then
|
||||||
|
install_dir="${app_name}"
|
||||||
|
fi
|
||||||
|
[[ ! -v override_gpg_key ]] || gpg_key="$override_gpg_key"
|
||||||
|
if [[ -v override_quiet ]]; then
|
||||||
|
quiet="$override_quiet"
|
||||||
|
elif [[ -z "$quiet" ]]; then
|
||||||
|
quiet="y"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set variables that do not have overrides
|
||||||
|
[[ -n "$arch" ]] || arch="$(uname -m)"
|
||||||
|
[[ -n "$airootfs_image_type" ]] || airootfs_image_type="squashfs"
|
||||||
|
[[ -n "$iso_name" ]] || iso_name="${app_name}"
|
||||||
|
[[ -n "$img_name" ]] || img_name="${iso_name}-${iso_version}-${arch}.iso"
|
||||||
}
|
}
|
||||||
|
|
||||||
_export_gpg_publickey() {
|
_export_gpg_publickey() {
|
||||||
@ -859,8 +907,6 @@ _build_profile() {
|
|||||||
# Set up essential directory paths
|
# Set up essential directory paths
|
||||||
airootfs_dir="${work_dir}/${arch}/airootfs"
|
airootfs_dir="${work_dir}/${arch}/airootfs"
|
||||||
isofs_dir="${work_dir}/iso"
|
isofs_dir="${work_dir}/iso"
|
||||||
# Set ISO file name
|
|
||||||
img_name="${iso_name}-${iso_version}-${arch}.iso"
|
|
||||||
# Create working directory
|
# Create working directory
|
||||||
[[ -d "${work_dir}" ]] || install -d -- "${work_dir}"
|
[[ -d "${work_dir}" ]] || install -d -- "${work_dir}"
|
||||||
# Write build date to file or if the file exists, read it from there
|
# Write build date to file or if the file exists, read it from there
|
||||||
@ -870,9 +916,9 @@ _build_profile() {
|
|||||||
printf '%s\n' "$SOURCE_DATE_EPOCH" > "${work_dir}/build_date"
|
printf '%s\n' "$SOURCE_DATE_EPOCH" > "${work_dir}/build_date"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ "${quiet}" == "n" ]] && _show_config
|
[[ "${quiet}" == "y" ]] || _show_config
|
||||||
_run_once _make_pacman_conf
|
_run_once _make_pacman_conf
|
||||||
[[ -n "${gpg_key}" ]] && _run_once _export_gpg_publickey
|
[[ -z "${gpg_key}" ]] || _run_once _export_gpg_publickey
|
||||||
_run_once _make_custom_airootfs
|
_run_once _make_custom_airootfs
|
||||||
_run_once _make_packages
|
_run_once _make_packages
|
||||||
_run_once _make_version
|
_run_once _make_version
|
||||||
@ -886,19 +932,16 @@ _build_profile() {
|
|||||||
|
|
||||||
while getopts 'p:C:L:P:A:D:w:o:g:vh?' arg; do
|
while getopts 'p:C:L:P:A:D:w:o:g:vh?' arg; do
|
||||||
case "${arg}" in
|
case "${arg}" in
|
||||||
p)
|
p) read -r -a override_pkg_list <<< "${OPTARG}" ;;
|
||||||
read -r -a opt_pkg_list <<< "${OPTARG}"
|
C) override_pacman_conf="${OPTARG}" ;;
|
||||||
pkg_list+=("${opt_pkg_list[@]}")
|
|
||||||
;;
|
|
||||||
C) override_pacman_conf="$(realpath -- "${OPTARG}")" ;;
|
|
||||||
L) override_iso_label="${OPTARG}" ;;
|
L) override_iso_label="${OPTARG}" ;;
|
||||||
P) override_iso_publisher="${OPTARG}" ;;
|
P) override_iso_publisher="${OPTARG}" ;;
|
||||||
A) override_iso_application="${OPTARG}" ;;
|
A) override_iso_application="${OPTARG}" ;;
|
||||||
D) override_install_dir="${OPTARG}" ;;
|
D) override_install_dir="${OPTARG}" ;;
|
||||||
w) work_dir="$(realpath -- "${OPTARG}")" ;;
|
w) override_work_dir="${OPTARG}" ;;
|
||||||
o) out_dir="$(realpath -- "${OPTARG}")" ;;
|
o) override_out_dir="${OPTARG}" ;;
|
||||||
g) override_gpg_key="${OPTARG}" ;;
|
g) override_gpg_key="${OPTARG}" ;;
|
||||||
v) quiet="n" ;;
|
v) override_quiet="n" ;;
|
||||||
h|?) _usage 0 ;;
|
h|?) _usage 0 ;;
|
||||||
*)
|
*)
|
||||||
_msg_error "Invalid argument '${arg}'" 0
|
_msg_error "Invalid argument '${arg}'" 0
|
||||||
@ -923,6 +966,7 @@ profile="$(realpath -- "${1}")"
|
|||||||
|
|
||||||
_read_profile
|
_read_profile
|
||||||
_set_overrides
|
_set_overrides
|
||||||
|
_validate_options
|
||||||
_build_profile
|
_build_profile
|
||||||
|
|
||||||
# vim:ts=4:sw=4:et:
|
# vim:ts=4:sw=4:et:
|
||||||
|
Loading…
Reference in New Issue
Block a user