File tik-1.2.4.obscpio of Package tik-experimental

07070100000000000081A4000000000000000000000001692B220400000454000000000000000000000000000000000000001200000000tik-1.2.4/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.
07070100000001000081A4000000000000000000000001692B220400001719000000000000000000000000000000000000001400000000tik-1.2.4/README.md# tik

Tailored 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
07070100000002000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000000E00000000tik-1.2.4/etc07070100000003000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001200000000tik-1.2.4/etc/tik07070100000004000081A4000000000000000000000001692B220400000377000000000000000000000000000000000000001900000000tik-1.2.4/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"07070100000005000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001000000000tik-1.2.4/tests07070100000006000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001700000000tik-1.2.4/tests/cenity07070100000007000081ED000000000000000000000001692B220400000103000000000000000000000000000000000000002300000000tik-1.2.4/tests/cenity/d_feeder.sh#!/bin/sh

mkfifo encrypt_pipe

sleep 5 
echo "# first line" > encrypt_pipe
sleep 1
echo "# second line" > encrypt_pipe
sleep 2
echo "invisible line" > encrypt_pipe
sleep 1
echo "# third line" > encrypt_pipe
sleep 1
echo "100" > encrypt_pipe

rm encrypt_pipe
07070100000008000081A4000000000000000000000001692B220400000414000000000000000000000000000000000000002700000000tik-1.2.4/tests/cenity/d_function_testcenity="../../usr/lib/tik/lib/cenity"
. $cenity

compare() {
    if [ "$mode" = "output" ]; then
        echo "$1"
    elif [ "$mode" = "sidebyside" ]; then
        diff -y <(echo "$1") <(echo "$2") || RESULT=$((RESULT+1))
    else
        diff <(echo "$1") <(echo "$2") || RESULT=$((RESULT+1))
    fi
}

string_test() {
    local strings=("$@")

    echo "$strings"

    for i in "${strings[@]}"; do
        echo "Testing $i"
        if grep "$i" "/tmp/out"; then
            echo "$i found - passed"
        else
            echo "$i not found - failed"
            RESULT=$((RESULT+1))
        fi
    done
}

check_result() {
    if [ $RESULT -gt 0 ]; then
        echo "$0 FAILED"
        exit 1
    else
        echo "$0 PASSED"
        exit 0
    fi

    echo "Error"
    exit 255
}

c_test() {
    unset c_retval
    
    cenity c_result "$@" || c_retval=$?
    echo "[cenity][${c_retval}][${c_result}] $@"
}

z_test() {
    unset z_retval

    z_result="$(zenity "$@")" || z_retval=$?
    echo "[zenity][${z_retval}][${z_result}] $@"
}
07070100000009000081ED000000000000000000000001692B2204000008FE000000000000000000000000000000000000003000000000tik-1.2.4/tests/cenity/disabled-tik_progress.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
./d_feeder.sh &
sleep 1
(tail -f encrypt_pipe) | c_test --progress --title="Configuring Encryption" --auto-close --no-cancel --width=400 > /tmp/out
strings=(
  "Configuring Encryption"
  "0% - # first line"
  "0% - # third line"
  "100%"
  "[cenity][][]"
)
string_test "${strings[@]}"
echo
rm -f /tmp/out


#######################################

(echo "10" ; sleep 1
echo "# Updating mail logs" ; sleep 1
echo "20" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "50" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "75" ; sleep 1
echo "# Rebooting system" ; sleep 1
echo "100" ; sleep 1
) | c_test --progress --title="Update System Logs" \
--text="Scanning mail logs..." --percentage=0 > /tmp/out 

strings=(
  "Update System Logs"
  "10% - # Updating mail logs"
  "100%"
  "[cenity][][]"
)
string_test "${strings[@]}"
echo
rm -f /tmp/out


#######################################
(cat /dev/zero | pv -f -F "# %b copied in %t %r" | /usr/bin/dd of=/dev/null bs=64k count=30GB) 2>&1 2>&1 | c_test --progress --title="Installing Testsystem" --pulsate --auto-close --no-cancel --width=400 > /tmp/out

strings=(
  "Installing Testsystem"
  "30000000000 bytes (30 GB, 28 GiB)"
  "# 27.9GiB copied in "
  "[cenity][][]"
)
string_test "${strings[@]}"
echo
rm -f /tmp/out

check_result


#TODO
#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)

#prun /usr/sbin/btrfs quota rescan -w ${mig_dir}/mnt | d_test --progress --title="Detected existing /home subvolume.." --pulsate --auto-close --no-cancel --width=400

#(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_test --progress --title="Backing up /home" --pulsate --auto-close --no-cancel --width=400

#(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_test --progress --title="Backing up containers" --pulsate --auto-close --no-cancel --width=400
0707010000000A000081ED000000000000000000000001692B2204000006B1000000000000000000000000000000000000002A00000000tik-1.2.4/tests/cenity/manual_progress.sh#!/bin/sh

cenity="../../usr/lib/tik/lib/cenity"
. $cenity

RESULT=1

z_result="$((
echo "10" ; sleep 1
echo "# Updating mail logs" ; sleep 1
echo "20" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "50" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "75" ; sleep 1
echo "# Rebooting system" ; sleep 1
echo "100" ; sleep 1
) |
zenity --progress --title="Update System Logs" \
  --text="Scanning mail logs..." --percentage=0)" ; z_retval=$?

(
echo "10" ; sleep 1
echo "# Updating mail logs" ; sleep 1
echo "20" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "50" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "75" ; sleep 1
echo "# Rebooting system" ; sleep 1
echo "100" ; sleep 1
) |
cenity c_result --progress --title="Update System Logs" \
  --text="Scanning mail logs..." --percentage=0 ; c_retval=$?


echo "[cenity][${c_retval}][${c_result}]"
echo "[zenity][${z_retval}][${z_result}]"

RESULT=1

z_result="$((
echo "# Updating mail logs" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "# Rebooting system" ; sleep 1
) |
zenity --progress --title="Update System Logs" \
   --pulsate --auto-close --no-cancel)" ; z_retval=$?

(
echo "# Updating mail logs" ; sleep 1
echo "# Resetting cron jobs" ; sleep 1
echo "This line will just be ignored" ; sleep 1
echo "# Rebooting system" ; sleep 1
) |
cenity c_result --progress --title="Update System Logs" \
   --pulsate --auto-close --no-cancel ; c_retval=$?


echo "[cenity][${c_retval}][${c_result}]"
echo "[zenity][${z_retval}][${z_result}]"



if [[ ${c_retval} = ${z_retval} ]] && [[ ${c_result} = ${z_result} ]]; then
  RESULT=0
fi

echo "Result: $RESULT"

0707010000000B000081ED000000000000000000000001692B2204000002E2000000000000000000000000000000000000002400000000tik-1.2.4/tests/cenity/run_tests.sh#!/bin/sh

PASSED=0
FAILED=0

mode=diff

for p in "$@"; do
  case "$p" in
    --mode*)
      mode=$(sed 's/^--mode=//' <<< $p)
      ;;
    *)
      echo "Unknown parameter"
      exit 1
      ;;
  esac
done

if ! [[ "$mode" =~ ^(diff|output|sidebyside)$ ]]; then
  echo "Unknown mode: $mode"
  exit 1
fi

for test in tik_*; do
  RESULT=0
  echo
  echo "############## Running: ${test} ##############"
  mode="$mode" ./${test} || RESULT=1
  echo "Test result for ${test}: $RESULT"
  if [ $RESULT == 1 ]; then
    FAILED=$((FAILED+1))
  elif [ $RESULT == 0 ]; then
    PASSED=$((PASSED+1))
  else
    echo error
  fi
done

echo "Tests passed: $PASSED"
echo "Tests failed: $FAILED"

if [ $FAILED -gt 0 ]; then
    exit 1
else
    exit 0
fi
0707010000000C000081ED000000000000000000000001692B2204000000E4000000000000000000000000000000000000002000000000tik-1.2.4/tests/cenity/template#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="$(echo -e '<EXPECTED OUTPUT>')"
output="$(c_test <options> <<< <input> 2>&1)"
compare "$output" "$asserted_output"

check_result
0707010000000D000081ED000000000000000000000001692B2204000001A6000000000000000000000000000000000000002400000000tik-1.2.4/tests/cenity/tik_entry.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="$(echo -e '--ENTRY----- This is a ENTRY ----------------

Press CTRL+C to cancel
[cenity][][Test entry] --entry --text=This is a entry text --title=This is a ENTRY')"
output="$(c_test --entry --text="This is a entry text" --title="This is a ENTRY" <<< "Test entry" 2>&1)"
compare "$output" "$asserted_output"

check_result
0707010000000E000081ED000000000000000000000001692B2204000003E1000000000000000000000000000000000000002400000000tik-1.2.4/tests/cenity/tik_error.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="$(echo -e '--ERROR----- Installation Failed ----------------

Please file a bug report at \033[1mTEST URL\033[0m

Please include the \033[1mtik.log\033[0m file
It can be found on the IGNITION partition on this USB Stick

\033[1mSystem is shutting down\033[0m

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --error --no-wrap --title=Installation Failed --text=Please file a bug report at <tt>TEST 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>')"
output="$(c_test --error --no-wrap --title="Installation Failed" --text="Please file a bug report at <tt>TEST 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>" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"

check_result
0707010000000F000081ED000000000000000000000001692B220400001B68000000000000000000000000000000000000002300000000tik-1.2.4/tests/cenity/tik_info.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="$(echo -e '--INFO------  ----------------

\033[1mTest Succeeded:\033[0m

Have a nice day!

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --timeout 5 --info --no-wrap --text=<b>Test Succeeded:</b>\\n\\nHave a nice day!')"
output="$(c_test --timeout 5 --info --no-wrap --text="<b>Test Succeeded:</b>\n\nHave a nice day!" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--INFO------ Installation Complete! ----------------

TIK_OS_NAME has been installed.

\033[1mSystem is rebooting\033[0m

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --timeout 5 --info --no-wrap --title=Installation Complete! --text=TIK_OS_NAME has been installed.\\n\\n<b>System is rebooting</b>')"
output="$(c_test --timeout 5 --info --no-wrap --title="Installation Complete!" --text="TIK_OS_NAME has been installed.\n\n<b>System is rebooting</b>" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--WARNING--- Encryption Recovery Key -------------security-high--

You may optionally scan the recovery key off screen:
                             
                             
    █▀▀▀▀▀█   ▀ █ █▀▀▀▀▀█    
    █ ███ █ ▀ ▀ ▄ █ ███ █    
    █ ▀▀▀ █  █▄█▀ █ ▀▀▀ █    
    ▀▀▀▀▀▀▀ █ █ ▀ ▀▀▀▀▀▀▀    
    ▀█▀▄█▀▀▀▀ █▄▀█▀▄  ▀▄▄    
    ▄ █ ▄▄▀▄▄▄ █▄█▀█▄▀▀█▀    
     ▀ ▀  ▀ █▄▄▀ ▀█▀ █ ▀█    
    █▀▀▀▀▀█ █▄▀ ▀ ▄ ▀▀ █▀    
    █ ███ █ ▀▀▄▄▀▄▀▄▀▀ █▀    
    █ ▀▀▀ █ █▀▄█▄█▀█▄▄▀▄▀    
    ▀▀▀▀▀▀▀ ▀▀ ▀ ▀▀▀  ▀▀▀    
                             
                             
For more information please visit \033[1mhttps://aeondesktop.org/encrypt\033[0m

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --width=500 --height=500 --no-wrap --warning --icon=security-high-symbolic --title=Encryption Recovery Key --text=You may optionally scan the recovery key off screen:\\n<span face='\''monospace'\''>                             
                             
    █▀▀▀▀▀█   ▀ █ █▀▀▀▀▀█    
    █ ███ █ ▀ ▀ ▄ █ ███ █    
    █ ▀▀▀ █  █▄█▀ █ ▀▀▀ █    
    ▀▀▀▀▀▀▀ █ █ ▀ ▀▀▀▀▀▀▀    
    ▀█▀▄█▀▀▀▀ █▄▀█▀▄  ▀▄▄    
    ▄ █ ▄▄▀▄▄▄ █▄█▀█▄▀▀█▀    
     ▀ ▀  ▀ █▄▄▀ ▀█▀ █ ▀█    
    █▀▀▀▀▀█ █▄▀ ▀ ▄ ▀▀ █▀    
    █ ███ █ ▀▀▄▄▀▄▀▄▀▀ █▀    
    █ ▀▀▀ █ █▀▄█▄█▀█▄▄▀▄▀    
    ▀▀▀▀▀▀▀ ▀▀ ▀ ▀▀▀  ▀▀▀    
                             
                             </span>\\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>')"
output="$(c_test --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 test -t UTF8i)</span>\nFor more information please visit <tt>https://aeondesktop.org/encrypt</tt>" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--WARNING--- Set Encryption Passphrase -------------security-high--

This  system is encrypted and will require a Passphrase on every boot

You will be prompted to set the Passphrase on the next screen

For more information please visit \033[1mhttps://aeondesktop.org/encrypt\033[0m

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --width=500 --height=300 --no-wrap --warning --icon=security-high-symbolic --title=Set Encryption Passphrase --text=This  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>')"
output="$(c_test --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>" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--INFO------ Message from the Aeon Team ----------------

We'\''d like to thank you for adopting openSUSE Aeon so early in it'\''s development,
before we fully understood what we were building or how we wanted it to look

We are sorry that you need to reinstall your system

Thank you so much for your support.
We hope you enjoy the new look openSUSE Aeon

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --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')"
output="$(c_test --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" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--INFO------  ----------------

\033[1mWelcome to \033[0m

Please press \033[1mInstall Now\033[0m to continue

Press CTRL+C to cancel
Press any key to Install Now
[cenity][][] --info --ok-label=Install Now --no-wrap --width=300 --height=300 --icon=distributor-logo-Aeon-symbolic --title= --text=<big>Welcome to </big>\\n\\nPlease press <b>Install Now</b> to continue')"
output="$(c_test --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" <<< "\n" 2>&1)"
compare "$output" "$asserted_output"

tput sgr0
check_result
07070100000010000081ED000000000000000000000001692B220400001353000000000000000000000000000000000000002300000000tik-1.2.4/tests/cenity/tik_list.sh#!/bin/sh

. ./d_function_test

RESULT=0

list_items=' virtio-0987654321 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test2 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test3 20G 3 unknown(2M),vfat(20M),btrfs(4.3G)'
#######################################
asserted_output="$(echo -e '--LIST------ Select A Disk ----------------

Press CTRL+C to cancel
Select the disk to install the operating system to.

\033[1mMake sure any important documents and files have been backed up.\033[0m

Item  Disk               Size  Partitions  Filesystems
0:    virtio-0987654321  20G   3           unknown(2M),vfat(20M),btrfs(4.3G)
1:    virtio-test2       20G   3           unknown(2M),vfat(20M),btrfs(4.3G)
2:    virtio-test3       20G   3           unknown(2M),vfat(20M),btrfs(4.3G)

Please select a item number
[cenity][][virtio-test3] --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.\\n\\n<b>Make sure any important documents and files have been backed up.</b>\\n virtio-0987654321 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test2 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test3 20G 3 unknown(2M),vfat(20M),btrfs(4.3G)')"
output="$(c_test --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.\n\n<b>Make sure any important documents and files have been backed up.</b>\n" ${list_items} <<< "2" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--LIST------ Select A Disk ----------------

Press CTRL+C to cancel
Select the disk to install the operating system to.

\033[1mMake sure any important documents and files have been backed up.\033[0m

Item  Disk               Size  Partitions  Filesystems
0:    virtio-0987654321  20G   3           unknown(2M),vfat(20M),btrfs(4.3G)
1:    virtio-test2       20G   3           unknown(2M),vfat(20M),btrfs(4.3G)
2:    virtio-test3       20G   3           unknown(2M),vfat(20M),btrfs(4.3G)

Please select a item number
[cenity][][virtio-test2] --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.\\n\\n<b>Make sure any important documents and files have been backed up.</b>\\n virtio-0987654321 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test2 20G 3 unknown(2M),vfat(20M),btrfs(4.3G) virtio-test3 20G 3 unknown(2M),vfat(20M),btrfs(4.3G)')"
output="$(c_test --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.\n\n<b>Make sure any important documents and files have been backed up.</b>\n" ${list_items} <<< "1" 2>&1)"
compare "$output" "$asserted_output"


list_items='tik-osimage-Aeon.20240731.raw.xz 1501130408 tik-osimage-Aeon.test2.raw.xz 1501130408 tik-osimage-Aeon.test3.raw.xz 1501130408'
#######################################
asserted_output="$(echo -e '--LIST------ Select A Image ----------------

Press CTRL+C to cancel
Select the operating system image to install.

Item  Image                             Size
0:    tik-osimage-Aeon.20240731.raw.xz  1501130408
1:    tik-osimage-Aeon.test2.raw.xz     1501130408
2:    tik-osimage-Aeon.test3.raw.xz     1501130408

Please select a item number
[cenity][][tik-osimage-Aeon.test2.raw.xz] --list --column=Image --column=Size --title=Select A Image --text=Select the operating system image to install.\\n tik-osimage-Aeon.20240731.raw.xz 1501130408 tik-osimage-Aeon.test2.raw.xz 1501130408 tik-osimage-Aeon.test3.raw.xz 1501130408')"
output="$(c_test --list --column=Image --column=Size --title="Select A Image" --text="Select the operating system image to install.\n" ${list_items} <<< "1" 2>&1)"
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--LIST------ Select A Image ----------------

Press CTRL+C to cancel
Select the operating system image to install.

Item  Image                             Size
0:    tik-osimage-Aeon.20240731.raw.xz  1501130408
1:    tik-osimage-Aeon.test2.raw.xz     1501130408
2:    tik-osimage-Aeon.test3.raw.xz     1501130408

Please select a item number
[cenity][][tik-osimage-Aeon.test3.raw.xz] --list --column=Image --column=Size --title=Select A Image --text=Select the operating system image to install.\\n tik-osimage-Aeon.20240731.raw.xz 1501130408 tik-osimage-Aeon.test2.raw.xz 1501130408 tik-osimage-Aeon.test3.raw.xz 1501130408')"
output="$(c_test --list --column=Image --column=Size --title="Select A Image" --text="Select the operating system image to install.\n" ${list_items} <<< "2" 2>&1)"
compare "$output" "$asserted_output"

check_result
07070100000011000081ED000000000000000000000001692B220400000293000000000000000000000000000000000000002700000000tik-1.2.4/tests/cenity/tik_password.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="$(echo -e '--PASSWORD-- Set Encryption Passphrase ----------------

Press CTRL+C to cancel
[cenity][][test] --password --title=Set Encryption Passphrase')"
output="$(c_test --password --title='Set Encryption Passphrase' <<< "test" 2>&1)"
compare "$output" "$asserted_output"


# TODO: Fix cancel-label
#######################################
#asserted_output="$(echo -e 'EXPECTED OUTPUT')"
#output="$(c_test --password --title='Encrypted partition (/devsda) detected' --cancel-label='Skip' <<< "test" 2>&1)"
#compare "$output" "$asserted_output"

check_result
07070100000012000081ED000000000000000000000001692B22040000093E000000000000000000000000000000000000002700000000tik-1.2.4/tests/cenity/tik_question.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="\
--QUESTION--  ----------------

Do you really want to quit?

Press CTRL+C to cancel
1) Yes
2) No
#? Selected: 1) yes
[cenity][][] --question --text=Do you really want to quit?"

output=$(c_test --question --text="Do you really want to quit?" <<< 1 2>&1) 
compare "$output" "$asserted_output"


asserted_output="\
--QUESTION--  ----------------

Do you really want to quit?

Press CTRL+C to cancel
1) Yes
2) No
#? Selected: 2) No
[cenity][1][] --question --text=Do you really want to quit?"

output=$(c_test --question --text="Do you really want to quit?" <<< 2 2>&1)
compare "$output" "$asserted_output"


#######################################
asserted_output="\
--QUESTION-- Backup users from the existing install? ----------------

These users will be restored to the new installation.

Press CTRL+C to cancel
1) Yes
2) No
#? Selected: 1) yes
[cenity][][] --question --no-wrap --title=Backup users from the existing install? --text=These users will be restored to the new installation."

output=$(c_test --question --no-wrap --title="Backup users from the existing install?" --text="These users will be restored to the new installation." <<< 1 2>&1)
compare "$output" "$asserted_output"


asserted_output="\
--QUESTION-- Backup users from the existing install? ----------------

These users will be restored to the new installation.

Press CTRL+C to cancel
1) Yes
2) No
#? Selected: 2) No
[cenity][1][] --question --no-wrap --title=Backup users from the existing install? --text=These users will be restored to the new installation."

output=$(c_test --question --no-wrap --title="Backup users from the existing install?" --text="These users will be restored to the new installation." <<< 2 2>&1)
compare "$output" "$asserted_output"


# TODO implement ok/cancel label and icon ahndling

#c_test --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}"

#c_test --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?"

check_result
07070100000013000081ED000000000000000000000001692B22040000065D000000000000000000000000000000000000002600000000tik-1.2.4/tests/cenity/tik_warning.sh#!/bin/sh

. ./d_function_test

RESULT=0

#######################################
asserted_output="\
--WARNING--- AC Power Recommended ----------------

Runnning on battery power detected

It is recommended to connect the system to AC power during the install

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --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"
output=$(c_test --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" <<< "\n" 2>&1)
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--WARNING---  -------------security-low--

postamble

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --width=600 --warning --icon=security-low-symbolic --text=postamble')"
output=$(c_test --width=600 --warning --icon=security-low-symbolic --text="postamble" <<< "\n" 2>&1)
compare "$output" "$asserted_output"


#######################################
asserted_output="$(echo -e '--WARNING---  -------------security-medium--

preamble

Reason: reason

postamble

Press CTRL+C to cancel
Press any key to continue
[cenity][][] --width=600 --warning --icon=security-medium-symbolic --text=preamble\\n\\nReason: reason\\n\\npostamble')"
output=$(c_test --width=600 --warning --icon=security-medium-symbolic --text="preamble\n\nReason: reason\n\npostamble" <<< "\n" 2>&1)
compare "$output" "$asserted_output"

check_result
07070100000014000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000000E00000000tik-1.2.4/usr07070100000015000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001200000000tik-1.2.4/usr/bin07070100000016000081ED000000000000000000000001692B220400000905000000000000000000000000000000000000001600000000tik-1.2.4/usr/bin/tik#!/bin/bash
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2023-2024 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2023-2024 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

# 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"

# Common helpers used by tik and modules
. ${tik_dir}/lib/tik-functions
# Core installer logic used only by tik and phase scripts
. ${tik_dir}/lib/tik-core

# Start logging
exec 2> >(exec tee -i -a "${tik_log}" >&2)
logging=true
log "[START] $0"

# Check for debug mode
if [[ $1 == "--debug" ]]; then
    debug=1
fi

# Check if graphical display is available
XDG_SESSION="${XDG_SESSION_TYPE:=unspecified}"
if [ "${XDG_SESSION_TYPE}" = "wayland" ] || [ "${XDG_SESSION_TYPE}" = "x11" ] ; then
    gui=true
else
    gui=false
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
        d --timeout 5 --info --no-wrap --text="<b>Test Succeeded:</b>\n\nHave a nice day!"
    elif [ "${retval}" == "0" ]; then
        d --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
        d --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

# Run pre modules
tik_init_phase_modules "pre"
load_modules "pre"
load_modules "pre" "custom"

# Select installation disk and image, then deploy image to disk
get_disk
get_img
dump_image "${TIK_INSTALL_IMAGE}" "${TIK_INSTALL_DEVICE}"
reread_partitiontable

# Run post modules
tik_init_phase_modules "post"
load_modules "post"
load_modules "post" "custom"
07070100000017000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001200000000tik-1.2.4/usr/lib07070100000018000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001600000000tik-1.2.4/usr/lib/tik07070100000019000081A4000000000000000000000001692B220400000359000000000000000000000000000000000000001D00000000tik-1.2.4/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"
0707010000001A000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001A00000000tik-1.2.4/usr/lib/tik/lib0707010000001B000081A4000000000000000000000001692B220400001900000000000000000000000000000000000000002100000000tik-1.2.4/usr/lib/tik/lib/cenitycenity() {

  trap ctrl_c INT
  
  title=""
  text=""
  icon="-"
  function=""
  oklabel="continue"
  cancellabel="cancel"
  cancel=true
  autoclose=false
  pulsate=false
  ctrlc=false
  retvalue=0
  columns=()
  content=()
  column_num=0
  percent=0

  for p in "$@"; do
    case "$p" in
      --info*)
        function=c_info
        ;;
      --warning*)
        function=c_warning
        ;;
      --error*)
        function=c_error
        ;;
      --question*)
        function=c_question
        ;;
      --entry*)
        function=c_entry
        ;;
      --password*)
        function=c_password
        ;;
      --list*)
        function=c_list
        ;;
      --progress*)
        function=c_progress
        ;;
      --title*)
        title=$(sed 's/^--title=//' <<< $p)
        ;;
      --text*)
        text=$(sed 's/^--text=//' <<< $p)
        ;;
      --percentage*)
        percentage=$(sed 's/^--percentage=//' <<< $p)
        ;;
      --ok-label*)
        oklabel=$(sed 's/^--ok-label=//' <<< $p)
        ;;
      --cancel-label*)
        cancellabel=$(sed 's/^--cancel-label=//' <<< $p)
        ;;
      --column*)
        columns+=("$(cut -d '=' -f2 <<< $p)")
        ;;
      --pulsate*)
        pulsate=true
        ;;
      --no-cancel*)
        cancel=false
        ;;
      --auto-close*)
        autoclose=true
        ;;
      --icon*)
        icon=$(sed 's/^--icon=//' <<< $p)
        ;;
      --height*)
        ;;
      --width*)
        ;;
      "")
        ;;
      *)
        content+=("$p")
        ;;
    esac
  done

  ctrl_c() {
    if ! $cancel; then
      echo "No Cancel"
    else
      echo "Cancelled, press Enter to continue"
      ctrlc=true
      return 1
    fi
  }

  if [[ ! $function ]]; then
    echo "function not set"
    return 1
  fi

  text=$(c_replace_tags "$text")
  icon=$(c_handle_icon "$icon")

  if [ $function = "c_progress" ]; then
    echo -e "--PROGESS--- ${title} -------------${icon}--\n"
    c_cancel "$cancellabel"

    if [ -p /dev/stdin ]; then
      if $pulsate; then
        { cat - & c_spinner; }
      else
        while IFS="" read line; do
          c_progress "${line}"
          if [[ "$line" == 100 ]]; then 
            break
	  fi
        done
      fi
      exec </dev/tty >/dev/tty
      c_handle_key "$oklabel"
    fi
  else
    result=""
    $function result "$title" "$text" "$icon" columns content; retvalue=$?
  fi

  eval $1='$result'

  if $ctrlc; then
    retvalue=1
  fi

  return $retvalue
}


c_spinner()
{
    local pid=$!
    local delay=0.4
    local spinstr='|/-\'
    while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
        for X in '-' '/' '|' '\'; do
            echo
            printf "[%c]" "$X"
            echo -en "\033[1A"
            sleep $delay
            printf "\b\b\b\b\b"
        done
    done
}


c_clear() {
  printf "\033c"
}


c_replace_tags() {
  text="$1"
  text="$(echo "$text" | sed -e 's/\(<b>\|<tt>\|<big>\)/\\033[1m/g' | sed 's/\(<\/b>\|<\/tt>\|<\/big>\)/\\033[0m/g')"
  text="$(echo "$text" | sed -e 's/<span face=.*>//')"
  text="$(echo "$text" | sed -e 's/<\/span>//')"
  echo "$text"
}


c_handle_icon() {
  local icon="$1"
  if [[ $icon =~ "security" ]]; then
    icon=$(sed 's/-symbolic$//' <<< $icon)
  else
    icon="-"
  fi
  echo "$icon"
}


c_cancel() {
  cancellabel="$1"
  if $cancel; then
    echo -e "Press CTRL+C to ${cancellabel}"
  fi
}


c_handle_key() {
  oklabel="$1"
  if ! $autoclose; then
    echo -e "Press any key to ${oklabel}"
    read -n 1 -s -r
  fi
}


c_progress() {
  local l=$1
  local re='^[0-9]+$'

  if [[ ${l} =~ $re ]]; then
    # clear line
    printf ' %.0s' {1..100} ; echo -ne "\r"
    percent=$l
    # print percentage
    printf '%3s%%' "${percent}"
  elif [[ "${l}" =~ ^#.* ]] ; then
    # clear line
    printf ' %.0s' {1..100} ; echo -ne "\r"
    # print text with percentage
    printf '%3s%% - %s' "${percent}" "${l}"
  fi
}


c_list() {
  local title=$2
  local text=$3
  local icon=$4
  local -n cols=$5
  local -n cont=$6
  local count=1 # set to 1 to skip the very first content tem, which is the variable to return
  local line=""
  local lines=()
  local output=""

  for l in $(seq 1 ${#cont[@]}); do
    line+=$(printf "%s\t" "${cont[$l]}")
    if (( count == ${#cols[@]} )); then
      lines+=("$line")
      line=""
      count=0
    fi
    count=$((count+1))
  done

  echo -e "--LIST------ ${title} -------------${icon}--\n"
  c_cancel "$cancellabel"
  echo -e "${text}"

  output="Item "
  # add column title
  for key in "${!cols[@]}"; do
    output="${output} $(printf '%s' "${cols[$key]} ")"
  done

  # add columns
  for key in "${!lines[@]}"; do
    output="${output}\n"
    output="${output} $(printf '%s: ' $key)"
    output="${output} $(printf '%s ' ${lines[$key]})"
  done

  # print table
  echo -e $output | column -t

  echo -e "\nPlease select a item number"
  read

  local selected=$(printf "%s" "${lines[$REPLY]}" | cut -d $'\t' -f1)
  eval $1='$selected'
}


c_question() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--QUESTION-- ${title} -------------${icon}--\n"
  echo -e "${text}\n"
  c_cancel "$cancellabel"

  select yn in "Yes" "No"; do
    case $yn in
      Yes )
        echo "Selected: 1) yes"
        return 0
        break
        ;;
      No )
        echo "Selected: 2) No"
        return 1
        break
        ;;
    esac
  done
}


c_entry() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--ENTRY----- ${title} -------------${icon}--\n"
  c_cancel "$cancellabel"
  read -p "${text}: "
  eval $1='$REPLY'
}


c_password() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--PASSWORD-- ${title} -------------${icon}--\n"
  c_cancel "$cancellabel"
  read -s -p "${text}: "
  eval $1='$REPLY'
}


c_info() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--INFO------ ${title} -------------${icon}--\n"
  echo -e "${text}\n"
  c_cancel "$cancellabel"
  c_handle_key "$oklabel"
}


c_warning() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--WARNING--- ${title} -------------${icon}--\n"
  echo -e "${text}\n"
  c_cancel "$cancellabel"
  c_handle_key "$oklabel" "$cancellabel"
}


c_error() {
  local title=$2
  local text=$3
  local icon=$4

  echo -e "--ERROR----- ${title} -------------${icon}--\n"
  echo -e "${text}\n"
  c_cancel "$cancellabel"
  c_handle_key "$oklabel" "$cancellabel"
}
0707010000001C000081A4000000000000000000000001692B2204000034CA000000000000000000000000000000000000002300000000tik-1.2.4/usr/lib/tik/lib/tik-core# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

get_disk() {
    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
            continue
        fi
        disk_device="$(echo "${disk_meta}" | cut -f1 -d:)"
        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
            continue
        fi
        if [[ ${disk_device} =~ ^/dev/fd ]]; then
            continue
        fi
        if [[ ${disk_device} =~ ^/dev/zram ]]; then
            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
            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
        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:)
        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
            TIK_INSTALL_DEVICE="/dev/disk/${disk_id}/${device_array[0]}"
            if [ ! -e "${TIK_INSTALL_DEVICE}" ]; then
                TIK_INSTALL_DEVICE="/dev/${device_array[0]}"
            fi
        else
            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}
            TIK_INSTALL_DEVICE="/dev/disk/${disk_id}/${result}"
            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_list
    local img_array
    local file_type

    for file_type in '*.raw.xz' '*.raw'; do
        for img_meta in $(cd "${TIK_IMG_DIR}" && (stat --printf="%n\t%s\n" ${file_type} 2>/dev/null | 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
        local img=${TIK_INSTALL_IMAGE}
        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
            TIK_INSTALL_IMAGE="${img_array[0]}"
        else
            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() {
    log "[reread_partitiontable] Re-reading partition table"
    sleep 3
    prun /usr/sbin/blockdev --rereadpt "${TIK_INSTALL_DEVICE}"
    sleep 3
}

create_keyfile() {
    tik_keyfile=$(prun mktemp /tmp/tik.XXXXXXXXXX)
    log "[create_keyfile] Creating keyfile ${tik_keyfile}"
    /usr/bin/base64 -w 0 /dev/urandom | head -c 1k | prun tee "${tik_keyfile}"
    prun /usr/bin/chmod 400 "${tik_keyfile}"
    tik_keyid=$(prun cat "${tik_keyfile}" | prun keyctl padd user cryptenroll @u)
}

wipe_keyfile() {
    log "[wipe_keyfile] Deleting keyfile ${tik_keyfile}"
    probe_partitions "${TIK_INSTALL_DEVICE}" "crypto_LUKS"
    if [ -n "${probedpart}" ]; then
        prun /usr/bin/systemd-cryptenroll --unlock-key-file="${tik_keyfile}" --wipe-slot=0 "${probedpart}"
    fi
    prun /usr/bin/rm "${tik_keyfile}"
    prun keyctl revoke "${tik_keyid}"
    prun keyctl reap
}

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}"

    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
            log "[dump_image_repart_image] systemd-repart attempt ${attempt_num} failed. Trying again..."
            sleep 1
            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}" --generate-fstab=/etc/fstab.repart "${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
        prun-opt /usr/sbin/efibootmgr -B -L "openSUSE Boot Manager"
        prun-opt /usr/sbin/efibootmgr -B -L "${TIK_OS_NAME} 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 "${TIK_OS_NAME} Boot Manager" -d "${TIK_INSTALL_DEVICE}" -l "\EFI\systemd\shim.efi" -p ${efipartnum}
        log "[set_boot_target] $(prun /usr/sbin/efibootmgr)"
        efi_already_set=1
    fi
}

tik_init_phase_modules() {
    local phase=$1
    local dir
    TIK_CURRENT_PHASE="${phase}"
    TIK_TOTAL_MODULES=0
    TIK_CURRENT_MODULE_INDEX=0

    for dir in "${tik_dir}/modules/${phase}" "${TIK_CUSTOM_DIR}/modules/${phase}"; do
        if [ -d "${dir}" ]; then
            for f in "${dir}"/*; do
                [ -f "${f}" ] || continue
                TIK_TOTAL_MODULES=$((TIK_TOTAL_MODULES + 1))
            done
        fi
    done

    case $phase in
        "pre")  TIK_PROGRESS_TITLE="Preparing Installation"  ;;
        "post") TIK_PROGRESS_TITLE="Finishing Installation"  ;;
        *)      TIK_PROGRESS_TITLE="Installation"            ;;
    esac

    export TIK_PROGRESS_TITLE

    log "[tik_init_phase_modules] phase=${phase} total_modules=${TIK_TOTAL_MODULES}"
}

load_modules() {
    local phase=$1
    local module_dir

    if [[ $2 = "custom" ]]; then
        module_dir=$TIK_CUSTOM_DIR/modules/$phase
    else
        module_dir=$tik_dir/modules/$phase
    fi

    if [ -n "$(ls -A "$module_dir" 2>/dev/null)" ]; then
        for f in "$module_dir"/*; do
            [ -f "$f" ] || continue
            TIK_CURRENT_MODULE_INDEX=$((TIK_CURRENT_MODULE_INDEX + 1))
            tik_module="$f"
            log "[START] $module_dir/$f (phase=${phase} module_index=${TIK_CURRENT_MODULE_INDEX}/${TIK_TOTAL_MODULES})"
            . "$f"
            log "[STOP] $module_dir/$f"

            # If this was the last module of the phase, close the phase's progress UI
            if [ -n "${TIK_TOTAL_MODULES}" ] && [ "${TIK_TOTAL_MODULES}" -gt 0 ] && \
               [ "${TIK_CURRENT_MODULE_INDEX}" -eq "${TIK_TOTAL_MODULES}" ]; then
                log "[load_modules] last module of phase '${phase}' completed, closing progress"
                tik_close_progress
            fi
        done
    fi
    tik_module="tik"
}
0707010000001D000081A4000000000000000000000001692B220400001B32000000000000000000000000000000000000002800000000tik-1.2.4/usr/lib/tik/lib/tik-functions# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2023-2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2023-2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

. /usr/lib/tik/lib/cenity

log() {
    if $logging; then
        echo "[${tik_module}][$(date +"%Y%m%d-%T")][LOG] $*" 1>&2
    fi
}

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
        if $gui; then
            result="$(zenity "$@")" || retval=$?
            log "[zenity][${retval}][${result}] $@"
        else
            cenity result "$@" || retval=$?
            log "[cenity][${retval}][${result}] $@"
        fi
        case $retval in
            0)
                return 0
            ;;
            1|255)
                if $gui; then
                    zenity --question --text="Do you really want to quit?" && exit 1
                else
                    cenity result --question --text="Do you really want to quit?" && exit 1
                fi
            ;;
        esac
    done
}

d_opt() {
    retval=0
    if $gui; then
        result="$(zenity "$@")" || retval=$?
        log "[zenity][${retval}][${result}] $@"
    else
        cenity result "$@" || retval=$?
        log "[cenity][${retval}][${result}] $@"
    fi
    return $retval
}

# 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
}

mount_etc_for_root() {
    local root=$1

    if grep -qF 'overlay /etc' "${root}/etc/fstab" ; then
        local etcmountcmd
        etcmountcmd=$(grep "overlay /etc" "${root}/etc/fstab" \
            | sed "s#/sysroot/#${root}/#g" \
            | sed "s#/work-etc.*#/work-etc ${root}/etc#g" \
            | sed 's#overlay /etc overlay#/usr/bin/mount -t overlay overlay -o#')
        eval prun "${etcmountcmd}"
    else
        prun /usr/bin/mount -o bind "${root}/etc" "${root}/etc"
    fi
}

tik_monitor_progress() {
    if [ -z "${TIK_PIPE}" ]; then
        return 0
    fi
    log "[progress] Monitoring installation progress"
    (tail -f "${TIK_PIPE}") | d --progress --title="${TIK_PROGRESS_TITLE}" --auto-close --no-cancel --width=400
    log "[progress] Progress UI closed"
}

tik_prepare_progress_pipe() {
    TIK_PIPE=/tmp/tikpipe
    export TIK_PIPE
    [ -p "${TIK_PIPE}" ] || mkfifo "${TIK_PIPE}"

    tik_monitor_progress &
    TIK_PROGRESS_PID=$!

    log "[tik_prepare_progress_pipe] progress pipe ready (pid=${TIK_PROGRESS_PID})"
}

tik_close_progress() {
    if [ -n "${TIK_PROGRESS_PID}" ]; then
        log "[tik_close_progress] stopping progress monitor pid=${TIK_PROGRESS_PID}"
        kill "${TIK_PROGRESS_PID}" 2>/dev/null || true
        wait "${TIK_PROGRESS_PID}" 2>/dev/null || true
        unset TIK_PROGRESS_PID
    fi

    if [ -n "${TIK_PIPE}" ] && [ -p "${TIK_PIPE}" ]; then
        log "[tik_close_progress] removing progress pipe ${TIK_PIPE}"
        rm -f "${TIK_PIPE}" 2>/dev/null || true
    fi
    unset TIK_PIPE
}

tik_progress_step() {
    # Create progress UI when first used in this phase
    [ -n "${TIK_PROGRESS_PID}" ] || tik_prepare_progress_pipe

    local message=$1
    local module_percent=$2

    if [ -z "${TIK_PIPE}" ]; then
        return 0
    fi

    local overall_percent

    if [ -n "${TIK_TOTAL_MODULES}" ] && [ "${TIK_TOTAL_MODULES}" -gt 0 ] && \
       [ -n "${TIK_CURRENT_MODULE_INDEX}" ] && [ "${TIK_CURRENT_MODULE_INDEX}" -gt 0 ]; then
        # Map module-local 0–100% into global 0–100% based on module index
        # overall = ((index-1)*100 + module_percent) / total_modules
        local base=$(( (TIK_CURRENT_MODULE_INDEX - 1) * 100 ))
        local num=$(( base + module_percent ))
        overall_percent=$(( num / TIK_TOTAL_MODULES ))
    else
        overall_percent=${module_percent}
    fi

    echo "# ${message}" > "${TIK_PIPE}"
    echo "${overall_percent}" > "${TIK_PIPE}"
}
0707010000001E000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000001E00000000tik-1.2.4/usr/lib/tik/modules0707010000001F000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000002300000000tik-1.2.4/usr/lib/tik/modules/post07070100000020000081A4000000000000000000000001692B2204000008DA000000000000000000000000000000000000002C00000000tik-1.2.4/usr/lib/tik/modules/post/00-setup# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

TIK_ROOT_MNT=/var/lib/tik/root
export TIK_ROOT_MNT
prun /usr/bin/mkdir -p "${TIK_ROOT_MNT}"

# Find ESP partition
probe_partitions "${TIK_INSTALL_DEVICE}" "vfat"
if [ -z "${probedpart}" ]; then
    error "esp partition not found"
fi
TIK_ESP_PART="${probedpart}"
export TIK_ESP_PART
log "[post-setup] ESP partition is ${TIK_ESP_PART}"

# Find LUKS partition (if any) and open it
probe_partitions "${TIK_INSTALL_DEVICE}" "crypto_LUKS"
if [ -n "${probedpart}" ]; then
    TIK_CRYPT_PART="${probedpart}"
    export TIK_CRYPT_PART
    tik_progress_step "Opening encrypted root" 0
    log "[post-setup] opening encrypted partition ${TIK_CRYPT_PART}"
    prun /usr/sbin/cryptsetup luksOpen --key-file="${tik_keyfile}" "${TIK_CRYPT_PART}" aeon_root
    TIK_ROOT_DEV="/dev/mapper/aeon_root"
else
    TIK_CRYPT_PART=""
    export TIK_CRYPT_PART
    tik_progress_step "Locating root filesystem" 25
    probe_partitions "${TIK_INSTALL_DEVICE}" "btrfs" "/usr/lib/os-release"
    if [ -z "${probedpart}" ]; then
        error "root partition not found"
    fi
    TIK_ROOT_DEV="${probedpart}"
fi
export TIK_ROOT_DEV
log "[post-setup] root device is ${TIK_ROOT_DEV}"

tik_progress_step "Mounting installed system" 50

prun /usr/bin/mount -o compress=zstd:1 "${TIK_ROOT_DEV}" "${TIK_ROOT_MNT}"
prun /usr/bin/mount -t proc /proc "${TIK_ROOT_MNT}/proc"
prun /usr/bin/mount --bind /sys "${TIK_ROOT_MNT}/sys"
prun /usr/bin/mount -t securityfs securityfs "${TIK_ROOT_MNT}/sys/kernel/security"
prun /usr/bin/mount -t efivarfs efivarfs "${TIK_ROOT_MNT}/sys/firmware/efi/efivars"
prun /usr/bin/mount --bind /dev "${TIK_ROOT_MNT}/dev"
prun /usr/bin/mount --bind /run "${TIK_ROOT_MNT}/run"
prun /usr/bin/mount --bind /tmp "${TIK_ROOT_MNT}/tmp"
prun /usr/bin/mount -o compress=zstd:1,subvol=/@/.snapshots "${TIK_ROOT_DEV}" "${TIK_ROOT_MNT}/.snapshots"
prun /usr/bin/mount -o compress=zstd:1,subvol=/@/var "${TIK_ROOT_DEV}" "${TIK_ROOT_MNT}/var"

mount_etc_for_root "${TIK_ROOT_MNT}"

prun /usr/bin/mount "${TIK_ESP_PART}" "${TIK_ROOT_MNT}/boot/efi"

tik_progress_step "Installed system mounted" 100
07070100000021000081A4000000000000000000000001692B220400000469000000000000000000000000000000000000002B00000000tik-1.2.4/usr/lib/tik/modules/post/10-sicu# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

# Module that cleans up various things from a SelfInstall deployed system that otherwise can't be filtered out using repart.d config

sicu() {
    tik_progress_step "Writing fstab" 0
    log "[sicu] Writing fstab"
    prun /usr/bin/cat "${TIK_ROOT_MNT}/etc/fstab.repart" | prun tee "${TIK_ROOT_MNT}/etc/fstab"
    echo "/etc /etc none bind,x-initrd.mount 0 0" | prun tee -a "${TIK_ROOT_MNT}/etc/fstab"
    prun /usr/bin/rm /etc/fstab.repart

    tik_progress_step "Cleaning up installer user" 50
    log "[sicu] Deleting tik user"
    prun /usr/bin/chroot "${TIK_ROOT_MNT}" userdel -r tik
    log "[sicu] Enabling initial-setup"
    prun /usr/bin/rm "${TIK_ROOT_MNT}/var/lib/gdm/block-initial-setup"
    log "[sicu] Disabling tik autologin"
    prun /usr/bin/sed -i 's/DISPLAYMANAGER_AUTOLOGIN="tik"/DISPLAYMANAGER_AUTOLOGIN=""/' "${TIK_ROOT_MNT}/etc/sysconfig/displaymanager"
}

sicu
tik_progress_step "Installer user cleaned up" 100
07070100000022000081A4000000000000000000000001692B22040000238D000000000000000000000000000000000000002E00000000tik-1.2.4/usr/lib/tik/modules/post/15-encrypt# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2024 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2024 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

# 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.

generate_recoveryKey() {
    tik_progress_step "Generating recovery key" 0
    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
    log "[generate_recoveryKey] adding recovery key to roots sdbootutil user keyring"
    logging=false
    pkexec keyctl add user sdbootutil ${key} @u
    logging=true
}

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• 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"
    logging=false
    d --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>"
    logging=true
    log "[display_recoveryKey] recovery key dialogue dismissed"
}

configure_encryption() {
    tik_progress_step "Configuring encryption and boot" 20
    log "[configure_encryption] configuring cmdline, crypttab, PCR policy, fstab and populating ${TIK_ESP_PART}"

    espUUID=$(lsblk -n -r -o UUID "${TIK_ESP_PART}")
    prun /usr/bin/gawk -v espUUID="${espUUID}" -i inplace '$2 == "/boot/efi" { $1 = "UUID="espUUID } { print $0 }' "${TIK_ROOT_MNT}/etc/fstab"

    # root=UUID= cmdline definition is a hard requirement of sdbootutil for updating predictions
    rootUUID=$(lsblk -n -r -o UUID "${TIK_ROOT_DEV}")
    prun /usr/bin/sed -i -e "s,\$, root=UUID=${rootUUID}," "${TIK_ROOT_MNT}/etc/kernel/cmdline"

    # /etc/crypttab is a hard requirement of sdbootutil for updating predictions
    cryptUUID=$(lsblk -n -r -d -o UUID "${TIK_CRYPT_PART}")
    echo "aeon_root UUID=${cryptUUID} none x-initrd.attach" | prun tee "${TIK_ROOT_MNT}/etc/crypttab"

    # FIXME: Dracut gets confused by previous installations on occasion with the default config, override the problematic option temporarily
    echo "hostonly_cmdline=\"no\"" | prun tee "${TIK_ROOT_MNT}/etc/dracut.conf.d/99-tik.conf"

    # Install bootloader with sdbootutil
    prun /usr/bin/chroot "${TIK_ROOT_MNT}" sdbootutil -vv --esp-path /boot/efi --no-variables install 1>&2

    tik_progress_step "Enrolling recovery key" 40
    prun /usr/bin/chroot "${TIK_ROOT_MNT}" sdbootutil -vv --esp-path /boot/efi --method=recovery-key enroll 1>&2

    # If Default mode has been detected, configure PCR policy.
    # `etc/sysconfig/fde-tools` must be created before any calls to sdbtools,
    # because sdbootutil expects at least one of the configuration files being
    # present. See
    # https://github.com/openSUSE/sdbootutil/commit/8d3db8b01f5681c11054c37145aad3e3973a7741
    if [ "${tik_encrypt_mode}" == 0 ]; then
        tik_progress_step "Enrolling TPM key" 60
        # Explaining the chosen PCR list below
        # - 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=4,5,7,9" | prun tee "${TIK_ROOT_MNT}/etc/sysconfig/fde-tools"
        # Explaining why the following PCRs were not used
        # - 0 - UEFI firmware, will require recovery key after firmware update and is particularly painful to re-enrol
        # - 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/chroot "${TIK_ROOT_MNT}" sdbootutil -vv --esp-path /boot/efi --method=tpm2 enroll 1>&2
    else
        tik_progress_step "Setting encryption passphrase" 60
        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 "[configure_encryption] Fallback Mode - Prompting user for passphrase for ${TIK_CRYPT_PART}"

        while true; do
            logging=false
            d_opt --password --title="Set Encryption Passphrase"
            pw="${result}"
            d_opt --password --title="Type Passphrase Again"
            pw_check="${result}"
            logging=true

            # User cancelled both dialogs -> no passphrase set, just exit loop
            if [ -z "${pw}" ] && [ -z "${pw_check}" ]; then
                break
            fi

            if [ "${pw}" != "${pw_check}" ]; then
                d --warning --no-wrap --title="Passphrase did not match" --text="Please try again"
                pw=""
                pw_check=""
                continue
            fi

            prun /usr/sbin/cryptsetup luksAddKey --key-file="${tik_keyfile}" --batch-mode --force-password "${TIK_CRYPT_PART}" <<<"${pw}"
            # Initrd wasn't generated by install or enroll as no TPM interaction, so do it now.
            prun /usr/bin/chroot "${TIK_ROOT_MNT}" sdbootutil -vv --esp-path /boot/efi mkinitrd 1>&2
            break
        done
    fi

    # FIXME: Dracut gets confused by previous installations on occasion with the default config, remove override now initrd done
    prun /usr/bin/rm "${TIK_ROOT_MNT}/etc/dracut.conf.d/99-tik.conf"
    tik_progress_step "Encryption configuration complete" 80
}

generate_recoveryKey
configure_encryption
display_recoveryKey
tik_progress_step "Encryption configured" 100
07070100000023000081A4000000000000000000000001692B220400000F7B000000000000000000000000000000000000002A00000000tik-1.2.4/usr/lib/tik/modules/post/20-mig# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2024 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2024 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

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 "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

    mount_etc_for_root "${mig_dir}/mnt"

    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
fi
07070100000024000081A4000000000000000000000001692B220400000331000000000000000000000000000000000000002E00000000tik-1.2.4/usr/lib/tik/modules/post/99-cleanup# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

tik_progress_step "Cleaning up system mounts" 0

for i in proc dev tmp 'boot/efi' etc var '.snapshots' 'sys/kernel/security' 'sys/firmware/efi/efivars' sys; do
    prun-opt /usr/bin/umount "${TIK_ROOT_MNT}/$i"
done
prun-opt /usr/bin/umount -l "${TIK_ROOT_MNT}/run"
prun-opt /usr/bin/umount "${TIK_ROOT_MNT}"

if [ -n "${TIK_CRYPT_PART}" ]; then
    log "[post-cleanup] closing encrypted root for ${TIK_CRYPT_PART}"
    prun-opt /usr/sbin/cryptsetup luksClose aeon_root
fi

tik_progress_step "Finalizing boot configuration" 50
wipe_keyfile
set_boot_target

tik_progress_step "Installation complete" 100

rm -f "${TIK_PIPE}"
07070100000025000041ED000000000000000000000002692B220400000000000000000000000000000000000000000000002200000000tik-1.2.4/usr/lib/tik/modules/pre07070100000026000081A4000000000000000000000001692B2204000005EB000000000000000000000000000000000000003500000000tik-1.2.4/usr/lib/tik/modules/pre/05-setup-gnome-env# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2024 Raymond Yip
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

setup_env() {
    # Setup environment for installation, mostly setting GNOME/gsettings vars to prevent screenlocking, etc
    log "[setup_env] Setting up environment for Installation"
    gsettings set org.gnome.shell favorite-apps ['']
    gsettings set org.gnome.desktop.session idle-delay '0'
    gsettings set org.gnome.desktop.screensaver lock-enabled 'false'
    gsettings set org.gnome.desktop.screensaver user-switch-enabled 'false'
    gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type 'nothing'
    gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'
    gsettings set org.gnome.desktop.lockdown disable-lock-screen 'true'
    gsettings set org.gnome.desktop.lockdown disable-log-out 'true'
    gsettings set org.gnome.desktop.lockdown disable-printing 'true'
    gsettings set org.gnome.desktop.lockdown disable-print-setup 'true'
    gsettings set org.gnome.desktop.lockdown disable-user-switching 'true'
    gsettings set org.gnome.desktop.lockdown user-administration-disabled 'true'
    gsettings set org.gnome.software allow-updates 'false'
    gsettings set org.gnome.software download-updates 'false'
    gsettings set org.gnome.software download-updates-notify 'false'
}

setup_env
07070100000027000081A4000000000000000000000001692B22040000087C000000000000000000000000000000000000002D00000000tik-1.2.4/usr/lib/tik/modules/pre/10-welcome# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2025 SUSE LLC
# SPDX-FileCopyrightText: Copyright 2025 Richard Brown
# SPDX-FileCopyrightText: Copyright 2024 Raymond Yip
# SPDX-FileCopyrightText: Copyright 2025 Tobias Görgens

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
07070100000028000081A4000000000000000000000001692B22040000111D000000000000000000000000000000000000002D00000000tik-1.2.4/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"
            d_opt --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_notification
07070100000029000081A4000000000000000000000001692B2204000029F3000000000000000000000000000000000000002900000000tik-1.2.4/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"
    d_opt --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
                if $gui; then
                    passphrase=$(zenity --password --title="Encrypted partition (${encrypted_partition}) detected" --cancel-label="Skip") || break
                else
                    cenity passphrase --password --title="Encrypted partition (${encrypted_partition}) detected" --cancel-label="Skip" || break
                fi
                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
            d_opt --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

        mount_etc_for_root "${mig_dir}/mnt"

        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!!!205 blocks
openSUSE Build Service is sponsored by