Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
devel:microos:yuga:testing
tik
_service:obs_scm:tik-1.2.14.obscpio
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:tik-1.2.14.obscpio of Package tik
07070100000000000081A400000000000000000000000166AB4F2B00000454000000000000000000000000000000000000001300000000tik-1.2.14/LICENSEMIT License Copyright (c) 2023-2024 SUSE LLC Copyright (c) 2023-2024 Richard Brown Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 07070100000001000081A400000000000000000000000166AB4F2B0000171E000000000000000000000000000000000000001500000000tik-1.2.14/README.md# tik Transactional Installation Kit - A toolkit for deploying Operating System images to UEFI hardware from a USB stick. ## General Premise A simple, lightweight, extensible tool for deploying a premade OS images to UEFI hardware. tik was originally inspired by the "SelfInstaller" functionality offered by [kiwi](https://github.com/OSInside/kiwi) OEM images, but is designed to be wholly independent of the toolchain used to create the OS images. It's core functionality is very similar to kiwi's SelfInstaller, with the basic workflow for deploying an image being a very simple process: - Identify storage devices on the system - Offer the user a list of available devices - Deploy image to that device In addition to the above workflow, tik supports the following additional features - Unattended automation of the deployment of the image - Optional extensions to be run before or after the deployment of the image (eg to support functionality like checking the network for an updated image). This functionality is inspired by [jeos-firstboot](https://github.com/openSUSE/jeos-firstboot/)'s module support - Support for multiple images provided on the same installation media (eg. openSUSE Aeon and openSUSE MicroOS) ## tik OS Images tik is designed to deploy three types of images. - systemd-repart "bundles" - systemd-repart "self deployment" - Block images In all three cases tik should not care about the contents of the disk image, which potentially could be of any Operating System built using any toolset (eg kiwi, mkosi, etc) Features like expanding the partitions to fill the disk are expected to be handled by tools like systemd-repart on the booting of the deployed OS, not by tik (though in theory optional extensions could be written to implement this) ### systemd-repart "bundles" tik can also deploy images bundled with their own systemd-repart configurations. tik expects the following on disk layout for each systemd-repart "bundle": - a Directory with a unique name to describe the OS/Version being deployed. Contained within that directory: - a `repart.d` Directory containing a complete [repart.d](https://www.freedesktop.org/software/systemd/man/latest/repart.d.html) partition layout for the OS being deployed - 1 (or more) Directories or Block images to be used by `CopyFiles=` or `CopyBlocks=` parameters in the `repart.d` configuration to populate the contents of the defined partitions The `repart.d` configuration is then read and applied to the target storage device, being populated automatically based on the configuration. By default these files should be located in `/usr/lib/tik/img` but can be relocated by redefining the `TIK_IMG_DIR` parameter in your tik config. As `CopyBlocks=` and `CopyFiles=` parameters require absolute filesystem paths, any change to the `TIK_IMG_DIR` parameter will require altering your configuration to match that new location. This feature was introduced in tik v1.2 ### systemd-repart "self-deployment" If tik is executed without any images in the defined `TIK_IMG_DIR` it will automatically attempt "self deployment", using the currently booted tik USB stick as its 'image' for writing to the target storage device. This is primarily for using tik to deploy images from a functioning 'live/portable' USB installation. For this to work, tik requires - a `repart.d` configuration containing a complete [repart.d](https://www.freedesktop.org/software/systemd/man/latest/repart.d.html) partition layout for the OS being deployed. This must be located in the standard `repart.d` paths, eg `/etc/repart.d/` or `/usr/lib/repart.d` The `repart.d` configuration is then read and applied to the target storage device, being populated automatically based on the configuration. It is expected that the `repart.d` configuration will use `CopyBlocks=auto` to automatically map the contents from the booted tik USB stick to the equivalent new partitions on the target storage device. This feature was introduced in tik v1.2 ### Block images tik can deploy a block-based disk images. These expected to be raw.xz files containing - the full partition table - a UEFI ESP/EFI partition - 1 (or more) OS partitions By default these files should be located in `/usr/lib/tik/img` but can be relocated by redefining the `TIK_IMG_DIR` parameter in your tik config ## tik Installation Media tik is designed to be run on a different style of media than many traditional OS installers Traditional tooling like YaST, Agama, Windows Installer, etc are all expected to be read-only Installation media that aren't modifiable by the user at all tik Installtion Media are expected to be a variant of openSUSE MicroOS, designed to be run from portable media (eg a USB stick) while the "Install OS" of the Installation Media will therefore be read-only when in use, the "Install OS" will be possible of being updated and configured to the users needs, directly on the USB stick after it's imaged More importantly, this also means that the Installation Media will have various read-write locations, including /var/lib/tik/images, the location of tiks image files, allowing users to add their own custom variants of such images to be offered when the tik installer boots up ## tik + ignition + combustion because tik installation media are built separately from the Operating System(s) which tik will offer to deploy, this means that tik installation images can also contain a separate 'ignition/combustion partition' which can have your ignition/combustion configurations stored within These will then be automatically used by any OS image which uses ignition or combustion (eg openSUSE MicroOS) on their first boot after tik has deployed an image, assuming the tik Installation USB stick is still connected This makes ignition and/or combustion the perfect tools for making any automated customisations to any OS image deployed via tik 07070100000002000041ED00000000000000000000000366AB4F2B00000000000000000000000000000000000000000000000F00000000tik-1.2.14/etc07070100000003000041ED00000000000000000000000266AB4F2B00000000000000000000000000000000000000000000001300000000tik-1.2.14/etc/tik07070100000004000081A400000000000000000000000166AB4F2B00000377000000000000000000000000000000000000001A00000000tik-1.2.14/etc/tik/config# Directory for users to add custom configuration and modules # Default: "/etc/tik" #TIK_CUSTOM_DIR="/etc/tik" # Directory for OS images to be deployed # Default: "/usr/lib/tik/img" #TIK_IMG_DIR="/usr/lib/tik/img" # To show USB devices in the install device selection dialog, uncomment this variable # USB devices are filtered out by default #TIK_ALLOW_USB_INSTALL_DEVICES=1 # For unattended installations the disk device to deploy the image must be defined if more than one is present # Default: Undefined #TIK_INSTALL_DEVICE="" # For unattended installations the disk image to deploy must be defined if more than one is present # Default: Undefined #TIK_INSTALL_IMAGE="" # Display name of the OS to be deployed by tik # Default: Undefined #TIK_OS_NAME="" # URL for bug reports to go to # Default: https://aeondesktop.org/reportbug #TIK_BUG_URL="https://aeondesktop.org/reportbug"07070100000005000041ED00000000000000000000000466AB4F2B00000000000000000000000000000000000000000000000F00000000tik-1.2.14/usr07070100000006000041ED00000000000000000000000266AB4F2B00000000000000000000000000000000000000000000001300000000tik-1.2.14/usr/bin07070100000007000081ED00000000000000000000000166AB4F2B0000070D000000000000000000000000000000000000001700000000tik-1.2.14/usr/bin/tik#!/bin/bash # SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2023-2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2023-2024 Richard Brown # Define variables # Style notes # lowercase variables = internal, not expected to be defined by users # uppercase variables = user facing, expected to be set by config tik_log=~/tik.log tik_dir=/usr/lib/tik tik_module="tik" # Read libraries . ${tik_dir}/lib/tik-functions # Start logging exec 2> >(exec tee -i -a "${tik_log}" >&2) log "[START] $0" # Check for debug mode if [[ $1 == "--debug" ]]; then debug=1 fi # Read configuration files, /usr first, then /etc . ${tik_dir}/config . ${TIK_CUSTOM_DIR}/config # Check essential paths exist if [ ! -d "${TIK_IMG_DIR}" ]; then error "${TIK_IMG_DIR} does not exist" fi cleanup() { retval=$? log "[STOP][${retval}] $0" if [ "${debug}" == "1" ]; then zenity --timeout 5 --info --no-wrap --text="<b>Test Succeeded:</b>\n\nHave a nice day!" elif [ "${retval}" == "0" ]; then zenity --timeout 5 --info --no-wrap --title="Installation Complete!" --text="${TIK_OS_NAME} has been installed.\n\n<b>System is rebooting</b>" prun systemctl reboot --force else zenity --error --no-wrap --title="Installation Failed" --text="Please file a bug report at <tt>${TIK_BUG_URL}</tt>\n\nPlease include the <tt>tik.log</tt> file\nIt can be found on the IGNITION partition on this USB Stick\n\n<b>System is shutting down</b>" cp -a ${tik_log} /ignition prun systemctl poweroff --force fi } trap cleanup EXIT load_modules "pre" load_modules "pre" "custom" get_disk get_img dump_image "${TIK_INSTALL_IMAGE}" "${TIK_INSTALL_DEVICE}" reread_partitiontable load_modules "post" load_modules "post" "custom" wipe_keyfile set_boot_target07070100000008000041ED00000000000000000000000366AB4F2B00000000000000000000000000000000000000000000001300000000tik-1.2.14/usr/lib07070100000009000041ED00000000000000000000000466AB4F2B00000000000000000000000000000000000000000000001700000000tik-1.2.14/usr/lib/tik0707010000000A000081A400000000000000000000000166AB4F2B00000359000000000000000000000000000000000000001E00000000tik-1.2.14/usr/lib/tik/config# Directory for users to add custom configuration and modules # Default: "/etc/tik" TIK_CUSTOM_DIR="/etc/tik" # Directory for OS images to be deployed # Default: "/usr/lib/tik/img" TIK_IMG_DIR="/usr/lib/tik/img" # To show USB devices in the install device selection dialog, uncomment this variable # USB devices are filtered out by default #TIK_ALLOW_USB_INSTALL_DEVICES=1 # For unattended installations the disk device to deploy the image must be defined # Default: Undefined #TIK_INSTALL_DEVICE="" # For unattended installations the disk image to deploy must be defined if more than one is present # Default: Undefined #TIK_INSTALL_IMAGE="" # Display name of the OS to be deployed by tik # Default: Undefined #TIK_OS_NAME="" # URL for bug reports to go to # Default: https://aeondesktop.org/reportbug TIK_BUG_URL="https://aeondesktop.org/reportbug" 0707010000000B000041ED00000000000000000000000266AB4F2B00000000000000000000000000000000000000000000001B00000000tik-1.2.14/usr/lib/tik/lib0707010000000C000081A400000000000000000000000166AB4F2B00004512000000000000000000000000000000000000002900000000tik-1.2.14/usr/lib/tik/lib/tik-functions# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2023-2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2023-2024 Richard Brown log(){ echo "[${tik_module}][$(date +"%Y%m%d-%T")][LOG] $*" 1>&2 } warn() { echo "[${tik_module}][$(date +"%Y%m%d-%T")][WARN] $*" 1>&2 d --warning --text="$*" } error() { echo "[${tik_module}][$(date +"%Y%m%d-%T")][ERROR] $*" 1>&2 d --error --text "$*" exit 1 } d(){ while true do retval=0 result="$(zenity "$@")" || retval=$? log "[zenity][${retval}][${result}] $@" case $retval in 0) return 0 ;; 1|255) zenity --question --text="Do you really want to quit?" && exit 1 ;; esac done } # variant of privileged run (prun) function that doesn't require the pkexec call to return 0 prun-opt() { if [ "${debug}" == "1" ]; then log "[pkexec-noexec] $@" else retval=0 pkexec "$@" retval=$? log "[pkexec][${retval}] $@" fi } # Most commonly used prun function, which requires the called command to work prun() { prun-opt "$@" if [ "${retval}" != "0" ]; then error "Command <tt>$@</tt> FAILED" fi } get_persistent_device_from_unix_node() { local unix_device=$1 local schema=$2 local node local persistent_name node=$(basename "${unix_device}") for persistent_name in /dev/disk/"${schema}"/*; do if [ "$(basename "$(readlink "${persistent_name}")")" = "${node}" ];then if [[ ${persistent_name} =~ ^/dev/disk/"${schema}"/nvme-eui ]]; then # Filter out nvme-eui nodes as they are not descriptive to the user continue fi echo "${persistent_name}" return fi done warn "Could not find <tt>${schema}</tt> representation of <tt>${node}</tt>. Using original device <tt>${unix_device}</tt>" echo "${unix_device}" } probe_partitions() { local probe_dir=/var/lib/tik/probe local filesystem_type=$2 local filematch=$3 local device=$1 local mountops local part if [[ "${filesystem_type}" == "btrfs" ]]; then mountops="-o compress=zstd:1" fi prun /usr/bin/mkdir -p ${probe_dir}/mnt probedpart="" for part in $(lsblk ${device} -p -n -r -o ID-LINK,FSTYPE|tr -s ' ' ";"|grep ";${filesystem_type}"|cut -d\; -f1); do if [ -z ${filematch} ]; then log "[probe_partitions] no file match required" # Fallback to unix device in order to fix issue with USB devices probedpart="$(/usr/bin/readlink -f "/dev/disk/by-id/""${part}")" log "[probe_partitions] Partition ${probedpart} found" else # Check if ${filematch} exists # Fallback to unix device in order to fix issue with USB devices part="$(/usr/bin/readlink -f "/dev/disk/by-id/""${part}")" prun /usr/bin/mount ${mountops} ${part} "${probe_dir}/mnt" if [ -f ${probe_dir}/mnt/${filematch} ]; then log "[probe_partitions] File ${filematch} found" # Fallback to unix device in order to fix issue with USB devices probedpart="${part}" log "[probe_partitions] Partition ${probedpart} found" if grep -q 'PRETTY_NAME="openSUSE MicroOS"' ${probe_dir}/mnt/${filematch} && [ -f ${probe_dir}/mnt/usr/bin/gnome-shell ]; then # Found legacy Aeon, activate easter egg log "Legacy Aeon Install FOUND" legacy_aeon=1 fi fi prun-opt /usr/bin/umount ${probe_dir}/mnt fi done prun /usr/bin/rmdir ${probe_dir}/mnt } get_disk() { # Volume label for the tik install media must be set to "TIKINSTALL" to filter it out from the device list tik_volid="TIKINSTALL" local disk_id="by-id" local disk_size local disk_device local disk_device_by_id local disk_meta local disk_list local device_array local list_items local blk_opts="-p -n -r -o NAME,SIZE,TYPE" local message local blk_opts_plus_label="${blk_opts},LABEL" local tik_install_disk_part local part_meta local part_count local part_size local part_info local part_fs local blk_opts_part_info="${blk_opts_plus_label},FSTYPE" local usb_match_1="usb" local usb_match_2=":0" tik_install_disk_part=$( eval lsblk "${blk_opts_plus_label}" | \ tr -s ' ' ":" | \ grep ":${tik_volid}" | \ cut -f1 -d: ) for disk_meta in $( eval lsblk "${blk_opts}" | grep -E "disk|raid" | tr ' ' ":" );do disk_size=$(echo "${disk_meta}" | cut -f2 -d:) if [[ "${disk_size}" == "0B" ]]; then # ignore disks with no size, e.g. empty SD card readers continue fi disk_device="$(echo "${disk_meta}" | cut -f1 -d:)" # find partitions and info for this disk part_count=0 part_info="" for part_meta in $( eval lsblk "${blk_opts_part_info}" | grep -E "${disk_device}.+part.+" | tr ' ' ":" );do part_count=$(expr $part_count + 1) part_size=$(echo "${part_meta}" | cut -f2 -d:) part_fs=$(echo "${part_meta}" | cut -f5 -d:) if [ -n "${part_info}" ]; then part_info="${part_info}," fi if [ -n "${part_fs}" ]; then part_info="${part_info}${part_fs}(${part_size})" else part_info="${part_info}unknown(${part_size})" fi done if [[ ${part_count} -eq 0 ]]; then part_info="none" fi if [[ "${tik_install_disk_part}" == "${disk_device}"* ]]; then # ignore install source device continue fi if [[ ${disk_device} =~ ^/dev/fd ]];then # ignore floppy disk devices continue fi if [[ ${disk_device} =~ ^/dev/zram ]];then # ignore zram devices continue fi disk_device_by_id=$( get_persistent_device_from_unix_node "${disk_device}" "${disk_id}" ) if [[ ( "${TIK_ALLOW_USB_INSTALL_DEVICES}" -ne 1 ) && ( "{$disk_device_by_id}" == *"${usb_match_1}"* || "{$disk_device_by_id}" == *"${usb_match_2}"* ) ]]; then # ignore USB devices if TIK_ALLOW_USB_INSTALL_DEVICES not set in config continue fi if [ -n "${disk_device_by_id}" ];then disk_device=${disk_device_by_id} fi list_items="${list_items} $(basename ${disk_device}) ${disk_size} ${part_count} ${part_info}" disk_list="${disk_list} $(basename ${disk_device}) ${disk_size}" done if [ -n "${TIK_INSTALL_DEVICE}" ];then # install device overwritten by config. local device=${TIK_INSTALL_DEVICE} local device_meta local device_size if [ ! -e "${device}" ];then local no_dev="Given device <tt>${device}</tt> does not exist." error "${no_dev}" fi if [ ! -b "${device}" ];then local no_block_dev="Given device <tt>${device}</tt> is not a block special." error "${no_block_dev}" fi device_meta=$( eval lsblk "${blk_opts}" "${device}" |\ grep -E "disk|raid" | tr ' ' ":" ) device_size=$(echo "${device_meta}" | cut -f2 -d:) # this case is not shown in manual selection, threfore we don't need partition info list_items="$(basename ${device}) ${device_size}" disk_list="$(basename ${device}) ${device_size}" message="tik installation device set to to: ${device}" log "${message}" fi if [ -z "${list_items}" ];then local no_device_text="No device(s) for installation found." error "${no_device_text}" fi if [ -n "${disk_list}" ];then local count=0 local device_index=0 for entry in ${disk_list};do if [ $((count % 2)) -eq 0 ];then device_array[${device_index}]=${entry} device_index=$((device_index + 1)) fi count=$((count + 1)) done if [ "${device_index}" -eq 1 ];then # one single disk device found, use it # Add back full path to it TIK_INSTALL_DEVICE="/dev/disk/${disk_id}/${device_array[0]}" # Fallback to unix device in case by-id does not exist # see get_persistent_device_from_unix_node, it does fallback like this. if [ ! -e "${TIK_INSTALL_DEVICE}" ]; then TIK_INSTALL_DEVICE="/dev/${device_array[0]}" fi else # manually select from storage list d --list --column=Disk --column=Size --column=Partitions --column=Filesystems --width=1050 --height=340 --title="Select A Disk" --text="Select the disk to install the operating system to. <b>Make sure any important documents and files have been backed up.</b>\n" ${list_items} # Add back full path to it TIK_INSTALL_DEVICE="/dev/disk/${disk_id}/${result}" # Fallback to unix device in case by-id does not exist # see get_persistent_device_from_unix_node, it does fallback like this. if [ ! -e "${TIK_INSTALL_DEVICE}" ]; then TIK_INSTALL_DEVICE="/dev/${result}" fi fi fi } get_img() { local list_items local message local img_meta local img_item local img_list local img_array local file_type # Images are assumed to be named to the following standard # $ProductName.$Version.raw.xz for block devices # $ProductName.$Version.raw for systemd-repart images # Any extraneous fields may confuse tik's detection, selection and presentation of the image to the user for file_type in '*.raw.xz' '*.raw';do for img_meta in $(cd $TIK_IMG_DIR && (stat --printf="%n\t%s\n" ${file_type} | tr ' ' ":"));do img_filename="$(echo $img_meta | cut -f1 -d:)" img_size="$(echo $img_meta | cut -f2 -d:)" list_items="${list_items} ${img_filename} ${img_size}" done done if [ -n "${TIK_INSTALL_IMAGE}" ];then # install image overwritten by config. local img=${TIK_INSTALL_IMAGE} local img_meta local img_size if [ ! -e "${img}" ];then local no_img="Given image <tt>${img}</tt> does not exist." error "${no_img}" fi if [ ! -s "${img}" ];then local empty_img="Given image <tt>${img}</tt> is empty." error "${empty_img}" fi img_meta=$( eval cd $TIK_IMG_DIR && (stat --printf="%n\t%s\n" $img | tr ' ' ":") ) img_filename="$(echo $img_meta | cut -f1 -d:)" img_size="$(echo $img_meta | cut -f2 -d:)" list_items="${list_items} ${img_filename} ${img_size}" message="tik installation image set to to: ${img}" log "${message}" fi if [ -z "${list_items}" ];then TIK_INSTALL_IMAGE='TIK_SELFDEPLOY' fi img_list=${list_items} if [ -n "${img_list}" ];then local count=0 local img_index=0 for entry in ${img_list};do if [ $((count % 2)) -eq 0 ];then img_array[${img_index}]=${entry} img_index=$((img_index + 1)) fi count=$((count + 1)) done if [ "${img_index}" -eq 1 ];then # one single disk image found, use it TIK_INSTALL_IMAGE="${img_array[0]}" else # manually select from storage list d --list --column=Image --column=Size --title="Select A Image" --text="Select the operating system image to install.\n" ${list_items} TIK_INSTALL_IMAGE="$result" fi fi } reread_partitiontable() { # We've just done a lot to $TIK_INSTALL_DEVICE and it's probably a good idea to make sure the partition table is clearly read so tools like dracut dont get confused. log "[reread_partitiontable] Re-reading partition table" prun /usr/sbin/blockdev --rereadpt ${TIK_INSTALL_DEVICE} } create_keyfile() { # Even if there's no partitions using encryption, systemd-repart will need a key-file defined for the --key-file parameter. tik_keyfile=/tmp/tikkeyfile log "[create_keyfile] Creating keyfile ${tik_keyfile}" prun /usr/bin/dd bs=512 count=4 if=/dev/urandom of=${tik_keyfile} iflag=fullblock prun /usr/bin/chmod 400 ${tik_keyfile} } wipe_keyfile() { # We made a keyfile and need to clean it up at the end of the installation, possibly wiping it from the newly installed device log "[wipe_keyfile] Deleting keyfile ${tik_keyfile}" probe_partitions ${TIK_INSTALL_DEVICE} "crypto_LUKS" if [ -n "${probedpart}" ]; then # Assumes Slot 0 is always by the key-file at enrolment prun /usr/bin/systemd-cryptenroll --unlock-key-file=${tik_keyfile} --wipe-slot=0 ${probedpart} fi # We're done with the key-file, so remove it prun /usr/bin/rm ${tik_keyfile} } dump_image() { local image_source_files=$1 local image_target=$2 d --question --no-wrap --title="Begin Installation?" --text="Once the installation begins the changes to the selected disk are irreversible.\n\n<b>Proceeding will fully erase the disk.</b>\n\nContinue with installation?" case "${image_source_files}" in *.raw.xz) dump_image_dd ${image_source_files} ${image_target} ;; *.raw) dump_image_repart_image ${image_source_files} ${image_target} ;; TIK_SELFDEPLOY) dump_image_repart_self ${image_target} ;; *) error "invalid image type provided" esac } dump_image_dd() { local image_source_files=$1 local image_target=$2 log "[dump_image_dd] deploying ${TIK_IMG_DIR}/${image_source_files}" (xzcat ${TIK_IMG_DIR}/${image_source_files} | pv -f -F "# %b copied in %t %r" | prun /usr/bin/dd of=${image_target} bs=64k) 2>&1 | d --progress --title="Installing ${TIK_OS_NAME}" --pulsate --auto-close --no-cancel --width=400 prun /usr/bin/sync | d --progress --title="Syncing" --pulsate --auto-close --no-cancel --width=400 } dump_image_repart_image() { local image_source_files=$1 local image_target=$2 local success=0 local max_attempts=5 local attempt_num=1 create_keyfile log "[dump_image_repart_image] deploying ${TIK_IMG_DIR}/${image_source_files}" # systemd-repart doesn't always parse the contents of the image perfectly first time, so retry a few times before declaring it a failure while [ ${success} = 0 ] && [ ${attempt_num} -lt ${max_attempts} ]; do prun-opt systemd-repart --no-pager --pretty=0 --empty=force --dry-run=no --key-file=${tik_keyfile} --image=${TIK_IMG_DIR}/${image_source_files} --image-policy=root=unprotected ${image_target} > >(d --progress --title="Installing ${TIK_OS_NAME}" --text="Deploying OS Image" --pulsate --auto-close --no-cancel --width=400) if [ ${retval} -eq 0 ]; then success=1 else # repart couldn't find a root partition log "[dump_image_repart_image] systemd-repart attempt $attempt_num failed. Trying again..." sleep 1 # Increment the attempt counter attempt_num=$(( attempt_num + 1 )) fi done if [ ${success} = 1 ]; then log "[dump_image_repart_image] systemd-repart succeeded after $attempt_num attempts" else error "systemd-repart failed" fi } dump_image_repart_self() { local image_target=$1 create_keyfile log "[dump_image_repart_self] self-deploying" prun systemd-repart --no-pager --pretty=0 --empty=force --dry-run=no --key-file=${tik_keyfile} ${image_target} > >(d --progress --title="Installing ${TIK_OS_NAME}" --text="Deploying OS Image" --pulsate --auto-close --no-cancel --width=400) } set_boot_target() { local efipartnum if [ "${debug}" == "1" ]; then log "[debug] Not setting EFI boot target" elif [ -n "${efi_already_set}" ]; then log "[set_boot_target] boot target already set, not setting again" else # Cleanup any existing openSUSE boot entries prun-opt /usr/sbin/efibootmgr -B -L "openSUSE Boot Manager" prun /usr/sbin/efibootmgr -O log "[set_boot_target] searching for ESP partition containing /EFI/systemd/shim.efi on ${TIK_INSTALL_DEVICE}" probe_partitions ${TIK_INSTALL_DEVICE} "vfat" "/EFI/systemd/shim.efi" if [ -z "${probedpart}" ]; then error "esp partition not found" fi efipartnum=$(lsblk ${probedpart} -p -n -r -o PARTN) log "[set_boot_target] found ESP on ${probedpart}, partition number ${efipartnum}" prun /usr/sbin/efibootmgr -c -L "openSUSE Boot Manager" -d ${TIK_INSTALL_DEVICE} -l "\EFI\systemd\shim.efi" -p ${efipartnum} # Log to show the resulting eficonfig log "[set_boot_target] $(prun /usr/sbin/efibootmgr)" efi_already_set=1 fi } load_modules() { local module_dir if [[ $2 = "custom" ]]; then module_dir=$TIK_CUSTOM_DIR/modules/$1 else module_dir=$tik_dir/modules/$1 fi if [ -n "$(ls -A $module_dir)" ]; then for f in $module_dir/* do tik_module="$f" log "[START] $module_dir/$f" . $f log "[STOP] $module_dir/$f" done fi tik_module="tik" } 0707010000000D000041ED00000000000000000000000466AB4F2B00000000000000000000000000000000000000000000001F00000000tik-1.2.14/usr/lib/tik/modules0707010000000E000041ED00000000000000000000000266AB4F2B00000000000000000000000000000000000000000000002400000000tik-1.2.14/usr/lib/tik/modules/post0707010000000F000081A400000000000000000000000166AB4F2B0000320A000000000000000000000000000000000000002F00000000tik-1.2.14/usr/lib/tik/modules/post/15-encrypt# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2024 Richard Brown # Module does not actually do any encryption, but is intended to finish installation of an encrypted image, such as one deployed via systemd-repart # Module expects to find a single ESP partition (find_esp) and a single LUKS2 partition (find_crypt) on $TIK_INSTALL_DEVICE, upon which it will do the following # - Open the encrypted device, mounting var, etc, boot/efi, tmp, run, sys, dev and proc (open_partition) # - Against the mounted partition, do the following (configure_encryption) # - write /etc/kernel/cmdline # - write /etc/crypttab # - update any /etc/fstab lines regarding /boot/efi and replace them with the correct ones for the on disk vfat filesystem # - populate /boot/efi with sdbootutil install & sdbootutil mkinitrd # - populate /etc/sysconfig/fde-tools (so the measurements can be updated on first boot) # - Close the partition (close_partition) # - Generate a recovery key (generate_recoveryKey) # - Add recovery key to device and identify it as a systemd-recovery key (add_recoveryKey) # - Display the recovery key to the user (display_recoveryKey) # - Remove the temporary key-file and replace it either with TPM enrollment or a user-supplied passphrase (add_key) # It is expected the LUKS2 partition is already encrypted with a key-file in the only populated keyslot. encrypt_dir=/var/lib/tik/encrypt encrypt_pipe=/tmp/encryptpipe if [ ! -d ${encrypt_dir}/mnt ]; then prun /usr/bin/mkdir -p ${encrypt_dir}/mnt fi if [ ! -p ${encrypt_pipe} ]; then mkfifo ${encrypt_pipe} fi crypt_progress() { log "[crypt_progress] Monitoring encryption progress" (tail -f ${encrypt_pipe}) | d --progress --title="Configuring Encryption" --auto-close --no-cancel --width=400 rm ${encrypt_pipe} log "[crypt_progress] Encryption progress reached 100%" } find_crypt() { echo "# Finding encrypted partition" > ${encrypt_pipe} log "[find_crypt] finding encrypted partition" probe_partitions ${TIK_INSTALL_DEVICE} "crypto_LUKS" if [ -z "${probedpart}" ]; then error "encrypted partition not found" fi cryptpart=${probedpart} log "[find_crypt] found ${cryptpart}" echo "14" > ${encrypt_pipe} } find_esp() { echo "# Finding encrypted partition" > ${encrypt_pipe} log "[find_esp] finding ESP" probe_partitions ${TIK_INSTALL_DEVICE} "vfat" if [ -z "${probedpart}" ]; then error "esp partition not found" fi esppart=${probedpart} log "[find_esp] found ${esppart}" echo "28" > ${encrypt_pipe} } open_partition() { echo "# Opening ${cryptpart}" > ${encrypt_pipe} log "[open_partition] opening ${cryptpart} and mounting for chroot" prun /usr/sbin/cryptsetup luksOpen --key-file=${tik_keyfile} ${cryptpart} aeon_root echo "35" > ${encrypt_pipe} prun /usr/bin/mount -o compress=zstd:1 /dev/mapper/aeon_root ${encrypt_dir}/mnt for i in proc dev sys tmp 'sys/firmware/efi/efivars' 'sys/fs/cgroup'; do prun /usr/bin/mount --bind "/$i" "${encrypt_dir}/mnt/$i" done prun /usr/bin/mount -o compress=zstd:1,subvol=/@/.snapshots /dev/mapper/aeon_root ${encrypt_dir}/mnt/.snapshots prun /usr/bin/mount -o compress=zstd:1,subvol=/@/var /dev/mapper/aeon_root ${encrypt_dir}/mnt/var etcmountcmd=$(cat ${encrypt_dir}/mnt/etc/fstab | grep "overlay /etc" | sed 's/\/sysroot\//${encrypt_dir}\/mnt\//g' | sed 's/\/work-etc.*/\/work-etc ${encrypt_dir}\/mnt\/etc\//' | sed 's/overlay \/etc overlay/\/usr\/bin\/mount -t overlay overlay -o/') eval prun "$etcmountcmd" prun /usr/bin/mount ${esppart} ${encrypt_dir}/mnt/boot/efi prun /usr/bin/mount -t tmpfs tmpfs "${encrypt_dir}/mnt/run" prun /usr/bin/mount -t securityfs securityfs "${encrypt_dir}/mnt/sys/kernel/security" echo "42" > ${encrypt_pipe} } configure_encryption() { # If Default Mode has been detected, configure crypttab for TPM if [ "${tik_encrypt_mode}" == 0 ]; then crypttab_opts=',tpm2-device=auto' fi echo "# Writing cmdline, crypttab, and fstab" > ${encrypt_pipe} log "[configure_encryption] configuring cmdline, crypttab, PCR policy, fstab and populating ${esppart}" espUUID=$(lsblk -n -r -o UUID ${esppart}) prun /usr/bin/gawk -v espUUID=$espUUID -i inplace '$2 == "/boot/efi" { $1 = "UUID="espUUID } { print $0 }' ${encrypt_dir}/mnt/etc/fstab # root=UUID= cmdline definition is a hard requirement of sdbootutil for updating predictions rootUUID=$(lsblk -n -r -o UUID /dev/mapper/aeon_root) prun /usr/bin/sed -i -e "s,\$, root=UUID=${rootUUID}," ${encrypt_dir}/mnt/etc/kernel/cmdline # /etc/crypttab is a hard requirement of sdbootutil for updating predictions cryptUUID=$(lsblk -n -r -d -o UUID ${cryptpart}) echo "aeon_root UUID=${cryptUUID} none x-initrd.attach${crypttab_opts}" | prun tee ${encrypt_dir}/mnt/etc/crypttab echo "# Installing boot loader" > ${encrypt_pipe} # Populate ESP prun /usr/bin/chroot ${encrypt_dir}/mnt sdbootutil -vv --esp-path /boot/efi --no-variables install 1>&2 echo "56" > ${encrypt_pipe} echo "# Creating initrd" > ${encrypt_pipe} # FIXME: Dracut gets confused by previous installations on occasion with the default config, override the problematic option temporarily /usr/bin/echo 'hostonly_cmdline="no"' | prun tee ${encrypt_dir}/mnt/etc/dracut.conf.d/99-tik.conf # mkinitrd done by add-all-kernels prun /usr/bin/chroot ${encrypt_dir}/mnt sdbootutil -vv --esp-path /boot/efi --no-variables add-all-kernels 1>&2 # FIXME: Dracut gets confused by previous installations on occasion with the default config, remove override now initrd done prun /usr/bin/rm ${encrypt_dir}/mnt/etc/dracut.conf.d/99-tik.conf echo "70" > ${encrypt_pipe} # If Default mode has been detected, configure PCR policy if [ "${tik_encrypt_mode}" == 0 ]; then # Explaining the chosen PCR list below # - 0 - UEFI firmware, will require recovery key after firmware update # - 4 - Bootloader and drivers, should never recovery key as bootloader should only be updated with new PCR measurements # - 5 - GPT Partition table, should never require recovery key as partition layout shouldn't change # - 7 - SecureBoot state, will require recovery key if SecureBoot is enabled/disabled # - 9 - initrd - should never require recovery key as initrd should only be updated with new PCR measurements echo "FDE_SEAL_PCR_LIST=0,4,5,7,9" | prun tee ${encrypt_dir}/mnt/etc/sysconfig/fde-tools # Explaining why the following PCRs were not used # - 1 - Not only changes with CPU/RAM/hardware changes, but also when UEFI config changes are made, which is too common to lockdown # - 2 - Includes option ROMs on pluggable hardware, such as external GPUs. Attaching a GPU to your laptop shouldn't hinder booting. # - 3 - Firmware from pluggable hardware. Attaching hardware to your laptop shouldn't hinder booting prun /usr/bin/tee ${encrypt_dir}/mnt/etc/systemd/system/firstboot-update-predictions.service << EOF [Unit] Description=First Boot Update Predictions ConditionSecurity=tpm2 [Service] Type=oneshot ExecStart=rm /etc/systemd/system/firstboot-update-predictions.service ExecStart=rm /etc/systemd/system/default.target.wants/firstboot-update-predictions.service ExecStart=/usr/bin/sdbootutil update-predictions [Install] WantedBy=default.target EOF prun /usr/bin/ln -s ${encrypt_dir}/mnt/etc/systemd/system/firstboot-update-predictions.service ${encrypt_dir}/mnt/etc/systemd/system/default.target.wants/firstboot-update-predictions.service log "[configure_encryption] Generating Predictions" echo "# Generating TPM Predictions" > ${encrypt_pipe} prun /usr/bin/chroot ${encrypt_dir}/mnt sdbootutil -vv update-predictions echo "73" > ${encrypt_pipe} log "[configure_encryption] Default Mode - Enrolling ${cryptpart} to TPM 2.0" echo "# Enrolling to TPM" > ${encrypt_pipe} prun /usr/bin/chroot ${encrypt_dir}/mnt systemd-cryptenroll --unlock-key-file=${tik_keyfile} --tpm2-device=auto ${cryptpart} echo "76" > ${encrypt_pipe} fi } close_partition() { echo "# Closing ${cryptpart}" > ${encrypt_pipe} log "[close_partition] unmounting and closing ${cryptpart}" for i in proc dev run tmp 'boot/efi' etc var '.snapshots' 'sys/kernel/security' 'sys/firmware/efi/efivars' 'sys/fs/cgroup' sys; do prun /usr/bin/umount "${encrypt_dir}/mnt/$i" done prun /usr/bin/umount ${encrypt_dir}/mnt prun /usr/sbin/cryptsetup luksClose aeon_root echo "77" > ${encrypt_pipe} } generate_recoveryKey() { echo "# Generating recovery key" > ${encrypt_pipe} log "[generate_recoveryKey] generating recovery key" modhex=('c' 'b' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'n' 'r' 't' 'u' 'v') mapfile -t raw_key < <(hexdump -v --format '1/1 "%u\n"' -n 32 /dev/random) [ "${#raw_key[@]}" = 32 ] key="" for ((i=0;i<"${#raw_key[@]}";++i)); do [ "$i" -gt 0 ] && [ "$((i%4))" -eq 0 ] && key="${key}-" c="${raw_key[i]}" key="${key}${modhex[$((c>>4))]}${modhex[$((c&15))]}" done echo "84" > ${encrypt_pipe} } add_recoveryKey() { echo "# Adding recovery key to ${cryptpart}" > ${encrypt_pipe} log "[add_recoveryKey] adding recovery key to ${cryptpart}" prun /usr/sbin/cryptsetup luksAddKey --key-file=${tik_keyfile} --batch-mode --force-password "${cryptpart}" <<<"${key}" echo '{"type":"systemd-recovery","keyslots":["2"]}' | prun /usr/sbin/cryptsetup token import "${cryptpart}" echo "100" > ${encrypt_pipe} } display_recoveryKey() { local defaultmsg="This ${TIK_OS_NAME} system is encrypted and checks its own integrity on every boot\nIn the event of these integrity checks failing, you will need to use the Recovery Key provided below to enter this system\n\nLikely reasons for integrity checks failing include:\n\n• UEFI System Firmware updated\n• Secure Boot changed from enabled or disabled\n• Boot drive was moved to a different computer\n• Disk partitions were changed\n• Boot loader or initrd were altered unexpectedly\n\nIf you are unaware as to why the system is requesting the recovery key, this systems security may have been compromised\nThe best course of action may be to not unlock the disk until you can determine what changed to require the Recovery Key\n\nThis systems Recovery Key is:\n\n <b><big>${key}</big></b>\n\nPlease save this secret Recovery Key in a secure location\n\n" local fallbackmsg="In addition to your Passphrase a Recovery Key has been generated:\n\n <b><big>${key}</big></b>\n\nPlease save this secret Recovery Key in a secure location\nIt may be used to regain access to this system if the other Passphrase becomes lost or forgotten\n\n" local message [ "${tik_encrypt_mode}" == 0 ] && message=${defaultmsg} [ "${tik_encrypt_mode}" == 1 ] && message=${fallbackmsg} log "[display_recoveryKey] displaying recovery key" zenity --width=500 --height=500 --no-wrap --warning --icon=security-high-symbolic --title="Encryption Recovery Key" --text="${message}You may optionally scan the recovery key off screen:\n<span face='monospace'>$(qrencode ${key} -t UTF8i)</span>\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>" log "[display_recoveryKey] recovery key dialogue dismissed" } add_key() { if [ "${tik_encrypt_mode}" == 1 ]; then d --width=500 --height=300 --no-wrap --warning --icon=security-high-symbolic --title="Set Encryption Passphrase" --text="This ${TIK_OS_NAME} system is encrypted and will require a Passphrase on every boot\n\nYou will be prompted to set the Passphrase on the next screen\n\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>" log "[add_key] Fallback Mode - Prompting user for passphrase for ${cryptpart}" # Not using 'd' function to avoid logging the password while true do retval=0 key="$(zenity --password --title='Set Encryption Passphrase')" || retval=$? case $retval in 0) prun /usr/sbin/cryptsetup luksAddKey --key-file=${tik_keyfile} --batch-mode --force-password "${cryptpart}" <<<"${key}" return 0 ;; 1|255) zenity --question --text="Do you really want to quit?" && exit 1 ;; esac done fi } crypt_progress & find_crypt find_esp open_partition configure_encryption close_partition add_key generate_recoveryKey add_recoveryKey display_recoveryKey07070100000010000081A400000000000000000000000166AB4F2B00001160000000000000000000000000000000000000002B00000000tik-1.2.14/usr/lib/tik/modules/post/20-mig# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2024 Richard Brown writemigdesktop() { prun-opt /usr/bin/tee $1/.config/autostart/aeon-mig-firstboot.desktop << "EOF" [Desktop Entry] Name=Aeon Migration FirstBoot Setup Comment=Sets up Aeon Correctly On FirstBoot after Migration Exec=/usr/bin/aeon-mig-firstboot Icon=org.gnome.Terminal Type=Application Categories=Utility;System; Name[en_GB]=startup EOF prun-opt /usr/bin/chmod 666 $1/.config/autostart/aeon-mig-firstboot.desktop } if [ "${migrate}" == 1 ]; then probe_partitions ${TIK_INSTALL_DEVICE} "crypto_LUKS" [ -z "${probedpart}" ] || prun /usr/sbin/cryptsetup luksOpen --key-file=${tik_keyfile} ${cryptpart} aeon_root probe_partitions $TIK_INSTALL_DEVICE "btrfs" "/usr/lib/os-release" [ -n "${probedpart}" ] || error "MIGRATION FAILED: New Installation NOT FOUND" prun /usr/bin/mkdir ${mig_dir}/mnt prun /usr/bin/mount -o compress=zstd:1 ${probedpart} ${mig_dir}/mnt prun /usr/bin/systemd-repart --pretty 0 --root ${mig_dir}/mnt --dry-run=0 ${probedpart} prun /usr/bin/mount -o compress=zstd:1,subvol=/@/var ${probedpart} ${mig_dir}/mnt/var prun /lib/systemd/systemd-growfs ${mig_dir}/mnt/var etcmountcmd=$(cat ${mig_dir}/mnt/etc/fstab | grep "overlay /etc" | sed 's/\/sysroot\//${mig_dir}\/mnt\//g' | sed 's/\/work-etc.*/\/work-etc ${mig_dir}\/mnt\/etc\//' | sed 's/overlay \/etc overlay/\/usr\/bin\/mount -t overlay overlay -o/') eval prun "$etcmountcmd" prun /usr/bin/cat ${mig_dir}/passwd.out | prun tee -a ${mig_dir}/mnt/etc/passwd prun /usr/bin/cat ${mig_dir}/group.out | prun tee -a ${mig_dir}/mnt/etc/group prun /usr/bin/cat ${mig_dir}/shadow.out | prun tee -a ${mig_dir}/mnt/etc/shadow prun /usr/bin/sed -i "/^wheel:/ s/$/$(head -n 1 ${mig_dir}/passwd.out | awk -F'[/:]' '{print $1}')/" ${mig_dir}/mnt/etc/group prun /usr/bin/cp -a ${mig_dir}/subuid ${mig_dir}/mnt/etc/subuid prun /usr/bin/cp -a ${mig_dir}/subgid ${mig_dir}/mnt/etc/subgid # It's not guaranteed that the system will have existing network configs, localtime or AccountsService prun-opt /usr/bin/cp -a ${mig_dir}/system-connections/* ${mig_dir}/mnt/etc/NetworkManager/system-connections prun-opt /usr/bin/cp -a ${mig_dir}/localtime ${mig_dir}/mnt/etc/localtime prun-opt /usr/bin/cp -a ${mig_dir}/users/* ${mig_dir}/mnt/var/lib/AccountsService/users prun-opt /usr/bin/cp -a ${mig_dir}/icons/* ${mig_dir}/mnt/var/lib/AccountsService/icons prun-opt /usr/bin/cp -a ${mig_dir}/bluetooth/* ${mig_dir}/mnt/var/lib/bluetooth prun-opt /usr/bin/cp -a ${mig_dir}/fprint/* ${mig_dir}/mnt/var/lib/fprint prun-opt /usr/bin/cp -a ${mig_dir}/openvpn/* ${mig_dir}/mnt/etc/openvpn prun /usr/bin/umount ${mig_dir}/mnt/etc prun /usr/bin/umount ${mig_dir}/mnt/var prun /usr/bin/umount ${mig_dir}/mnt prun /usr/bin/mount -o compress=zstd:1,subvol=/@ ${probedpart} ${mig_dir}/mnt prun /usr/sbin/btrfs subvolume delete ${mig_dir}/mnt/home (prun /usr/sbin/btrfs send ${mig_dir}/${snap_dir} | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}/mnt) 2>&1 | d --progress --title="Restoring /home" --pulsate --auto-close --no-cancel --width=400 prun /usr/bin/mv ${mig_dir}/mnt/${snap_dir} ${mig_dir}/mnt/home prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/mnt/home ro false for subsubvol in $(prun-opt /usr/sbin/btrfs subvolume list -o ${mig_dir}/${snap_dir} --sort=path | rev | cut -f1 -d' ' | rev | sed 's/^@//'); do subsubvolname=$(basename $subsubvol) subsubdirname=$(dirname $subsubvol | awk -F "${mig_dir}/${snap_dir}" '{print $2}') (prun /usr/sbin/btrfs send ${subsubvol} | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}/mnt/home/${subsubdirname} ) 2>&1 | d --progress --title="Restoring containers" --pulsate --auto-close --no-cancel --width=400 prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/mnt/home/${subsubdirname}/${subsubvolname} ro false prun-opt /usr/bin/sed -i 's/driver = "overlay"/driver = "btrfs"/g' ${mig_dir}/mnt/etc/containers/storage.conf done for userhome in ${mig_dir}/mnt/home/*/; do writemigdesktop $userhome done prun /usr/bin/umount ${mig_dir}/mnt prun /usr/bin/rmdir ${mig_dir}/mnt [ ! -e /dev/mapper/aeon_root ] || prun /usr/sbin/cryptsetup luksClose aeon_root fi07070100000011000041ED00000000000000000000000266AB4F2B00000000000000000000000000000000000000000000002300000000tik-1.2.14/usr/lib/tik/modules/pre07070100000012000081A400000000000000000000000166AB4F2B00000888000000000000000000000000000000000000002E00000000tik-1.2.14/usr/lib/tik/modules/pre/10-welcome# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2024 Richard Brown # SPDX-FileCopyrightText: Copyright 2024 Raymond Yip proceedInstall() { d --info --ok-label="Install Now" --no-wrap --width=300 --height=300 --icon=distributor-logo-Aeon-symbolic --title="" --text="<big>Welcome to ${TIK_OS_NAME}</big>\n\nPlease press <b>Install Now</b> to continue" } displayACWarningMsg() { d --warning --no-wrap --title="AC Power Recommended" --text="Runnning on battery power detected\n\nIt is recommended to connect the system to AC power during the install" } checkLaptop() { chassis=`cat /sys/class/dmi/id/chassis_type` #Test for respectively Handheld, Notebook, Laptop, and Portable #if chassis variable matches 8 9 10 or 11 function continues else it proceeds to test AC power and Battery [[ "$chassis" =~ ^(8|9|10|11)$ ]] || return #Tested machine is confirmed mobile givePowerRecommendation=false #Only check for AC and Battery power connections with upower updevices=`/usr/bin/upower -e|grep -E 'AC|BAT'` for pdev in $updevices; do #Get detailed info for each AC and BAT device in upower upinfo=`/usr/bin/upower -i $pdev|grep -E 'online|state'` #Check for discharging state or AC power offline which is equal to no state if [[ "$upinfo" =~ (discharging|no) ]]; then #Give power recommendation only once, so set this to true givePowerRecommendation=true fi done if [ "$givePowerRecommendation" = true ]; then log "AC Power disconnected and Battery is not charging" displayACWarningMsg fi } verify_efi() { # Verify that the system was booted with EFI, exit with error if not if [ ! -d /sys/firmware/efi ]; then # System was not booted with EFI local error_msg="${TIK_OS_NAME} requires UEFI mode, which is not found on your system.\nPlease check your BIOS settings to see if UEFI can be enabled." error "${error_msg}" fi } proceedInstall verify_efi checkLaptop 07070100000013000081A400000000000000000000000166AB4F2B0000111D000000000000000000000000000000000000002E00000000tik-1.2.14/usr/lib/tik/modules/pre/15-encrypt# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2024 Richard Brown # Based on the guide documented here: https://en.opensuse.org/index.php?title=Portal:Aeon/Encryption # verify_tpm checks which encryption mode the system is capable of, and stores it in ${tik_encrypt_mode} for use by post module # "tik_encrypt_mode = 0" - Default Mode # "tik_encrypt_mode = 1" - Fallback Mode # check_secureboot checks if secureboot is disabled for Fallback mode. Does not do anything if Default Mode. # encrypt_notification does nothing if Default Mode. For Fallback mode it provides a single notification containing the following information # - That Fallback Mode is enabled because [TPM 2.0 is missing | lacking features] # - That they will be prompted to enter a passphrase to encrypt their system later # - If Secureboot is disabled they will be encouraged to exit and enable it # - For more information go to rewrite https://aeondesktop.org/encrypt verify_tpm() { # Verify that the system has a TPM 2.0 if [ -c /dev/tpmrm0 ]; then # TPM 2.0 found tpm_found=1 log "[verify_tpm] TPM 2.0 found, checking for PolicyAuthorizeNV" # Check for command 0x192 PolicyAuthorizeNV if prun tpm2_getcap commands | grep -q 'commandIndex: 0x192'; then # PolicyAuthorizeNV found, set encryption mode to default tik_encrypt_mode=0 log "[verify_tpm] PolicyAuthorizeNV support found, Default Mode set" else # PolicyAuthorizeNV not found, set encryption mode to fallback tik_encrypt_mode=1 log "[verify_tpm] PolicyAuthorizeNV support not found, Fallback Mode set" fi else # TPM 2.0 not found, set encryption mode to fallback tpm_found=0 tik_encrypt_mode=1 log "[verify_tpm] TPM 2.0 not found, Fallback Mode set" fi } check_secureboot() { # We only care about Secureboot when using Fallback mode if [ "${tik_encrypt_mode}" == 1 ]; then if ! mokutil --sb-state | grep -q 'enabled'; then secureboot_disabled=1 log "[check_secureboot] secureboot disabled, will warn user" else log "[check_secureboot] secureboot enabled" fi fi } encrypt_notification() { local preamble="This system does not meet the Recommended Hardware requirements for ${TIK_OS_NAME}" local postamble="Disk Encryption will use <b>Fallback Mode</b>\nYou will be prompted to create a Passphrase later in the installation\nThis Passphrase will be required to unlock ${TIK_OS_NAME} on every boot\n\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>" local secureboot_warning="It is <b>Strongly Recommended</b> to enable SecureBoot\n\nWithout SecureBoot this system will be at increased risk of attacks which could compromise the security of your data\nPlease <b>Cancel Installation</b> and enable SecureBoot\n\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>" local reason # We're only going to show a notification when using Fallback mode if [ "${tik_encrypt_mode}" == 1 ]; then [ "${tpm_found}" == 0 ] && reason="No TPM 2.0 chipset found" [ "${tpm_found}" == 1 ] && reason="TPM 2.0 chipset found, but older than v1.38" # Secureboot being disabled makes the notification a Yes/No with the preference being to exit if [ "${secureboot_disabled}" == 1 ]; then log "[encrypt_notification] secureboot warning shown" zenity --width=600 --question --icon=security-low-symbolic --title="Warning" --ok-label="Cancel Installation" --cancel-label="I Understand, Proceed Anyway" --text="${preamble}\n\nReason: <b>SecureBoot Disabled</b> and ${reason}\n\n${secureboot_warning}" && exit 1 log "[encrypt_notification] secureboot warning ignored, installation continuing" d --width=600 --warning --icon=security-low-symbolic --text="${postamble}" # Secureboot is enabled, so show a warning else d --width=600 --warning --icon=security-medium-symbolic --text="${preamble}\n\nReason: ${reason}\n\n${postamble}" fi log "[encrypt_notification] user notified that Fallback mode will be used" fi } verify_tpm check_secureboot encrypt_notification07070100000014000081A400000000000000000000000166AB4F2B00002B09000000000000000000000000000000000000002A00000000tik-1.2.14/usr/lib/tik/modules/pre/20-mig# SPDX-License-Identifier: MIT # SPDX-FileCopyrightText: Copyright 2024 SUSE LLC # SPDX-FileCopyrightText: Copyright 2024 Richard Brown mig_dir=/var/lib/tik/mig snap_dir=homebk if [ ! -d ${mig_dir} ]; then prun /usr/bin/mkdir -p ${mig_dir} fi if [ ! -z "$(ls -A ${mig_dir})" ]; then log "existing backup found" zenity --question --no-wrap --cancel-label="No, Delete Backup" --title="Existing user backup detected" --text="These users can be restored to the new installation\n\nWould you like to use this backup?" oldbackupyn=$? log "[oldbackupyn][${oldbackupyn}]" if [ "${oldbackupyn}" == 0 ]; then skipbackup=1 migrate=1 log "backup skipped, migration will use existing backup" else prun-opt /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro false for subsubvol in $(prun-opt /usr/sbin/btrfs subvolume list -o ${mig_dir}/${snap_dir} --sort=path | rev | cut -f1 -d' ' | rev | sed "s/^@//"); do prun /usr/sbin/btrfs subvolume delete ${subsubvol} done prun-opt /usr/sbin/btrfs subvolume delete ${mig_dir}/${snap_dir} prun-opt /usr/bin/rm ${mig_dir}/*.out prun-opt /usr/bin/rm ${mig_dir}/system-connections/* prun-opt /usr/bin/rmdir ${mig_dir}/system-connections prun-opt /usr/bin/rm ${mig_dir}/users/* prun-opt /usr/bin/rmdir ${mig_dir}/users prun-opt /usr/bin/rm ${mig_dir}/icons/* prun-opt /usr/bin/rmdir ${mig_dir}/icons prun-opt /usr/bin/rm ${mig_dir}/localtime prun-opt /usr/bin/rm ${mig_dir}/subgid prun-opt /usr/bin/rm ${mig_dir}/subuid prun-opt /usr/bin/rm ${mig_dir}/bluetooth/* prun-opt /usr/bin/rmdir ${mig_dir}/bluetooth prun-opt /usr/bin/rm ${mig_dir}/openvpn/* prun-opt /usr/bin/rmdir ${mig_dir}/openvpn prun-opt /usr/bin/rm -R ${mig_dir}/fprint/* prun-opt /usr/bin/rmdir ${mig_dir}/fprint prun-opt /usr/bin/rmdir ${mig_dir}/mnt fi fi get_disk if [ -z "${skipbackup}" ]; then # Although Legacy Aeon didn't officially support LUKS encrypted installations, # some users might have nevertheless enabled encryption anyway. # Search for existing crypto_LUKS partitions and, if found, prompt the user # to unlock those so that the migration module can find existing data. for encrypted_partition in $(lsblk ${TIK_INSTALL_DEVICE} -p -n -r -o ID-LINK,FSTYPE|tr -s ' ' ";"|grep ";crypto_LUKS"|cut -d\; -f1); do if [ -e /dev/mapper/crypt_${encrypted_partition} ]; then # Already opened for some reason... do not prompt for the passphrase # but ensure we will clean up afterwards crypt_opened="${crypt_opened} crypt_${encrypted_partition}" else while [ 1 ]; do passphrase=$(zenity --password --title="Encrypted partition (${encrypted_partition}) detected" --cancel-label="Skip") || break if [ -n "${passphrase}" ]; then echo -n "${passphrase}" | prun /usr/sbin/cryptsetup luksOpen /dev/disk/by-id/${encrypted_partition} crypt_${encrypted_partition} if [ "${?}" -eq 0 ]; then crypt_opened="${crypt_opened} crypt_${encrypted_partition}" # Wait for the mapped device to appear wait_count=0 while [ ! -e /dev/mapper/crypt_${encrypted_partition} ] && [ ${wait_count} -lt 5 ]; do sleep 1 wait_count=$((wait_count + 1)) done break fi fi done fi done unset passphrase # Probe selected disk for a btrfs partition containing /usr/lib/os-release probe_partitions $TIK_INSTALL_DEVICE "btrfs" "/usr/lib/os-release" if [ -n "${probedpart}" ]; then prun /usr/bin/mkdir ${mig_dir}/mnt prun-opt /usr/bin/mount -o compress=zstd:1,subvol=/@/home ${probedpart} ${mig_dir}/mnt if [ ${retval} -eq 0 ]; then prun /usr/sbin/btrfs quota rescan -w ${mig_dir}/mnt | d --progress --title="Detected existing /home subvolume.." --pulsate --auto-close --no-cancel --width=400 home_size=$(prun /usr/sbin/btrfs qgroup show --raw -f ${mig_dir}/mnt | grep @/home$ | awk '{print $2}') tik_stick_size=$(prun /usr/sbin/btrfs fi usage --raw ${mig_dir} | grep estimated | awk '{print $3}') if [ ${home_size} -gt ${tik_stick_size} ]; then # Not enough space to offer migration migrate=0 fi if [ ${home_size} -le 16384 ]; then # /home subvolume is empty migrate=0 fi prun /usr/bin/umount ${mig_dir}/mnt else log "no @/home subvolume found on ${probedpart}" migrate=0 fi prun /usr/bin/rmdir ${mig_dir}/mnt # partition found, /home subvolume found, no known reason to not migrate, so ask the user if [ -z "${migrate}" ]; then if [ "${legacy_aeon}" == 1 ]; then d --info --width=300 --height=300 --icon=distributor-logo-Aeon-symbolic --no-wrap --title="Message from the Aeon Team" --text="We'd like to thank you for adopting openSUSE Aeon so early in it's development,\nbefore we fully understood what we were building or how we wanted it to look\n\nWe are sorry that you need to reinstall your system\n\nThank you so much for your support.\nWe hope you enjoy the new look openSUSE Aeon" fi zenity --question --no-wrap --title="Backup users from the existing install?" --text="These users will be restored to the new installation." migrateyn=$? if [ "${migrateyn}" == 0 ]; then migrate=1 else migrate=0 fi fi fi if [ "${migrate}" == 1 ]; then # We're migrating, lets go! prun /usr/bin/mkdir ${mig_dir}/mnt prun /usr/bin/mount -o compress=zstd:1,subvol=/@/home ${probedpart} ${mig_dir}/mnt # Check for existing snapshot from interrupted backup and delete if it exists boo#1224824 if [ -d ${mig_dir}/mnt/${snap_dir} ]; then prun /usr/sbin/btrfs subvolume delete ${mig_dir}/mnt/${snap_dir} fi prun /usr/sbin/btrfs subvolume snapshot -r ${mig_dir}/mnt ${mig_dir}/mnt/${snap_dir} (prun /usr/sbin/btrfs send ${mig_dir}/mnt/${snap_dir} | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}) 2>&1 | d --progress --title="Backing up /home" --pulsate --auto-close --no-cancel --width=400 prun /usr/sbin/btrfs subvolume delete ${mig_dir}/mnt/${snap_dir} # Probe for subvolumes nested beneath /home and back them up also if (prun-opt /usr/sbin/btrfs subvolume list -o ${mig_dir}/mnt | grep -q "ID "); then prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro false for subsubvol in $(prun-opt /usr/sbin/btrfs subvolume list -o ${mig_dir}/mnt --sort=path | rev | cut -f1 -d' ' | rev | sed 's/^@\/home//'); do subsubvolname=$(basename $subsubvol) subsubdirname=$(dirname $subsubvol) prun /usr/sbin/btrfs subvolume snapshot -r ${mig_dir}/mnt/${subsubvol} ${mig_dir}/mnt/${subsubvolname} (prun /usr/sbin/btrfs send ${mig_dir}/mnt/${subsubvolname} | pv -f -F "# %b copied in %t %r" | prun /usr/sbin/btrfs receive ${mig_dir}/${snap_dir}/${subsubdirname}) 2>&1 | d --progress --title="Backing up containers" --pulsate --auto-close --no-cancel --width=400 prun /usr/sbin/btrfs subvolume delete ${mig_dir}/mnt/${subsubvolname} done prun /usr/sbin/btrfs property set -f -ts ${mig_dir}/${snap_dir} ro true fi prun /usr/bin/umount ${mig_dir}/mnt prun /usr/bin/mount -o compress=zstd:1 ${probedpart} ${mig_dir}/mnt prun /usr/bin/mount -o compress=zstd:1,subvol=/@/var ${probedpart} ${mig_dir}/mnt/var etcmntcmd=$(cat ${mig_dir}/mnt/etc/fstab | grep "overlay /etc" | sed 's/\/sysroot\//${mig_dir}\/mnt\//g' | sed 's/\/work-etc.*/\/work-etc ${mig_dir}\/mnt\/etc\//' | sed 's/overlay \/etc overlay/\/usr\/bin\/mount -t overlay overlay -o/') eval prun "$etcmntcmd" prun /usr/bin/awk -F'[/:]' '($3 >= 1000 && $3 != 65534)' ${mig_dir}/mnt/etc/passwd | prun /usr/bin/awk -F':' '{ $7="/bin/bash"; print };' OFS=':' | prun tee ${mig_dir}/passwd.out prun /usr/bin/awk -F'[/:]' '($3 >= 1000 && $3 != 65534 && $3 != 65533)' ${mig_dir}/mnt/etc/group | prun tee ${mig_dir}/group.out prun /usr/bin/awk -F'[/:]' '{if ($3 >= 1000 && $3 != 65534) print $1}' ${mig_dir}/mnt/etc/passwd | prun /usr/bin/grep -f - ${mig_dir}/mnt/etc/shadow | prun tee ${mig_dir}/shadow.out prun /usr/bin/cp -a ${mig_dir}/mnt/etc/subuid ${mig_dir}/subuid prun /usr/bin/cp -a ${mig_dir}/mnt/etc/subgid ${mig_dir}/subgid # It's not guaranteed that the system will have existing network configs, custom localtime or AccountsService prun-opt /usr/bin/cp -a ${mig_dir}/mnt/etc/NetworkManager/system-connections ${mig_dir}/system-connections prun-opt /usr/bin/cp -a ${mig_dir}/mnt/etc/localtime ${mig_dir}/localtime prun-opt /usr/bin/cp -a ${mig_dir}/mnt/var/lib/AccountsService/users ${mig_dir}/users prun-opt /usr/bin/chmod 744 ${mig_dir}/users prun-opt /usr/bin/cp -a ${mig_dir}/mnt/var/lib/AccountsService/icons ${mig_dir}/icons prun-opt /usr/bin/cp -a ${mig_dir}/mnt/var/lib/bluetooth ${mig_dir}/bluetooth prun-opt /usr/bin/cp -a ${mig_dir}/mnt/var/lib/fprint ${mig_dir}/fprint prun-opt /usr/bin/cp -a ${mig_dir}/mnt/etc/openvpn ${mig_dir}/openvpn prun-opt /usr/bin/umount ${mig_dir}/mnt/etc prun /usr/bin/umount ${mig_dir}/mnt/var prun /usr/bin/umount ${mig_dir}/mnt prun /usr/bin/rmdir ${mig_dir}/mnt fi # Close eventual mapped LUKS devices if [ -n "${crypt_opened}" ]; then for mapped_partition in ${crypt_opened}; do if [ -e /dev/mapper/crypt_${encrypted_partition} ]; then # We are going to replace the encrypted partition anyway, so if # we're unable to gracefully close the device after 5 seconds, # just give up (hence the prun-opt usage) wait_count=0 while ! prun-opt /usr/sbin/cryptsetup luksClose /dev/mapper/${mapped_partition} && [ ${wait_count} -lt 5 ]; do sleep 1 wait_count=$((wait_count + 1)) done fi done fi fi 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!130 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor