nullpoint/install.sh
2025-05-18 18:31:20 +02:00

838 lines
29 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
BANNER=$(cat << "EOF"
:^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]
EOF
)
TANG_SERVERS=(
# "https://tang1.example.com your-thumbprint-1"
# "https://tang2.example.com your-thumbprint-2"
)
TPM_PCR_BANK="sha256"
TPM_PCR_IDS="0,1,2,3,4,5,6,7,8"
FEDORA_VERSION="42"
FEDORA_USER="null"
ENABLE_MOTD=true
SSH_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOkoTn2NreAXMriOUqzyj3YoFW6jMo9B5B+3R5k8yrMi dodox@dodox-ProArt"
########################################################
# Config End
########################################################
set -euo pipefail
echo -e "\nStarting installation...\n"
# Check 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."
read -p "Continue without TPM? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "Installation aborted."
exit 1
fi
echo "Proceeding without TPM..."
TPM_ENABLED=false
else
echo "TPM detected."
TPM_ENABLED=true
fi
# Check for SSH key
if [ -z "${SSH_KEY:-}" ]; then
echo "No SSH key provided. Please enter your public SSH key:"
read -r SSH_KEY
if [ -z "$SSH_KEY" ]; then
echo "Error: SSH key is required for installation"
exit 1
fi
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 "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
# Wipe disks
echo "Wiping disks..."
dd if=/dev/zero of=/dev/sda bs=1M count=100
dd if=/dev/zero of=/dev/sdb bs=1M count=100
sync
# 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%
# Second disk
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary 1MiB 1000MiB
parted /dev/sdb mkpart primary 1000MiB 100%
# Create boot RAID1
echo "Creating boot RAID1 array..."
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
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
# 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
# Create BTRFS RAID1
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..."
mount /dev/mapper/root_a /mnt
btrfs subvolume create /mnt/@root
btrfs subvolume create /mnt/@home
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"
# Mount Fedora ISO
echo "Mounting Fedora installer..."
mkdir -p /mnt/iso
mount -o loop "Fedora-Server-dvd-x86_64-${FEDORA_VERSION}-1.5.iso" /mnt/iso
# Create kickstart file
echo "Creating kickstart configuration..."
cat > /mnt/ks.cfg << EOF
# Fedora Server installation with our secure setup
text
lang en_US.UTF-8
keyboard us
timezone --utc Etc/UTC
# Security settings
selinux --enforcing
rootpw --lock
user --name=${FEDORA_USER} --groups=wheel --shell=/bin/bash --password="${USER_PASSWORD}" --lock
# SSH setup
sshkey --username=${FEDORA_USER} "${SSH_KEY}"
# Network
network --bootproto=dhcp --device=link --activate
# Bootloader
bootloader --timeout=1 --location=mbr --append="no_timer_check console=tty1 console=ttyS0,115200n8"
# 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
# Packages
%packages
@^server-product-environment
clevis
clevis-luks
clevis-tang
clevis-tpm2
tpm2-tools
tpm2-tss
cryptsetup
btrfs-progs
mdadm
dropbear
%end
# Post-installation
%post
# Create BTRFS subvolumes
btrfs subvolume create /@root
btrfs subvolume create /@home
btrfs subvolume create /@db
chattr +C /@db
# 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
# Configure dropbear for early SSH access
cat > /etc/dropbear-initramfs/config << EOF
DROPBEAR_OPTIONS="-I 60 -j -k -p 2222 -s"
EOF
# 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
# Set up MOTD
if [ "$ENABLE_MOTD" = true ]; then
cat > /etc/motd << EOF
${BANNER}
EOF
fi
# Configure Clevis
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\"},"
done
TANG_JSON="${TANG_JSON%,}]" # Remove trailing comma and close array
fi
# Create Clevis config
cat > /etc/clevis/clevis.conf << EOF
{
"t": 2,
"pins": {
$([ "$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}
}")
}
}
EOF
# 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
else
echo "No Tang servers or TPM available, skipping Clevis setup"
fi
# Enable required services
systemctl enable clevis-luks-askpass
systemctl enable dropbear-initramfs
# Create TPM update script
cat > /root/update-tpm-bindings.py << 'TPMSCRIPT'
#!/usr/bin/env python3
import subprocess
import sys
import os
def run_command(cmd):
try:
result = subprocess.run(cmd, capture_output=True, text=True, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"Error running command: {' '.join(cmd)}")
print(f"Error: {e.stderr}")
sys.exit(1)
def get_pcr_values():
print("Current PCR values:")
for i in range(0, 9):
pcr = run_command(['tpm2_pcrread', f'sha256:{i}'])
print(f"PCR {i}: {pcr.split('=')[1].strip()}")
def update_bindings():
print("\nUpdating TPM bindings...")
devices = ['/dev/sda2', '/dev/sdb2']
for device in devices:
print(f"\nUpdating bindings for {device}")
try:
# Remove existing bindings
run_command(['clevis', 'luks', 'unbind', '-d', device, '-s', '1'])
run_command(['clevis', 'luks', 'unbind', '-d', device, '-s', '2'])
# Create new bindings
run_command(['clevis', 'luks', 'bind', '-d', device, 'sss', '-c', '/etc/clevis/clevis.conf'])
print(f"Successfully updated bindings for {device}")
except subprocess.CalledProcessError as e:
print(f"Error updating bindings for {device}: {e.stderr}")
continue
def verify_bindings():
print("\nVerifying bindings...")
devices = ['/dev/sda2', '/dev/sdb2']
for device in devices:
print(f"\nBindings for {device}:")
try:
bindings = run_command(['clevis', 'luks', 'list', '-d', device])
print(bindings)
except subprocess.CalledProcessError as e:
print(f"Error verifying bindings for {device}: {e.stderr}")
continue
def main():
if os.geteuid() != 0:
print("This script must be run as root")
sys.exit(1)
print("TPM Binding Update Script")
print("========================")
get_pcr_values()
update_bindings()
verify_bindings()
print("\nUpdate complete. Please reboot to test the new bindings.")
if __name__ == "__main__":
main()
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
reboot
EOF
# 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."