Anaconda provisioning: Autoinstall working now #4

Merged
obel1x merged 6 commits from :main into main 2026-04-21 19:16:14 +02:00
13 changed files with 238 additions and 61 deletions
@@ -1,7 +1,7 @@
[Desktop Entry]
Comment[de_DE]=
Comment=
Exec=/opt/sys_config/system_setup/logon_script.sh
Exec=xterm -maximized -e /opt/sys_config/system_setup/logon_script.sh
GenericName[de_DE]=
GenericName=
Icon=application-x-shellscript
@@ -10,6 +10,7 @@ Name[de_DE]=User Logon Script
Name=User Logon Script
Path=/opt/sys_config/system_setup
StartupNotify=true
Hidden=false
Terminal=true
TerminalOptions=
Type=Application
@@ -0,0 +1,9 @@
[Profile0]
Name=default
IsRelative=1
Path=default
Default=1
[General]
StartWithLastProfile=1
Version=2
+109
View File
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: Daniel Pätzold
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# Will prepare local mozilla and thunderbird folders with given tar.files
#
import sys
import subprocess
import certifi
import tarfile
import shutil
import os
from os import environ
# See https://pypi.org/project/webdavclient3/
# needs pip install webdavclient3
from webdav3.client import Client
#Variables
thunderbird_tar = os.path.dirname(__file__) + '/thunderbird.tar.zst'
firefox_tar = os.path.dirname(__file__) + '/firefox.tar.zst'
firefoxhome_path = environ['HOME'] + "/.config/mozilla/firefox"
firefoxhome_profile_src = os.path.dirname(__file__) + '/profiles_ff.ini'
firefoxhome_profile_dst = firefoxhome_path + '/profiles.ini'
#Check Env
if not 'DAVTOKEN_USER' in environ:
print("Error: Script cannot be executed standalone and needs a prereserved Environment. Quit.")
sys.exit(1)
options = {
'webdav_hostname': "https://nextcloud.obel1x.de/remote.php/dav/files/unbrot",
'webdav_login': environ['DAVTOKEN_USER'],
'webdav_password': environ['DAVTOKEN_PASS']
}
client = Client(options)
#client.verify = False # To not check SSL certificates (Default = True)
if 'PROFILE_FIREFOX_RESET_LOCAL' in environ:
#Remove all files in ~/mozilla
print("Removing " + firefoxhome_path)
shutil.rmtree(firefoxhome_path)
print("Extracting " + firefox_tar + " to " + firefoxhome_path)
if not os.path.exists(firefoxhome_path): # Recreate
os.makedirs(firefoxhome_path)
tar = tarfile.open(firefox_tar)
tar.extractall(path = firefoxhome_path, filter = 'data')
tar.close()
shutil.copyfile(firefoxhome_profile_src, firefoxhome_profile_dst) # Copy initial profiles.ini to dir
print("Done.")
#Firefox first profile setup
if 'PROFILE_FIREFOX_SRC' in environ: # Check and setup mozilla
pathstr = environ['PROFILE_FIREFOX_SRC'] + "/default"
if not client.check(pathstr):
print("Path " + pathstr + " was not found on Server. Creating it.")
i = 0
while i >= 0: #Dive into subfolders of string
i = pathstr.find("/", i + 1)
if i >= 0:
#print("/" + pathstr[:i])
if not client.check(pathstr[:i]):
client.execute_request("mkdir", "/" + pathstr[:i])
#print("/" + pathstr)
client.execute_request("mkdir", "/" + pathstr)
print("Done.")
#Check and create local Folder
if not os.path.exists(environ['PROFILE_FIREFOX_DST'] + "/default"):
os.makedirs(environ['PROFILE_FIREFOX_DST'] + "/default")
#First sync to initialise sync-db
print("Call " + environ['SYSCONFIGPATH'] + "/system_setup/mozilla_starter.sh firefox sync")
retstr = subprocess.call(['sh', environ['SYSCONFIGPATH'] + '/system_setup/mozilla_starter.sh', 'firefox', 'sync'])
#Extract empty firefox profile to Folder
print("Extracting " + firefox_tar + " to " + environ['PROFILE_FIREFOX_DST'])
tar = tarfile.open(firefox_tar)
tar.extractall(path=environ['PROFILE_FIREFOX_DST'],filter='data')
tar.close()
print("Done.")
#Next sync will be executed by logon script
#Thunderbird first profile setup
if 'PROFILE_TB_SRC' in environ: # Check and setup mozilla
pathstr = environ['PROFILE_TB_SRC'] + "/default"
if not client.check(pathstr):
print("Path " + pathstr + " was not found on Server. Creating it.")
i = 0
while i >= 0: #Dive into subfolders of string
i = pathstr.find("/", i + 1)
if i >= 0:
#print("/" + pathstr[:i])
if not client.check(pathstr[:i]):
client.execute_request("mkdir", "/" + pathstr[:i])
#print("/" + pathstr)
client.execute_request("mkdir", "/" + pathstr)
print("Done.")
#Check and create local Folder
if not os.path.exists(environ['PROFILE_TB_DST'] + "/default"):
os.makedirs(environ['PROFILE_TB_DST'] + "/default")
#First sync to initialise sync-db
print("Call " + environ['SYSCONFIGPATH'] + "/system_setup/mozilla_starter.sh thunderbird sync")
retstr = subprocess.call(['sh', environ['SYSCONFIGPATH'] + '/system_setup/mozilla_starter.sh', 'thunderbird', 'sync'])
#Extract empty firefox profile to Folder
print("Extracting " + thunderbird_tar + " to " + environ['PROFILE_TB_DST'])
tar = tarfile.open(thunderbird_tar)
tar.extractall(path=environ['PROFILE_TB_DST'],filter='data')
tar.close()
print("Done.")
#Next sync will be executed by logon script
sys.exit(0)
+56 -16
View File
@@ -1,8 +1,15 @@
#Basic settings:
graphical
text
skipx
cdrom
# Configure installation method
url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64"
repo --name=fedora-updates --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f43&arch=x86_64" --cost=0
repo --name=fedora-cisco-openh264 --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-cisco-openh264-43&arch=x86_64" --install
repo --name=rpmfusion-free --mirrorlist="https://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-43&arch=x86_64"
repo --name=rpmfusion-free-updates --mirrorlist="https://mirrors.rpmfusion.org/mirrorlist?repo=free-fedora-updates-released-43&arch=x86_64" --cost=0
repo --name=rpmfusion-nonfree --mirrorlist="https://mirrors.rpmfusion.org/mirrorlist?repo=nonfree-fedora-43&arch=x86_64"
repo --name=rpmfusion-nonfree-updates --mirrorlist="https://mirrors.rpmfusion.org/mirrorlist?repo=nonfree-fedora-updates-released-43&arch=x86_64" --cost=0
# Keyboard layouts
keyboard --vckeymap=de-nodeadkeys --xlayouts='de (nodeadkeys)'
@@ -11,23 +18,55 @@ lang de_DE.UTF-8
# System timezone
timezone Europe/Berlin --utc
%pre --log=/root/ks-pre.log
mkdir /mnt/anaconda_pre
mount -L OEMDRV /mnt/anaconda_pre
/bin/sh /mnt/anaconda_pre/ks_base_profiles/basic_pre_script.inc
%end
%packages
#@^kde-desktop-environment
@core
@admin-tools
@domain-client
@system-tools
@kde-desktop
@kde-media
@kde-spin-initial-setup
@libreoffice
@office
@sound-and-video
@vlc
#@development-tools
#@editors
#@firefox
#@kde-apps
#@kde-desktop
#@kde-media
#@kde-spin-initial-setup
#@libreoffice
#@office
#@sound-and-video
#@vlc
@firefox
thunderbird
openssh-server
bash
sudo
gocryptfs
htop
mc
mediawriter
python-pip
pykickstart
xrdp
xorgxrdp
plasma-workspace-x11
xterm
flatpak
btrfs-assistant
btrbk
ktorrent
cadaver
kdevelop
git
ffmpeg
-kpat
-kmines
#Needed by SSSD
oddjob-mkhomedir
nss-pam-ldapd
%end
# System authorization information
@@ -36,8 +75,6 @@ authselect enable-feature with-fingerprint
# Run the Setup Agent on first boot
firstboot --enable
timesource --ntp-server=_gateway
# Generated using Blivet version 3.12.1
ignoredisk --only-use=sda
# Partition clearing information
@@ -50,5 +87,8 @@ autopart --type=btrfs
rootpw --iscrypted $y$j9T$jpKVkxaFqL6GH6GAgB0Yb/$oc.rfZgnHNlTAIj/boJeI.ZFf1QHvMF7fymZww9bzE3
%post --log=/root/ks-post.log
/bin/sh /mnt/tmp/system_setup/setup_system_full.sh install
mkdir /opt/sys_config
mount -L OEMDRV /opt/sys_config
/bin/sh /opt/sys_config/system_setup/setup_system_full.sh install
umount /opt/sys_config
%end
+4 -4
View File
@@ -24,16 +24,16 @@ fi
# Usually, the pre section is run in the sh- shell, the OEMDRV will be mountet at /mnt/tmp
# So we need to check if this is the case
FQFILENAME="/mnt/tmp/ks_base_profiles/basic_pre_script.inc"
FQFILENAME="/mnt/anaconda_pre/ks_base_profiles/basic_pre_script.inc"
if [ ! -f ${FQFILENAME} ]; then
echo "* Error finding the expeted Directory/File structure: Missing File"
echo "${FQFILENAME}"
echo "* Please check to run from Kickstart- Installation, or mount the OEMDRV with this File in /mnt/tmp before."
echo "* Please check to run from Kickstart- Installation, or mount the OEMDRV with this File in /mnt/anaconda_pre before."
exit 1
fi
# Check if there is a Partition OEMDRV and on which Drive
source /mnt/tmp/system_setup/setup_system.conf
/mnt/anaconda_pre/system_setup/setup_system.inc.sh
OEMDRVINFO=$(blkid | grep 'LABEL="OEMDRV"')
if [ "${OEMDRVINFO}." == "." ] ; then
echo "* Error: Required partition with label 'OEMDRV' is not found."
@@ -78,7 +78,7 @@ if [ "${REMPARTS}." != "." ]; then
for (( i=0; i<${#REMPART}; i++ )); do
CHAR="${REMPART:$i:1}"
if [[ "${CHAR}" =~ [0-9] ]]; then
PARTNR+="${CHAR}" # Append if it's a digit
PARTNR+="${CHAR}" # Append if its a digit
else
PARTNR="" # Reset if a non-digit is encountered
fi
+1 -2
View File
@@ -14,11 +14,10 @@ cd /etc
sudo rm -f -r /etc/skel
sudo tar -xf ${SRCFILE}
if [ $? -eq 0 ]; then
echo "Sucessfully wrote skel new"
echo "Sucessfully wrote skel."
sudo chown -R root:root /etc/skel
sudo setfacl -R -m u::rwX,g::rX,o::rX /etc/skel
else
echo "Something went wrong, please check Output"
fi
cd ${EXECDIR}
+1
View File
@@ -57,6 +57,7 @@ if [ "$EUID" -ne 0 ]; then
#End of Sync Folder for nextcloud client
#Firefox Profiles of the User
export PROFILE_FIREFOX_RESET_LOCAL="true" # Set this to wipe ~/.mozilla each time if you don't want users to setup their own firefox profile
export PROFILE_FIREFOX_SRC="mozilla_profiles/firefox"
export PROFILE_FIREFOX_DST="${DECRYPTEDDATADIR}/firefox"
Regular → Executable
View File
+52 -35
View File
@@ -21,7 +21,7 @@
# - Make it check for what to do each time so that it can be called every startup
# - Make it callable from anakondas kickstart post- script to setup system at first run
# (kickstart post-script must be non-interactive, while first start with systemd can have a service bounf to tty for getting user-input too)
# - Detect System Environement and make User-Logon- Setup Start after first Logon
# - Detect System Environment and make User-Logon- Setup Start after first Logon
# Supported: Cinnamon, KDE
# - Not needed: Import Firefox-Cert from IPA automatically at first run to system -> Somehow this is not needed any more, firefox will work from scratch!
@@ -32,26 +32,28 @@
# TODO write a doc!
#Load Sytem Settings
#Load Sytem Settings - MUST BE SOURCED, otherwise Variables will not be available
source $(dirname "$0")/setup_system.inc.sh
# TODO
# Install System settings to installed system
# read system settings from that file
##Step 1 - Install at System boot
# Setup needed boot- service
firstrun_prepare()
{
#Checking Service
if [[ -z ${FIRSTRUN_SERVICENAME} ]]; then
echo "Error in Config, no Servicename found. Please check your Environment for FIRSTRUN_SERVICENAME."
env
exit 1
fi
FIRSTRUN_SERVICESTATUS=$( systemctl is-enabled ${FIRSTRUN_SERVICENAME} )
echo "Current Service Status of ${FIRSTRUN_SERVICENAME} is ${FIRSTRUN_SERVICESTATUS}"
if [ ${FIRSTRUN_SERVICESTATUS} != "enabled" ]; then
if [ "${FIRSTRUN_SERVICESTATUS}." != "enabled." ]; then
echo "Installing Service at ${FIRSTRUN_SCRIPTPATH}/${FIRSTRUN_SERVICENAME}"
( cat <<EOF | sudo tee ${FIRSTRUN_SCRIPTPATH}/${FIRSTRUN_SERVICENAME}
[Unit]
Description=First time setup of this PC
After=NetworkManager-wait-online.service
Before=sssd.service
Before=systemd-user-sessions.service nss-user-lookup.target
Wants=nss-user-lookup.target
ConditionKernelCommandLine=!inst.nofirstrun
[Service]
@@ -65,7 +67,7 @@ ExecStart=/bin/sh ${SCRIPTPATH}/${SCRIPTNAME} firstrun_run
#ExecStart=-/sbin/agetty --noclear -n -l "/bin/sh ${SCRIPTPATH}/${SCRIPTNAME} firstrun_run" %I 38400
# user interaction in tty8
StandardInput=tty
TTYPath=/dev/tty8
TTYPath=/dev/tty2
TTYReset=yes
TTYVHangup=yes
@@ -88,7 +90,10 @@ firstrun_remove()
#Do updates
upgrade_interactive()
{
check_root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Not running as root, cannot continue."
return 1
fi
dnf upgrade --refresh
#Check if restart is needed
dnf needs-restarting
@@ -109,29 +114,36 @@ fi
}
#Software needed and additional stuff
# Moved all to syc_client_software.sh to make it more interactive
install_sw()
{
check_root
dnf install -y mc htop ipa-client thunderbird pykickstart gocryptfs mediawriter
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Not running as root, cannot continue."
return 1
fi
#Set default Umask 0077
sudo cp -f /etc/login.defs /etc/login.defs_backup_${CDATEC8}_${CTIMEC6}
( sed 's/^UMASK.*022$/UMASK\t077/' /etc/login.defs | sudo tee /etc/login.defs ) >/dev/null
#Append OEMDRV mount to SYSCONFIGPATH in fstab
echo "LABEL=OEMDRV ${SYSCONFIGPATH} btrfs noatime,nodiratime,nofail 0 0" >> /etc/fstab
}
ipa_register_host()
{
#Integrate this PC into Domain
chvt 8
chvt 2
#Check if IPA is already Configured
echo "Checking for existing IPA- Setup."
if ( grep -q "${FQDN}" /etc/ipa/default.conf ); then
echo "IPA is already installed, skipping setup."
chvt 1
return 0
fi
echo "IPA not jet installed, doing Setup."
check_root
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Not running as root, cannot continue."
return 1
fi
#Serialnr of this device
echo "This PC is called ${FQDN} and will join Domain ${DOMAIN}"
#Always set determined hostname - see setup_system.conf
@@ -147,22 +159,41 @@ echo -n "Please Enter your Domain- Userid: "
read IPAUSERID
echo -n "Please Enter your Domain- Password: "
read -s IPAPASSWD
INSTCMD="ipa-client-install -U --mkhomedir --force-join --no-ntp --principal=${IPAUSERID} --domain=${DOMAIN} --server=${SERVERFQDN_IPA} --hostname=${FQDN} -w ${IPAPASSWD}"
echo ${INSTCMD}
echo ""
INSTCMD="ipa-client-install -U --mkhomedir --force-join --no-ntp --principal=${IPAUSERID} --domain=${DOMAIN} --server=${SERVERFQDN_IPA} -w ${IPAPASSWD}"
echo "${INSTCMD/${IPAPASSWD}/*PASSWD*}"
${INSTCMD}
if [ $? -ne 0 ]; then
echo "Some Error. Please check what went wrong and redo."
return 1
fi
echo "The PC was integrated into the Domain. You should now be able to Logon with tha User. If not, restart SSSD- Service and check the Logs."
echo "The PC was integrated into the Domain. You should now be able to Logon with tha User. If not, check the Logs at /var/sssd."
echo ""
echo "ADVISE: for the First Logon, you may use Console (Using e.g. CONTROL+ALT+F3) - as maybe you will be prompted for Changing your Password there"
echo "which may not work on graphical logon. After that works, use CONTROL+ALT+F2 (or F7) to get back to the graphical logon."
echo ""
read -n 1 -s -r -p "Press any key to continue."
chvt 1
echo ""
}
prepare_skel()
{
if [ "$EUID" -ne 0 ]; then
echo "ERROR: Not running as root, cannot continue."
return 1
fi
#Copy and extrakt Skel-Archive
#Include: Autostart for Getting WEB-DAV-Token if not there
#+An empty Firefox Profile - already integrated into domain with one single Startup-Page: Get Token
# https://nextcloud.obel1x.de/settings/user/security
#
#File was created with from Draft-Folder and then transferred to NC
#tar -I 'zstd -9' -cf system_setup.tar.zst ~/system_setup
#
./setup_skel.sh
}
test_tty()
{
#Use TTY3 and show it
@@ -175,23 +206,10 @@ test_tty()
echo "========== END ========"
}
prepare_skel()
{
check_root
#Copy and extrakt Skel-Archive
#Include: Autostart for Getting WEB-DAV-Token if not there
#+An empty Firefox Profile - already integrated into domain with one single Startup-Page: Get Token
# https://nextcloud.obel1x.de/settings/user/security
#
#File was created with from Draft-Folder and then transferred to NC
#tar -I 'zstd -9' -cf system_setup.tar.zst ~/system_setup
#
./setup_skel.sh
}
### MAIN
case $1 in
'install')
# Executed after base installation (anaconda post script)
echo "Mode: Install"
install_sw
prepare_skel
@@ -204,7 +222,6 @@ case $1 in
firstrun_remove
;;
'firstrun_run')
# test_tty
ipa_register_host
echo "========== END FIRSTRUN-SERVICE ========"
;;
Binary file not shown.
+1
View File
@@ -37,6 +37,7 @@ mkdir -p ${TEMPDIR}
#Install or update Nextcloud com.nextcloud.desktopclient.nextcloud
echo "Update or install Nextcloud client"
/usr/bin/flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
/usr/bin/flatpak install -y --or-update --noninteractive flathub com.nextcloud.desktopclient.nextcloud && echo "Done Update/Install of Nextcloud."
#Sync Files