From 8a39511aea55f9b5843432bc913ea919f89327b1 Mon Sep 17 00:00:00 2001 From: Dominik Roth Date: Mon, 19 May 2025 01:24:01 +0200 Subject: [PATCH] many fixes and additions but somethings still broken --- README.md | 1 + install.sh | 855 +++++++++++++++++------------------------------------ 2 files changed, 273 insertions(+), 583 deletions(-) diff --git a/README.md b/README.md index 0d867da..1e0711a 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ After firmware updates (UEFI/BIOS), the TPM bindings need to be updated: chmod +x 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 - Reboot the server diff --git a/install.sh b/install.sh index ca410f5..7590bcc 100755 --- a/install.sh +++ b/install.sh @@ -41,13 +41,18 @@ SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkoTn2NreAXMriOUqzyj3YoFW6jMo9B5B+ ######################################################## 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 -echo "Checking for TPM..." +echo "[+] Checking for TPM..." if [ ! -d "/sys/class/tpm/tpm0" ]; then echo "WARNING: No TPM detected!" 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 echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then @@ -72,63 +77,133 @@ if [ -z "${SSH_KEY:-}" ]; then fi # Generate secure LUKS passphrase -echo "Generating secure LUKS passphrase..." -LUKS_PASSPHRASE=$(openssl rand -base64 32) -USER_PASSWORD=$(openssl rand -base64 12) # Shorter for easier typing -echo "Generated LUKS passphrase: ${LUKS_PASSPHRASE}" -echo "Generated user password: ${USER_PASSWORD}" +echo "[+] Generating secure LUKS passphrase..." +LUKS_PASSPHRASE=$(openssl rand -base64 30) + +echo "----------------------------------------" +echo "Generated LUKS passphrase:" +echo "${LUKS_PASSPHRASE}" +echo "----------------------------------------" echo "Please save these credentials securely. You will need them for recovery." echo "Press Enter to continue..." read -# Install required packages in Rescue System (Debian) -echo "Installing required packages..." -apt-get update -apt-get install -y cryptsetup btrfs-progs mdadm +### End of user interaction -# Clear boot sectors and partition tables -echo "Clearing boot sectors and partition tables..." -# Clear MBR/GPT and first few sectors -dd if=/dev/zero of=/dev/sda bs=512 count=2048 -dd if=/dev/zero of=/dev/sdb bs=512 count=2048 -# Clear end of disk (where backup GPT might be) -dd if=/dev/zero of=/dev/sda bs=512 seek=$(($(blockdev --getsz /dev/sda) - 2048)) count=2048 -dd if=/dev/zero of=/dev/sdb bs=512 seek=$(($(blockdev --getsz /dev/sdb) - 2048)) count=2048 -sync +# Install required package +apt-get update +DEBIAN_FRONTEND=noninteractive apt-get install -y genisoimage grub-efi-amd64-bin util-linux + +# Detect disk naming scheme and set variables +echo "[+] Detecting disk configuration..." +DISKS=($(lsblk -d -n -o NAME | grep -E '^(sd[a-z]|nvme[0-9]+n[0-9]+)$' | sort)) +if [ ${#DISKS[@]} -ne 2 ]; then + 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 -echo "Creating partitions..." -# First disk -parted /dev/sda mklabel gpt -parted /dev/sda mkpart primary 1MiB 1000MiB -parted /dev/sda mkpart primary 1000MiB 100% +echo "[+] Creating partitions..." +for disk in $DISK1 $DISK2; do + # Create new GPT partition table + parted -s $disk mklabel gpt + # 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 -parted /dev/sdb mklabel gpt -parted /dev/sdb mkpart primary 1MiB 1000MiB -parted /dev/sdb mkpart primary 1000MiB 100% +# For NVMe disks, we need to append 'p' to partition numbers +if [[ "$DISK1" =~ nvme ]]; then + PART1="${DISK1}p1" + 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 -echo "Creating boot RAID1 array..." -mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1 +echo "[+] Creating boot RAID1 array..." +mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=0.90 --force --run $PART2 $PART5 mkfs.ext4 /dev/md0 # Create LUKS volumes -echo "Setting up LUKS encryption..." -echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat /dev/sda2 --type luks2 -echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat /dev/sdb2 --type luks2 +echo "[+] Setting up LUKS encryption..." +echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat $PART3 --type luks2 +echo "${LUKS_PASSPHRASE}" | cryptsetup luksFormat $PART6 --type luks2 # Open LUKS volumes -echo "Opening LUKS volumes..." -echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen /dev/sda2 root_a -echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen /dev/sdb2 root_b +echo "[+] Opening LUKS volumes..." +echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen $PART3 root_a +echo "${LUKS_PASSPHRASE}" | cryptsetup luksOpen $PART6 root_b # 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 # Create subvolumes -echo "Creating BTRFS subvolumes..." +echo "[+] Creating BTRFS subvolumes..." mount /dev/mapper/root_a /mnt btrfs subvolume create /mnt/@root btrfs subvolume create /mnt/@home @@ -136,17 +211,27 @@ btrfs subvolume create /mnt/@db chattr +C /mnt/@db # Download 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" - +echo "[+] Downloading Fedora installer..." +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 -echo "Mounting Fedora installer..." +echo "[+] Mounting Fedora installer..." 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 -echo "Creating kickstart configuration..." -cat > /mnt/ks.cfg << EOF +echo "[+] Creating kickstart configuration..." +cat > /mnt/ks.cfg << KICKSTART # Fedora Server installation with our secure setup text lang en_US.UTF-8 @@ -156,13 +241,13 @@ timezone --utc Etc/UTC # Security settings selinux --enforcing 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 sshkey --username=${FEDORA_USER} "${SSH_KEY}" -# Network -network --bootproto=dhcp --device=link --activate +# Network - let installer detect interface +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 --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 --enabled=sshd,clevis-luks-askpass,dropbear -# Partitioning -clearpart --all --initlabel --disklabel=gpt - -# Boot RAID1 -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 +# Use existing partitions +part /boot/efi --fstype=vfat --onpart=${PART1} +part /boot --fstype=ext4 --onpart=/dev/md0 +part / --fstype=btrfs --onpart=/dev/mapper/root_a # Packages %packages @@ -194,99 +273,138 @@ cryptsetup btrfs-progs mdadm dropbear +git +zsh +lsd +bat +tmux +neovim +fortune-mod +cowsay +lolcat +xclip +python3-pip %end # Post-installation %post -# Create BTRFS subvolumes -btrfs subvolume create /@root -btrfs subvolume create /@home -btrfs subvolume create /@db -chattr +C /@db +# Configure network with static IP (Hetzner dedicated server style) +cat > /etc/sysconfig/network-scripts/ifcfg-ens3 << EOF +DEVICE=ens3 +ONBOOT=yes +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 -cat > /etc/fstab << EOF -/dev/md0 /boot ext4 defaults 1 2 -/dev/mapper/root_a / btrfs subvol=@root,defaults,noatime 0 0 -/dev/mapper/root_a /home btrfs subvol=@home,defaults,noatime 0 0 -/dev/mapper/root_a /db btrfs subvol=@db,defaults,noatime,nodatacow 0 0 -EOF - -# 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 +cat > /etc/fstab << "FSTAB" +${PART1} /boot/efi vfat defaults 1 2 +/dev/md0 /boot ext4 defaults 1 2 +/dev/mapper/root_a / btrfs subvol=@root,defaults,noatime 0 0 +/dev/mapper/root_a /home btrfs subvol=@home,defaults,noatime 0 0 +/dev/mapper/root_a /db btrfs subvol=@db,defaults,noatime,nodatacow 0 0 +FSTAB # Configure dropbear for early SSH access -cat > /etc/dropbear-initramfs/config << EOF -DROPBEAR_OPTIONS="-I 60 -j -k -p 2222 -s" -EOF +mkdir -p /etc/dracut.conf.d +cat > /etc/dracut.conf.d/dropbear.conf << "DROPBEAR" +add_drivers+=" dropbear " +install_optional_items=yes +DROPBEAR -# Add SSH key to dropbear for early boot access -mkdir -p /etc/dropbear-initramfs/authorized_keys -echo "${SSH_KEY}" > /etc/dropbear-initramfs/authorized_keys -chmod 600 /etc/dropbear-initramfs/authorized_keys +# Add SSH key to dropbear +mkdir -p /etc/dropbear +echo "${SSH_KEY}" > /etc/dropbear/authorized_keys +chmod 600 /etc/dropbear/authorized_keys + +# Regenerate initramfs with dropbear +dracut -f # Set up MOTD if [ "$ENABLE_MOTD" = true ]; then - cat > /etc/motd << EOF - ${BANNER} - EOF + cat > /etc/motd << "MOTD" + :^7J5GB##&&##GPY?~: + ^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 # Configure Clevis -if [ ${#TANG_SERVERS[@]} -gt 0 ] || [ "$TPM_ENABLED" = true ]; then +if [ ${#TANG_SERVERS[@]} -gt 0 ] || [ "${TPM_ENABLED}" = true ]; then mkdir -p /etc/clevis # Build Tang servers JSON array if we have any if [ ${#TANG_SERVERS[@]} -gt 0 ]; then TANG_JSON="[" for server in "${TANG_SERVERS[@]}"; do - read -r url thumbprint <<< "$server" - TANG_JSON+="{\"url\":\"$url\",\"thumbprint\":\"$thumbprint\"}," + read -r url thumbprint <<< "\$server" + TANG_JSON+="{\"url\":\"\$url\",\"thumbprint\":\"\$thumbprint\"}," done - TANG_JSON="${TANG_JSON%,}]" # Remove trailing comma and close array + TANG_JSON="\${TANG_JSON%,}]" # Remove trailing comma and close array fi # Create Clevis config - cat > /etc/clevis/clevis.conf << EOF + cat > /etc/clevis/clevis.conf << "CLEVIS" { "t": 2, "pins": { - $([ "$TPM_ENABLED" = true ] && echo "\"tpm2\": { + $([ "${TPM_ENABLED}" = true ] && echo "\"tpm2\": { \"pcr_bank\": \"${TPM_PCR_BANK}\", \"pcr_ids\": \"${TPM_PCR_IDS}\" },") $([ ${#TANG_SERVERS[@]} -gt 0 ] && echo "\"tang\": { \"t\": 1, - \"tang\": ${TANG_JSON} + \"tang\": \${TANG_JSON} }") } } -EOF +CLEVIS # Bind LUKS volumes - clevis luks bind -d /dev/sda2 sss -c /etc/clevis/clevis.conf - clevis luks bind -d /dev/sdb2 sss -c /etc/clevis/clevis.conf + clevis luks bind -d ${PART3} sss -c /etc/clevis/clevis.conf + clevis luks bind -d ${PART6} sss -c /etc/clevis/clevis.conf else echo "No Tang servers or TPM available, skipping Clevis setup" fi # Enable required services systemctl enable clevis-luks-askpass -systemctl enable dropbear-initramfs +systemctl enable dropbear # Create TPM update script -cat > /root/update-tpm-bindings.py << 'TPMSCRIPT' +cat > /root/update-tpm-bindings.py << "TPMSCRIPT" #!/usr/bin/env python3 import subprocess import sys @@ -309,7 +427,7 @@ def get_pcr_values(): def update_bindings(): print("\nUpdating TPM bindings...") - devices = ['/dev/sda2', '/dev/sdb2'] + devices = ['${PART3}', '${PART6}'] for device in devices: print(f"\nUpdating bindings for {device}") @@ -328,7 +446,7 @@ def update_bindings(): def verify_bindings(): print("\nVerifying bindings...") - devices = ['/dev/sda2', '/dev/sdb2'] + devices = ['${PART3}', '${PART6}'] for device in devices: print(f"\nBindings for {device}:") @@ -359,484 +477,55 @@ TPMSCRIPT chmod +x /root/update-tpm-bindings.py -# Install additional packages -dnf install -y git zsh lsd bat tmux neovim fortune-mod cowsay lolcat xclip python3-pip --skip-unavailable - -# 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 +# Force SELinux relabel on next boot +touch /.autorelabel +# Cleanup +echo "[+] Now rebooting..." reboot -EOF +KICKSTART # Start Fedora installation echo "Starting Fedora installation..." 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 -e "\nInstallation started! Please wait for completion and reboot." \ No newline at end of file +echo "SSH access will be available on port 2222" + +# 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 \ No newline at end of file