many fixes and additions but somethings still broken

This commit is contained in:
Dominik Moritz Roth 2025-05-19 01:24:01 +02:00
parent 31f1543fe5
commit 8a39511aea
2 changed files with 273 additions and 583 deletions

View File

@ -74,6 +74,7 @@ After firmware updates (UEFI/BIOS), the TPM bindings need to be updated:
chmod +x install.sh chmod +x install.sh
./install.sh ./install.sh
``` ```
- If the script tells you that no TPM is avaible you probably have to make a support ticket to get a KVM attached and toggle TPM yourself in the BIOS.
- Wait for installation to complete - Wait for installation to complete
- Reboot the server - Reboot the server

View File

@ -41,13 +41,18 @@ SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkoTn2NreAXMriOUqzyj3YoFW6jMo9B5B+
######################################################## ########################################################
set -euo pipefail set -euo pipefail
echo -e "\nStarting installation...\n" alias c="clear"
alias cls="clear"
clear
echo -e "\n$BANNER"
echo -e "\n[+] Starting installation..."
# Check for TPM # Check for TPM
echo "Checking for TPM..." echo "[+] Checking for TPM..."
if [ ! -d "/sys/class/tpm/tpm0" ]; then if [ ! -d "/sys/class/tpm/tpm0" ]; then
echo "WARNING: No TPM detected!" echo "WARNING: No TPM detected!"
echo "This system will not be able to use TPM-based boot verification." echo "This system will not be able to use TPM-based boot verification."
echo "You might need to enable TPM in the BIOS. (On Hetzner make a support ticket for KVM access)"
read -p "Continue without TPM? [y/N] " -n 1 -r read -p "Continue without TPM? [y/N] " -n 1 -r
echo echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then if [[ ! $REPLY =~ ^[Yy]$ ]]; then
@ -72,63 +77,133 @@ if [ -z "${SSH_KEY:-}" ]; then
fi fi
# Generate secure LUKS passphrase # Generate secure LUKS passphrase
echo "Generating secure LUKS passphrase..." echo "[+] Generating secure LUKS passphrase..."
LUKS_PASSPHRASE=$(openssl rand -base64 32) LUKS_PASSPHRASE=$(openssl rand -base64 30)
USER_PASSWORD=$(openssl rand -base64 12) # Shorter for easier typing
echo "Generated LUKS passphrase: ${LUKS_PASSPHRASE}" echo "----------------------------------------"
echo "Generated user password: ${USER_PASSWORD}" echo "Generated LUKS passphrase:"
echo "${LUKS_PASSPHRASE}"
echo "----------------------------------------"
echo "Please save these credentials securely. You will need them for recovery." echo "Please save these credentials securely. You will need them for recovery."
echo "Press Enter to continue..." echo "Press Enter to continue..."
read read
# Install required packages in Rescue System (Debian) ### End of user interaction
echo "Installing required packages..."
apt-get update
apt-get install -y cryptsetup btrfs-progs mdadm
# Clear boot sectors and partition tables # Install required package
echo "Clearing boot sectors and partition tables..." apt-get update
# Clear MBR/GPT and first few sectors DEBIAN_FRONTEND=noninteractive apt-get install -y genisoimage grub-efi-amd64-bin util-linux
dd if=/dev/zero of=/dev/sda bs=512 count=2048
dd if=/dev/zero of=/dev/sdb bs=512 count=2048 # Detect disk naming scheme and set variables
# Clear end of disk (where backup GPT might be) echo "[+] Detecting disk configuration..."
dd if=/dev/zero of=/dev/sda bs=512 seek=$(($(blockdev --getsz /dev/sda) - 2048)) count=2048 DISKS=($(lsblk -d -n -o NAME | grep -E '^(sd[a-z]|nvme[0-9]+n[0-9]+)$' | sort))
dd if=/dev/zero of=/dev/sdb bs=512 seek=$(($(blockdev --getsz /dev/sdb) - 2048)) count=2048 if [ ${#DISKS[@]} -ne 2 ]; then
sync echo "Error: Expected exactly 2 disks, found ${#DISKS[@]}"
exit 1
fi
# Set disk variables
DISK1="/dev/${DISKS[0]}"
DISK2="/dev/${DISKS[1]}"
# Stop any existing RAID arrays
echo "[+] Stopping any existing RAID arrays..."
mdadm --stop /dev/md0 2>/dev/null || true
# Unmount any existing partitions
echo "[+] Unmounting partitions..."
for disk in $DISK1 $DISK2; do
umount -f $disk* 2>/dev/null || true
done
# Stop any device mapper devices
echo "[+] Stopping device mapper devices..."
dmsetup remove_all 2>/dev/null || true
# Disconnect NVMe devices if present
if [[ "$DISK1" =~ nvme ]] || [[ "$DISK2" =~ nvme ]]; then
echo "Disconnecting NVMe devices..."
nvme disconnect-all
sleep 2
fi
# Zero out partition tables
echo "[+] Zeroing out partition tables..."
for disk in $DISK1 $DISK2; do
# Use blkdiscard for NVMe drives, dd for others
if [[ "$disk" =~ nvme ]]; then
blkdiscard -f $disk
else
# Zero first 2MB and last 2MB of disk
dd if=/dev/zero of=$disk bs=1M count=2 conv=fsync
dd if=/dev/zero of=$disk bs=1M seek=$(($(blockdev --getsz $disk) / 2048 - 2)) count=2 conv=fsync
fi
sync
done
# Create partitions # Create partitions
echo "Creating partitions..." echo "[+] Creating partitions..."
# First disk for disk in $DISK1 $DISK2; do
parted /dev/sda mklabel gpt # Create new GPT partition table
parted /dev/sda mkpart primary 1MiB 1000MiB parted -s $disk mklabel gpt
parted /dev/sda mkpart primary 1000MiB 100% # Create EFI partition (512MB)
parted -s $disk mkpart primary fat32 0% 512MB
# Create boot partition (1GB)
parted -s $disk mkpart primary ext4 512MB 1.5GB
# Create root partition (rest of disk)
parted -s $disk mkpart primary ext4 1.5GB 100%
# Set boot flag on first partition
parted -s $disk set 1 boot on
sync
done
# Second disk # For NVMe disks, we need to append 'p' to partition numbers
parted /dev/sdb mklabel gpt if [[ "$DISK1" =~ nvme ]]; then
parted /dev/sdb mkpart primary 1MiB 1000MiB PART1="${DISK1}p1"
parted /dev/sdb mkpart primary 1000MiB 100% PART2="${DISK1}p2"
PART3="${DISK1}p3"
PART4="${DISK2}p1"
PART5="${DISK2}p2"
PART6="${DISK2}p3"
else
PART1="${DISK1}1"
PART2="${DISK1}2"
PART3="${DISK1}3"
PART4="${DISK2}1"
PART5="${DISK2}2"
PART6="${DISK2}3"
fi
echo "Detected disks:"
echo "Disk 1: $DISK1 (will make partitions: $PART1, $PART2, $PART3)"
echo "Disk 2: $DISK2 (will make partitions: $PART4, $PART5, $PART6)"
# Create EFI partitions
echo "[+] Creating EFI partitions..."
mkfs.vfat -F 32 $PART1
mkfs.vfat -F 32 $PART4
# Create boot RAID1 # Create boot RAID1
echo "Creating boot RAID1 array..." echo "[+] Creating boot RAID1 array..."
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1 mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=0.90 --force --run $PART2 $PART5
mkfs.ext4 /dev/md0 mkfs.ext4 /dev/md0
# Create LUKS volumes # Create LUKS volumes
echo "Setting up LUKS encryption..." echo "[+] Setting up LUKS encryption..."
echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat /dev/sda2 --type luks2 echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat $PART3 --type luks2
echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat /dev/sdb2 --type luks2 echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat $PART6 --type luks2
# Open LUKS volumes # Open LUKS volumes
echo "Opening LUKS volumes..." echo "[+] Opening LUKS volumes..."
echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen /dev/sda2 root_a echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen $PART3 root_a
echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen /dev/sdb2 root_b echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen $PART6 root_b
# Create BTRFS RAID1 # Create BTRFS RAID1
echo "Creating BTRFS RAID1 filesystem..." echo "[+] Creating BTRFS RAID1 filesystem..."
mkfs.btrfs -f -d raid1 -m raid1 /dev/mapper/root_a /dev/mapper/root_b mkfs.btrfs -f -d raid1 -m raid1 /dev/mapper/root_a /dev/mapper/root_b
# Create subvolumes # Create subvolumes
echo "Creating BTRFS subvolumes..." echo "[+] Creating BTRFS subvolumes..."
mount /dev/mapper/root_a /mnt mount /dev/mapper/root_a /mnt
btrfs subvolume create /mnt/@root btrfs subvolume create /mnt/@root
btrfs subvolume create /mnt/@home btrfs subvolume create /mnt/@home
@ -136,17 +211,27 @@ btrfs subvolume create /mnt/@db
chattr +C /mnt/@db chattr +C /mnt/@db
# Download Fedora installer # Download Fedora installer
echo "Downloading Fedora installer..." echo "[+] Downloading Fedora installer..."
wget "https://download.fedoraproject.org/pub/fedora/linux/releases/${FEDORA_VERSION}/Server/x86_64/iso/Fedora-Server-dvd-x86_64-${FEDORA_VERSION}-1.5.iso" wget "https://download.fedoraproject.org/pub/fedora/linux/releases/${FEDORA_VERSION}/Server/x86_64/iso/Fedora-Server-netinst-x86_64-${FEDORA_VERSION}-1.1.iso"
# Mount Fedora ISO # Mount Fedora ISO
echo "Mounting Fedora installer..." echo "[+] Mounting Fedora installer..."
mkdir -p /mnt/iso mkdir -p /mnt/iso
mount -o loop "Fedora-Server-dvd-x86_64-${FEDORA_VERSION}-1.5.iso" /mnt/iso mount -o loop "Fedora-Server-netinst-x86_64-${FEDORA_VERSION}-1.1.iso" /mnt/iso
# Get current IP address and gateway from first non-loopback interface
echo "[+] Detecting current IP address and gateway..."
INTERFACE=$(ip -o -4 route show to default | awk '{print $5}' | head -n1)
IPV4=$(ip -4 addr show $INTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
GATEWAY=$(ip route show default | awk '/default/ {print $3}')
echo "[+] Detected network configuration:"
echo "Interface: $INTERFACE"
echo "IP: $IPV4"
echo "Gateway: $GATEWAY"
# Create kickstart file # Create kickstart file
echo "Creating kickstart configuration..." echo "[+] Creating kickstart configuration..."
cat > /mnt/ks.cfg << EOF cat > /mnt/ks.cfg << KICKSTART
# Fedora Server installation with our secure setup # Fedora Server installation with our secure setup
text text
lang en_US.UTF-8 lang en_US.UTF-8
@ -156,13 +241,13 @@ timezone --utc Etc/UTC
# Security settings # Security settings
selinux --enforcing selinux --enforcing
rootpw --lock rootpw --lock
user --name=${FEDORA_USER} --groups=wheel --shell=/bin/bash --password="${USER_PASSWORD}" --lock user --name=${FEDORA_USER} --groups=wheel --shell=/bin/bash --lock
# SSH setup # SSH setup
sshkey --username=${FEDORA_USER} "${SSH_KEY}" sshkey --username=${FEDORA_USER} "${SSH_KEY}"
# Network # Network - let installer detect interface
network --bootproto=dhcp --device=link --activate network --bootproto=static --ip=${IPV4} --netmask=255.255.255.255 --gateway=${GATEWAY} --nameserver=185.12.64.1 --nameserver=185.12.64.2 --activate
# Bootloader # Bootloader
bootloader --timeout=1 --location=mbr --append="no_timer_check console=tty1 console=ttyS0,115200n8" bootloader --timeout=1 --location=mbr --append="no_timer_check console=tty1 console=ttyS0,115200n8"
@ -170,16 +255,10 @@ bootloader --timeout=1 --location=mbr --append="no_timer_check console=tty1 cons
# Services # Services
services --enabled=sshd,clevis-luks-askpass,dropbear services --enabled=sshd,clevis-luks-askpass,dropbear
# Partitioning # Use existing partitions
clearpart --all --initlabel --disklabel=gpt part /boot/efi --fstype=vfat --onpart=${PART1}
part /boot --fstype=ext4 --onpart=/dev/md0
# Boot RAID1 part / --fstype=btrfs --onpart=/dev/mapper/root_a
part /boot --size=1000 --fstype=ext4 --label=boot
raid /boot --level=1 --device=md0 --fstype=ext4 --label=boot /dev/sda1 /dev/sdb1
# LUKS + BTRFS RAID1
part /dev/sda2 --size=2000 --grow --fstype=btrfs --label=root_a
part /dev/sdb2 --size=2000 --grow --fstype=btrfs --label=root_b
# Packages # Packages
%packages %packages
@ -194,99 +273,138 @@ cryptsetup
btrfs-progs btrfs-progs
mdadm mdadm
dropbear dropbear
git
zsh
lsd
bat
tmux
neovim
fortune-mod
cowsay
lolcat
xclip
python3-pip
%end %end
# Post-installation # Post-installation
%post %post
# Create BTRFS subvolumes # Configure network with static IP (Hetzner dedicated server style)
btrfs subvolume create /@root cat > /etc/sysconfig/network-scripts/ifcfg-ens3 << EOF
btrfs subvolume create /@home DEVICE=ens3
btrfs subvolume create /@db ONBOOT=yes
chattr +C /@db BOOTPROTO=static
IPADDR=${IPV4}
NETMASK=255.255.255.255
SCOPE="peer ${GATEWAY}"
EOF
# Create route file
cat > /etc/sysconfig/network-scripts/route-ens3 << EOF
ADDRESS0=0.0.0.0
NETMASK0=0.0.0.0
GATEWAY0=${GATEWAY}
EOF
# Reload network configuration
nmcli con reload || true
nmcli con up ens3 || true
# Update fstab # Update fstab
cat > /etc/fstab << EOF cat > /etc/fstab << "FSTAB"
/dev/md0 /boot ext4 defaults 1 2 ${PART1} /boot/efi vfat defaults 1 2
/dev/mapper/root_a / btrfs subvol=@root,defaults,noatime 0 0 /dev/md0 /boot ext4 defaults 1 2
/dev/mapper/root_a /home btrfs subvol=@home,defaults,noatime 0 0 /dev/mapper/root_a / btrfs subvol=@root,defaults,noatime 0 0
/dev/mapper/root_a /db btrfs subvol=@db,defaults,noatime,nodatacow 0 0 /dev/mapper/root_a /home btrfs subvol=@home,defaults,noatime 0 0
EOF /dev/mapper/root_a /db btrfs subvol=@db,defaults,noatime,nodatacow 0 0
FSTAB
# Save LUKS passphrase
echo "${LUKS_PASSPHRASE}" > /root/luks-passphrase.txt
chmod 600 /root/luks-passphrase.txt
# Configure sudoers
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel
# Configure SSH
cat > /etc/ssh/sshd_config.d/99-custom.conf << EOF
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
EOF
# Configure dropbear for early SSH access # Configure dropbear for early SSH access
cat > /etc/dropbear-initramfs/config << EOF mkdir -p /etc/dracut.conf.d
DROPBEAR_OPTIONS="-I 60 -j -k -p 2222 -s" cat > /etc/dracut.conf.d/dropbear.conf << "DROPBEAR"
EOF add_drivers+=" dropbear "
install_optional_items=yes
DROPBEAR
# Add SSH key to dropbear for early boot access # Add SSH key to dropbear
mkdir -p /etc/dropbear-initramfs/authorized_keys mkdir -p /etc/dropbear
echo "${SSH_KEY}" > /etc/dropbear-initramfs/authorized_keys echo "${SSH_KEY}" > /etc/dropbear/authorized_keys
chmod 600 /etc/dropbear-initramfs/authorized_keys chmod 600 /etc/dropbear/authorized_keys
# Regenerate initramfs with dropbear
dracut -f
# Set up MOTD # Set up MOTD
if [ "$ENABLE_MOTD" = true ]; then if [ "$ENABLE_MOTD" = true ]; then
cat > /etc/motd << EOF cat > /etc/motd << "MOTD"
${BANNER} :^7J5GB##&&##GPY?~:
EOF ^75B&@@@@@@&&&@@@@@@@#GJ~:
5&@@@&B5?7~^^^^^~!7YP#@@@@#!
Y##P7^ :~JB#B!
:: :
7PP?: :^~!!~^: :?PP7
:B@@B: !5B&@@@@&B5! :#@@B:
:!!: ^G@@@&BPPB@@@@G^ :!!:
:B@@@5^ ^5@@@B:
:7J7: !@@@# :&@@@~ :?J7:
J@@@5 :#@@@Y: :Y@@@B: 5@@@J
!@@@&^ ~B@@@&G55G&@@@B~ ~&@@@~
5@@@G: :7P#@@@@@@#P7: :B@@@Y
:P@@@B~ :~!77!~: ~B@@@P
Y@@@&Y^ ^5@@@@J
!G@@@&P7^ ^7P&@@@G~
!P&@@@&B? :: ?B&@@@&P!
^75#&&Y :P&&5: 5&&B57^
:^^ :P&&5: ^^:
^^
[nullpoint]
MOTD
fi fi
# Configure Clevis # Configure Clevis
if [ ${#TANG_SERVERS[@]} -gt 0 ] || [ "$TPM_ENABLED" = true ]; then if [ ${#TANG_SERVERS[@]} -gt 0 ] || [ "${TPM_ENABLED}" = true ]; then
mkdir -p /etc/clevis mkdir -p /etc/clevis
# Build Tang servers JSON array if we have any # Build Tang servers JSON array if we have any
if [ ${#TANG_SERVERS[@]} -gt 0 ]; then if [ ${#TANG_SERVERS[@]} -gt 0 ]; then
TANG_JSON="[" TANG_JSON="["
for server in "${TANG_SERVERS[@]}"; do for server in "${TANG_SERVERS[@]}"; do
read -r url thumbprint <<< "$server" read -r url thumbprint <<< "\$server"
TANG_JSON+="{\"url\":\"$url\",\"thumbprint\":\"$thumbprint\"}," TANG_JSON+="{\"url\":\"\$url\",\"thumbprint\":\"\$thumbprint\"},"
done done
TANG_JSON="${TANG_JSON%,}]" # Remove trailing comma and close array TANG_JSON="\${TANG_JSON%,}]" # Remove trailing comma and close array
fi fi
# Create Clevis config # Create Clevis config
cat > /etc/clevis/clevis.conf << EOF cat > /etc/clevis/clevis.conf << "CLEVIS"
{ {
"t": 2, "t": 2,
"pins": { "pins": {
$([ "$TPM_ENABLED" = true ] && echo "\"tpm2\": { $([ "${TPM_ENABLED}" = true ] && echo "\"tpm2\": {
\"pcr_bank\": \"${TPM_PCR_BANK}\", \"pcr_bank\": \"${TPM_PCR_BANK}\",
\"pcr_ids\": \"${TPM_PCR_IDS}\" \"pcr_ids\": \"${TPM_PCR_IDS}\"
},") },")
$([ ${#TANG_SERVERS[@]} -gt 0 ] && echo "\"tang\": { $([ ${#TANG_SERVERS[@]} -gt 0 ] && echo "\"tang\": {
\"t\": 1, \"t\": 1,
\"tang\": ${TANG_JSON} \"tang\": \${TANG_JSON}
}") }")
} }
} }
EOF CLEVIS
# Bind LUKS volumes # Bind LUKS volumes
clevis luks bind -d /dev/sda2 sss -c /etc/clevis/clevis.conf clevis luks bind -d ${PART3} sss -c /etc/clevis/clevis.conf
clevis luks bind -d /dev/sdb2 sss -c /etc/clevis/clevis.conf clevis luks bind -d ${PART6} sss -c /etc/clevis/clevis.conf
else else
echo "No Tang servers or TPM available, skipping Clevis setup" echo "No Tang servers or TPM available, skipping Clevis setup"
fi fi
# Enable required services # Enable required services
systemctl enable clevis-luks-askpass systemctl enable clevis-luks-askpass
systemctl enable dropbear-initramfs systemctl enable dropbear
# Create TPM update script # Create TPM update script
cat > /root/update-tpm-bindings.py << 'TPMSCRIPT' cat > /root/update-tpm-bindings.py << "TPMSCRIPT"
#!/usr/bin/env python3 #!/usr/bin/env python3
import subprocess import subprocess
import sys import sys
@ -309,7 +427,7 @@ def get_pcr_values():
def update_bindings(): def update_bindings():
print("\nUpdating TPM bindings...") print("\nUpdating TPM bindings...")
devices = ['/dev/sda2', '/dev/sdb2'] devices = ['${PART3}', '${PART6}']
for device in devices: for device in devices:
print(f"\nUpdating bindings for {device}") print(f"\nUpdating bindings for {device}")
@ -328,7 +446,7 @@ def update_bindings():
def verify_bindings(): def verify_bindings():
print("\nVerifying bindings...") print("\nVerifying bindings...")
devices = ['/dev/sda2', '/dev/sdb2'] devices = ['${PART3}', '${PART6}']
for device in devices: for device in devices:
print(f"\nBindings for {device}:") print(f"\nBindings for {device}:")
@ -359,484 +477,55 @@ TPMSCRIPT
chmod +x /root/update-tpm-bindings.py chmod +x /root/update-tpm-bindings.py
# Install additional packages # Force SELinux relabel on next boot
dnf install -y git zsh lsd bat tmux neovim fortune-mod cowsay lolcat xclip python3-pip --skip-unavailable touch /.autorelabel
# Set zsh as default shell for root and default user
chsh -s /bin/zsh root
chsh -s /bin/zsh ${FEDORA_USER}
# Install Oh My Zsh
su - ${FEDORA_USER} -c 'sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended'
# Install Powerlevel10k
su - ${FEDORA_USER} -c 'git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k"'
# Create .zshrc for default user
cat > /home/${FEDORA_USER}/.zshrc << 'ZSHRC'
USE_OH_MY_ZSH=true
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Path to your oh-my-zsh installation.
if [[ $USE_OH_MY_ZSH == "true" ]]; then
export ZSH="$HOME/.oh-my-zsh"
fi
ZSH_THEME="powerlevel10k/powerlevel10k"
HIST_STAMPS="dd.mm.yyyy"
if [[ $USE_OH_MY_ZSH == "true" ]]; then
plugins=(git)
source $ZSH/oh-my-zsh.sh
fi
if [[ -n $SSH_CONNECTION ]]; then
export EDITOR='vim'
else
export EDITOR='nvim'
fi
if [ $TILIX_ID ] || [ $VTE_VERSION ]; then
source /etc/profile.d/vte.sh
fi
# lang
alias ptpython="python -m ptpython"
alias ptpy="python -m ptpython"
alias py13='python3.13'
alias py12='python3.12'
alias py10='python3.10'
alias bpytop="python -m bpytop"
# python venv
alias pvcreate="python -m venv .venv"
alias pvactivate="source .venv/bin/activate"
alias pvinstall="echo 'Creating Python-venv' && pvcreate && echo 'Entering venv' && pvactivate && echo 'Upgrading pip' && pip install pip --upgrade && echo 'Installing Dependencies' && pip install -r requirements.txt && echo 'Done.'"
# qol
alias cls="clear"
alias root="sudo su --shell /bin/zsh"
alias open="xdg-open"
alias filenum="du -a | cut -d/ -f2 | sort | uniq -c | sort -nr"
alias pg="progress"
alias hist="history"
alias untar="tar -zxvf"
notify() {
$@ && echo "[DONE] $@" || echo "[ERROR] $@"
}
# grep
alias antigrep="grep -v"
alias grep2="grep -A 2 -B 2"
alias grep4="grep -A 4 -B 4"
alias grep8="grep -A 8 -B 8"
alias grep16="grep -A 16 -B 16"
alias grep32="grep -A 32 -B 32"
alias ag="alias | grep"
# packages
alias get="sudo dnf install"
alias upd="sudo dnf check-upgrade"
alias upg="sudo dnf upgrade"
alias upf="sudo flatpak update"
alias upp="pip install --upgrade pip setuptools wheel && pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U"
#clipboard
alias setclip="xclip -selection c"
alias getclip="xclip -selection c -o"
alias pwdclip="pwd | xargs echo -n | xclip -selection c"
# chars
alias c="clear"
alias t="bpytop"
alias p="ptpy"
alias h="history | grep"
alias v="nvim"
alias n="nano"
alias f="nautilus ."
alias o="open"
alias e="\d"
alias ":q"="exit"
# git
alias gs="git status"
alias gt="git log --all --graph --decorate --oneline --abbrev-commit"
alias gnoc='git shortlog -sn | cat'
alias gloc='git ls-files | while read f; do git blame -w -M -C -C --line-porcelain "$f" | grep -I "^author "; done | sort -f | uniq -ic | sort -n --reverse'
alias gpa='gaa && gc -m "." && gp -4'
# extensions
alias sudo="sudo "
alias watch="watch "
alias watch1="watch -n 1 "
# better ls via lsd
alias ls="lsd"
alias l="ls -1"
alias la="ls -A"
alias laa="ls -a"
alias lsa="ls -lA"
alias lla="ls -lA"
alias ltree="ls --tree"
alias d0="ls --tree"
alias d="ls --depth 1 --tree"
alias d1="ls --depth 1 --tree"
alias d2="ls --depth 2 --tree"
alias d3="ls --depth 3 --tree"
alias d4="ls --depth 4 --tree"
alias d5="ls --depth 5 --tree"
alias d6="ls --depth 6 --tree"
# more ls
alias lo="\ls --color=tty"
alias dtree="tree --du -h"
alias gtree="tree --du -h -F -C | grep 'G] ' --color=never"
# better cat via batcat
alias bat="bat --pager ''"
alias pat="bat --pager '' --plain"
alias lat="bat"
# more fancy batcat stuff
alias man="batman"
# tmux
alias s="tmux"
alias sa="tmux attach"
alias sn="tmux new -s"
alias san="tmux attach -t"
alias sl="tmux ls"
alias sk="tmux kill-session -t"
alias ska="tmux kill-session -a"
# Powerlevel10k initialization
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
ZSHRC
# Create .p10k.zsh for default user
cat > /home/${FEDORA_USER}/.p10k.zsh << 'P10K'
# Temporarily change options.
'builtin' 'local' '-a' 'p10k_config_opts'
[[ ! -o 'aliases' ]] || p10k_config_opts+=('aliases')
[[ ! -o 'sh_glob' ]] || p10k_config_opts+=('sh_glob')
[[ ! -o 'no_brace_expand' ]] || p10k_config_opts+=('no_brace_expand')
'builtin' 'setopt' 'no_aliases' 'no_sh_glob' 'brace_expand'
() {
emulate -L zsh
setopt no_unset extended_glob
# Unset all configuration options. This allows you to apply configiguration changes without
# restarting zsh. Edit ~/.p10k.zsh and type `source ~/.p10k.zsh`.
unset -m 'POWERLEVEL9K_*'
autoload -Uz is-at-least && is-at-least 5.1 || return
zmodload zsh/langinfo
if [[ ${langinfo[CODESET]:-} != (utf|UTF)(-|)8 ]]; then
local LC_ALL=${${(@M)$(locale -a):#*.(utf|UTF)(-|)8}[1]:-en_US.UTF-8}
fi
# The list of segments shown on the left. Fill it with the most important segments.
typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
context
dir # current directory
vcs # git status
)
typeset -g POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=(
background_jobs # presence of background jobs
direnv # direnv status (https://direnv.net/)
virtualenv # python virtual environment (https://docs.python.org/3/library/venv.html)
kubecontext # current kubernetes context (https://kubernetes.io/)
vim_shell # vim shell indicator (:sh)
vi_mode # vi mode (you don't need this if you've enabled prompt_char)
disk_usage # disk usage
)
typeset -g POWERLEVEL9K_VISUAL_IDENTIFIER_EXPANSION='${P9K_VISUAL_IDENTIFIER// }'
typeset -g POWERLEVEL9K_MODE=nerdfont-complete
typeset -g POWERLEVEL9K_ICON_BEFORE_CONTENT=
typeset -g POWERLEVEL9K_PROMPT_ADD_NEWLINE=false
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX='%242F╭─'
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_PREFIX='%242F├─'
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX='%242F╰─'
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_SUFFIX='%242F─╮'
typeset -g POWERLEVEL9K_MULTILINE_NEWLINE_PROMPT_SUFFIX='%242F─┤'
typeset -g POWERLEVEL9K_MULTILINE_LAST_PROMPT_SUFFIX='%242F─╯'
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR=' '
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_BACKGROUND=
if [[ $POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_CHAR != ' ' ]]; then
typeset -g POWERLEVEL9K_MULTILINE_FIRST_PROMPT_GAP_FOREGROUND=242
typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_FIRST_SEGMENT_END_SYMBOL='%{%}'
typeset -g POWERLEVEL9K_EMPTY_LINE_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='%{%}'
fi
typeset -g POWERLEVEL9K_LEFT_SUBSEGMENT_SEPARATOR='\uE0B1'
typeset -g POWERLEVEL9K_RIGHT_SUBSEGMENT_SEPARATOR='\uE0B3'
typeset -g POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR='\uE0B0'
typeset -g POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR='\uE0B2'
typeset -g POWERLEVEL9K_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL='\uE0B0'
typeset -g POWERLEVEL9K_RIGHT_PROMPT_FIRST_SEGMENT_START_SYMBOL='\uE0B2'
typeset -g POWERLEVEL9K_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=''
typeset -g POWERLEVEL9K_RIGHT_PROMPT_LAST_SEGMENT_END_SYMBOL=''
typeset -g POWERLEVEL9K_EMPTY_LINE_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
#################################[ os_icon: os identifier ]##################################
typeset -g POWERLEVEL9K_OS_ICON_FOREGROUND=232
typeset -g POWERLEVEL9K_OS_ICON_BACKGROUND=7
typeset -g POWERLEVEL9K_OS_ICON_CONTENT_EXPANSION='%B${P9K_CONTENT// }'
################################[ prompt_char: prompt symbol ]################################
typeset -g POWERLEVEL9K_PROMPT_CHAR_BACKGROUND=
typeset -g POWERLEVEL9K_PROMPT_CHAR_OK_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=76
typeset -g POWERLEVEL9K_PROMPT_CHAR_ERROR_{VIINS,VICMD,VIVIS,VIOWR}_FOREGROUND=196
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIINS_CONTENT_EXPANSION=' ' #''
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VICMD_CONTENT_EXPANSION=' ' #''
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIVIS_CONTENT_EXPANSION=' ' #''
typeset -g POWERLEVEL9K_PROMPT_CHAR_{OK,ERROR}_VIOWR_CONTENT_EXPANSION=' ' #'▶'
typeset -g POWERLEVEL9K_PROMPT_CHAR_OVERWRITE_STATE=true
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_LAST_SEGMENT_END_SYMBOL=
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_PROMPT_FIRST_SEGMENT_START_SYMBOL=
typeset -g POWERLEVEL9K_PROMPT_CHAR_LEFT_{LEFT,RIGHT}_WHITESPACE=
##################################[ dir: current directory ]##################################
typeset -g POWERLEVEL9K_DIR_BACKGROUND=234
typeset -g POWERLEVEL9K_DIR_FOREGROUND=39
typeset -g POWERLEVEL9K_SHORTEN_STRATEGY=truncate_to_unique
typeset -g POWERLEVEL9K_SHORTEN_DELIMITER=
typeset -g POWERLEVEL9K_DIR_SHORTENED_FOREGROUND=103
typeset -g POWERLEVEL9K_DIR_ANCHOR_FOREGROUND=39
typeset -g POWERLEVEL9K_DIR_ANCHOR_BOLD=false
local anchor_files=(
.bzr
.citc
.git
.hg
.node-version
.python-version
.ruby-version
.shorten_folder_marker
.svn
.terraform
CVS
Cargo.toml
composer.json
go.mod
package.json
)
typeset -g POWERLEVEL9K_SHORTEN_FOLDER_MARKER="(${(j:|:)anchor_files})"
typeset -g POWERLEVEL9K_SHORTEN_DIR_LENGTH=1
typeset -g POWERLEVEL9K_DIR_MAX_LENGTH=80
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS=40
typeset -g POWERLEVEL9K_DIR_MIN_COMMAND_COLUMNS_PCT=50
typeset -g POWERLEVEL9K_DIR_HYPERLINK=false
typeset -g POWERLEVEL9K_DIR_SHOW_WRITABLE=true
typeset -g POWERLEVEL9K_DIR_CLASSES=()
#####################################[ vcs: git status ]######################################
# Version control system colors.
typeset -g POWERLEVEL9K_VCS_CLEAN_FOREGROUND=10
typeset -g POWERLEVEL9K_VCS_CLEAN_BACKGROUND=235 #2
typeset -g POWERLEVEL9K_VCS_MODIFIED_FOREGROUND=10
typeset -g POWERLEVEL9K_VCS_MODIFIED_BACKGROUND=235 #3
typeset -g POWERLEVEL9K_VCS_UNTRACKED_FOREGROUND=10
typeset -g POWERLEVEL9K_VCS_UNTRACKED_BACKGROUND=235 #2
typeset -g POWERLEVEL9K_VCS_CONFLICTED_FOREGROUND=9
typeset -g POWERLEVEL9K_VCS_CONFLICTED_BACKGROUND=235 #3
typeset -g POWERLEVEL9K_VCS_LOADING_FOREGROUND=15
typeset -g POWERLEVEL9K_VCS_LOADING_BACKGROUND=255
# Branch icon. Set this parameter to '\uF126 ' for the popular Powerline branch icon. Disabled because bug
typeset -g POWERLEVEL9K_VCS_BRANCH_ICON='\uF126 '
POWERLEVEL9K_VCS_BRANCH_ICON=${(g::)POWERLEVEL9K_VCS_BRANCH_ICON}
# Untracked files icon. It's really a question mark, your font isn't broken.
# Change the value of this parameter to show a different icon.
typeset -g POWERLEVEL9K_VCS_UNTRACKED_ICON='?'
POWERLEVEL9K_VCS_UNTRACKED_ICON=${(g::)POWERLEVEL9K_VCS_UNTRACKED_ICON}
# Formatter for Git status.
#
# Example output: master ⇣42⇡42 *42 merge ~42 +42 !42 ?42.
#
# You can edit the function to customize how Git status looks.
#
# VCS_STATUS_* parameters are set by gitstatus plugin. See reference:
# https://github.com/romkatv/gitstatus/blob/master/gitstatus.plugin.zsh.
function my_git_formatter() {
emulate -L zsh
if [[ -n $P9K_CONTENT ]]; then
# If P9K_CONTENT is not empty, use it. It's either "loading" or from vcs_info (not from
# gitstatus plugin). VCS_STATUS_* parameters are not available in this case.
typeset -g my_git_format=$P9K_CONTENT
return
fi
# Styling for different parts of Git status.
local meta='' #'%7F' # white foreground
local clean='' #'%0F' # black foreground
local modified='' #'%0F' # black foreground
local untracked='' #'%0F' # black foreground
local conflicted='' #'%1F' # red foreground
local res
local where # branch or tag
if [[ -n $VCS_STATUS_LOCAL_BRANCH ]]; then
res+="${clean}${POWERLEVEL9K_VCS_BRANCH_ICON}"
where=${(V)VCS_STATUS_LOCAL_BRANCH}
elif [[ -n $VCS_STATUS_TAG ]]; then
res+="${meta}#"
where=${(V)VCS_STATUS_TAG}
fi
# If local branch name or tag is at most 32 characters long, show it in full.
# Otherwise show the first 12 … the last 12.
(( $#where > 32 )) && where[13,-13]="…"
res+="${clean}${where//\%/%%}" # escape %
# Display the current Git commit if there is no branch or tag.
# Tip: To always display current Git commit, remove `[[ -z $where ]] &&` from the next line.
[[ -z $where ]] && res+="${meta}@${clean}${VCS_STATUS_COMMIT[1,8]}"
# Show tracking branch name if it differs from local branch.
if [[ -n ${VCS_STATUS_REMOTE_BRANCH:#$VCS_STATUS_LOCAL_BRANCH} ]]; then
res+="${meta}:${clean}${(V)VCS_STATUS_REMOTE_BRANCH//\%/%%}" # escape %
fi
# ⇣42 if behind the remote.
(( VCS_STATUS_COMMITS_BEHIND )) && res+=" ${clean}${VCS_STATUS_COMMITS_BEHIND}"
# ⇡42 if ahead of the remote; no leading space if also behind the remote: ⇣42⇡42.
(( VCS_STATUS_COMMITS_AHEAD && !VCS_STATUS_COMMITS_BEHIND )) && res+=" "
(( VCS_STATUS_COMMITS_AHEAD )) && res+="${clean}${VCS_STATUS_COMMITS_AHEAD}"
# *42 if have stashes.
(( VCS_STATUS_STASHES )) && res+=" ${clean}*${VCS_STATUS_STASHES}"
# 'merge' if the repo is in an unusual state.
[[ -n $VCS_STATUS_ACTION ]] && res+=" ${conflicted}${VCS_STATUS_ACTION}"
# ~42 if have merge conflicts.
(( VCS_STATUS_NUM_CONFLICTED )) && res+=" ${conflicted}~${VCS_STATUS_NUM_CONFLICTED}"
# +42 if have staged changes.
(( VCS_STATUS_NUM_STAGED )) && res+=" ${modified}+${VCS_STATUS_NUM_STAGED}"
# !42 if have unstaged changes.
(( VCS_STATUS_NUM_UNSTAGED )) && res+=" ${modified}!${VCS_STATUS_NUM_UNSTAGED}"
# ?42 if have untracked files. It's really a question mark, your font isn't broken.
# See POWERLEVEL9K_VCS_UNTRACKED_ICON above if you want to use a different icon.
# Remove the next line if you don't want to see untracked files at all.
(( VCS_STATUS_NUM_UNTRACKED )) && res+=" ${untracked}${POWERLEVEL9K_VCS_UNTRACKED_ICON}${VCS_STATUS_NUM_UNTRACKED}"
typeset -g my_git_format=$res
}
functions -M my_git_formatter 2>/dev/null
# Disable the default Git status formatting.
typeset -g POWERLEVEL9K_VCS_DISABLE_GITSTATUS_FORMATTING=true
# Install our own Git status formatter.
typeset -g POWERLEVEL9K_VCS_CONTENT_EXPANSION='${$((my_git_formatter()))+${my_git_format}}'
# Enable counters for staged, unstaged, etc.
typeset -g POWERLEVEL9K_VCS_{STAGED,UNSTAGED,UNTRACKED,CONFLICTED,COMMITS_AHEAD,COMMITS_BEHIND}_MAX_NUM=-1
# Custom icon.
# typeset -g POWERLEVEL9K_VCS_VISUAL_IDENTIFIER_EXPANSION='⭐'
# Custom prefix.
# typeset -g POWERLEVEL9K_VCS_PREFIX='on '
# Show status of repositories of these types. You can add svn and/or hg if you are
# using them. If you do, your prompt may become slow even when your current directory
# isn't in an svn or hg reposotiry.
typeset -g POWERLEVEL9K_VCS_BACKENDS=(git)
##################################[ disk_usgae: disk usage ]##################################
typeset -g POWERLEVEL9K_DISK_USAGE_WARNING_LEVEL=95
typeset -g POWERLEVEL9K_DISK_USAGE_CRITICAL_LEVEL=98
typeset -g POWERLEVEL9K_DISK_USAGE_ONLY_WARNING=true
###########[ vi_mode: vi mode (you don't need this if you've enabled prompt_char) ]###########
typeset -g POWERLEVEL9K_VI_MODE_FOREGROUND=0
typeset -g POWERLEVEL9K_VI_COMMAND_MODE_STRING=NORMAL
typeset -g POWERLEVEL9K_VI_MODE_NORMAL_BACKGROUND=2
typeset -g POWERLEVEL9K_VI_VISUAL_MODE_STRING=VISUAL
typeset -g POWERLEVEL9K_VI_MODE_VISUAL_BACKGROUND=4
typeset -g POWERLEVEL9K_VI_OVERWRITE_MODE_STRING=OVERTYPE
typeset -g POWERLEVEL9K_VI_MODE_OVERWRITE_BACKGROUND=3
typeset -g POWERLEVEL9K_VI_INSERT_MODE_STRING=
typeset -g POWERLEVEL9K_VI_MODE_INSERT_FOREGROUND=8
######################################[ ram: free RAM ]#######################################
# RAM color.
# typeset -g POWERLEVEL9K_RAM_FOREGROUND=0
# typeset -g POWERLEVEL9K_RAM_BACKGROUND=3
# Custom icon.
# typeset -g POWERLEVEL9K_RAM_VISUAL_IDENTIFIER_EXPANSION='⭐'
#####################################[ swap: used swap ]######################################
# Swap color.
# typeset -g POWERLEVEL9K_SWAP_FOREGROUND=0
# typeset -g POWERLEVEL9K_SWAP_BACKGROUND=3
# Custom icon.
# typeset -g POWERLEVEL9K_SWAP_VISUAL_IDENTIFIER_EXPANSION='⭐'
######################################[ load: CPU load ]######################################
typeset -g POWERLEVEL9K_LOAD_WHICH=5
##################################[ context: user@hostname ]##################################
typeset -g POWERLEVEL9K_CONTEXT_ROOT_FOREGROUND=1
typeset -g POWERLEVEL9K_CONTEXT_ROOT_BACKGROUND=0
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_FOREGROUND=3
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_BACKGROUND=0
typeset -g POWERLEVEL9K_CONTEXT_FOREGROUND=3
typeset -g POWERLEVEL9K_CONTEXT_BACKGROUND=0
typeset -g POWERLEVEL9K_CONTEXT_ROOT_TEMPLATE='%n@%m'
typeset -g POWERLEVEL9K_CONTEXT_{REMOTE,REMOTE_SUDO}_TEMPLATE='%n@%m'
typeset -g POWERLEVEL9K_CONTEXT_TEMPLATE='%n'
###[ virtualenv: python virtual environment (https://docs.python.org/3/library/venv.html) ]###
typeset -g POWERLEVEL9K_VIRTUALENV_SHOW_PYTHON_VERSION=false
typeset -g POWERLEVEL9K_VIRTUALENV_{LEFT,RIGHT}_DELIMITER=
#############[ kubecontext: current kubernetes context (https://kubernetes.io/) ]#############
typeset -g POWERLEVEL9K_KUBECONTEXT_SHOW_ON_COMMAND='kubectl|helm|kubens|kubectx|oc'
typeset -g POWERLEVEL9K_KUBECONTEXT_CLASSES=(
# '*prod*' PROD # These values are examples that are unlikely
# '*test*' TEST # to match your needs. Customize them as needed.
'*' DEFAULT)
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_FOREGROUND=7
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_BACKGROUND=5
typeset -g POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION=
POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${P9K_KUBECONTEXT_CLOUD_CLUSTER:-${P9K_KUBECONTEXT_NAME}}'
POWERLEVEL9K_KUBECONTEXT_DEFAULT_CONTENT_EXPANSION+='${${:-/$P9K_KUBECONTEXT_NAMESPACE}:#/default}'
####################################[ time: current time ]####################################
typeset -g POWERLEVEL9K_TIME_FORMAT='%D{%H:%M:%S}'
typeset -g POWERLEVEL9K_TIME_UPDATE_ON_COMMAND=false
typeset -g POWERLEVEL9K_TRANSIENT_PROMPT=off
typeset -g POWERLEVEL9K_INSTANT_PROMPT=verbose
typeset -g POWERLEVEL9K_DISABLE_HOT_RELOAD=true
(( ! $+functions[p10k] )) || p10k reload
}
(( ${#p10k_config_opts} )) && setopt ${p10k_config_opts[@]}
'builtin' 'unset' 'p10k_config_opts'
P10K
# Set correct permissions
chown -R ${FEDORA_USER}:${FEDORA_USER} /home/${FEDORA_USER}/.oh-my-zsh
chown ${FEDORA_USER}:${FEDORA_USER} /home/${FEDORA_USER}/.zshrc
chown ${FEDORA_USER}:${FEDORA_USER} /home/${FEDORA_USER}/.p10k.zsh
# Install Python packages
pip3 install --user ptpython bpytop
%end
# Cleanup
echo "[+] Now rebooting..."
reboot reboot
EOF KICKSTART
# Start Fedora installation # Start Fedora installation
echo "Starting Fedora installation..." echo "Starting Fedora installation..."
echo "This will take some time. Please wait..." echo "This will take some time. Please wait..."
/mnt/iso/isolinux/vmlinuz initrd=/mnt/iso/isolinux/initrd.img inst.ks=file:///mnt/ks.cfg inst.stage2=hd:LABEL=Fedora-S-42-1-5-x86_64 echo "SSH access will be available on port 2222"
echo -e "\nInstallation started! Please wait for completion and reboot."
# Create ALL needed directories
mkdir -p /mnt/boot
mount /dev/md0 /mnt/boot
mkdir -p /mnt/boot/efi
mount $PART1 /mnt/boot/efi
mkdir -p /mnt/boot/efi/EFI/fedora
mkdir -p /mnt/boot/grub
mkdir -p /mnt/boot/installer
mkdir -p /mnt/iso
# Now mount and copy
cp /mnt/iso/images/pxeboot/vmlinuz /mnt/boot/installer/
cp /mnt/iso/images/pxeboot/initrd.img /mnt/boot/installer/
cp /mnt/ks.cfg /mnt/boot/installer/
# Get actual ISO label
ISO_LABEL=$(isoinfo -d -i "Fedora-Server-netinst-x86_64-${FEDORA_VERSION}-1.1.iso" | grep "Volume id:" | cut -d: -f2 | tr -d ' ')
# Set IP-related kernel boot params for installer
KERNEL_NET_PARAMS="ip=${IPV4}::${GATEWAY}:255.255.255.255::ens3:none nameserver=185.12.64.1 nameserver=185.12.64.2"
cat > /mnt/boot/grub/grub.cfg << "GRUBCFG"
set timeout=5
set default=0
menuentry "Fedora Installer" {
linux /installer/vmlinuz inst.ks=file:///installer/ks.cfg inst.stage2=hd:LABEL=${ISO_LABEL} ${KERNEL_NET_PARAMS} inst.sshd inst.ssh.port=2222 inst.ssh.key=${SSH_KEY}
initrd /installer/initrd.img
}
GRUBCFG
# Install GRUB EFI
grub-install --target=x86_64-efi --boot-directory=/mnt/boot --efi-directory=/mnt/boot/efi --removable $DISK1
grub-install --target=x86_64-efi --boot-directory=/mnt/boot --efi-directory=/mnt/boot/efi --removable $DISK2
umount /mnt/boot/efi
umount /mnt/boot
umount /mnt/iso
#reboot