838 lines
29 KiB
Bash
838 lines
29 KiB
Bash
#!/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." |