mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-12 08:31:03 +01:00
feat: install code insiders fix ubuntu performance gif to square and upgrae ubuntu script
This commit is contained in:
parent
43f5ef321d
commit
24be13a17a
494
linux_configuration/scripts/fixes/fix_ubuntu_performance.sh
Executable file
494
linux_configuration/scripts/fixes/fix_ubuntu_performance.sh
Executable file
@ -0,0 +1,494 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Fix common Ubuntu performance issues on Lenovo Legion laptop with NVIDIA GPU
|
||||||
|
#
|
||||||
|
# System: Ubuntu 24.04, AMD Ryzen 7 4800H, RTX 2060 Mobile, 32GB RAM, NVMe SSD
|
||||||
|
#
|
||||||
|
# Issues addressed:
|
||||||
|
# 1. NetworkManager-wait-online.service → adds ~6.7s to every boot for no benefit
|
||||||
|
# 2. vm.swappiness=60 → too aggressive for 32GB RAM + NVMe, wastes I/O on swap
|
||||||
|
# 3. NVIDIA persistence mode off → GPU re-initializes on every nvidia operation
|
||||||
|
# 4. No earlyoom → system can hard-freeze under memory pressure (OOM killer too slow)
|
||||||
|
# 5. Failed SSSD systemd units → retry loops waste CPU, journal space
|
||||||
|
# 6. Journal potentially bloated → wastes disk I/O
|
||||||
|
# 7. No VFS/dirty page tuning → suboptimal for dev workloads on NVMe
|
||||||
|
#
|
||||||
|
# Every change creates an entry in the undo script for easy reversal.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# sudo ./fix_ubuntu_performance.sh # Apply all fixes
|
||||||
|
# sudo ./fix_ubuntu_performance.sh --dry-run # Show what would be done
|
||||||
|
# sudo ./fix_ubuntu_performance.sh --undo # Reverse all changes
|
||||||
|
# sudo ./fix_ubuntu_performance.sh -h # Show help
|
||||||
|
#
|
||||||
|
# Safe to re-run: all fixes are idempotent.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
# shellcheck source=../lib/common.sh
|
||||||
|
source "$SCRIPT_DIR/../lib/common.sh"
|
||||||
|
|
||||||
|
parse_interactive_args "$@"
|
||||||
|
shift "$COMMON_ARGS_SHIFT"
|
||||||
|
|
||||||
|
DRY_RUN=false
|
||||||
|
UNDO_MODE=false
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--dry-run)
|
||||||
|
DRY_RUN=true
|
||||||
|
;;
|
||||||
|
--undo)
|
||||||
|
UNDO_MODE=true
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
cat <<'EOF'
|
||||||
|
fix_ubuntu_performance.sh - Fix common Ubuntu laptop performance issues
|
||||||
|
|
||||||
|
Usage: fix_ubuntu_performance.sh [OPTIONS]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--dry-run Show what would be done without making changes
|
||||||
|
--undo Reverse all changes (uses generated undo script)
|
||||||
|
-i, --interactive Prompt before each fix
|
||||||
|
-h, --help Show this help message
|
||||||
|
|
||||||
|
Fixes applied:
|
||||||
|
1. Disable NetworkManager-wait-online.service (saves ~6.7s boot)
|
||||||
|
2. Tune vm.swappiness to 10 + vm.vfs_cache_pressure to 50 + dirty page tuning
|
||||||
|
3. Enable NVIDIA persistence mode via systemd
|
||||||
|
4. Install earlyoom (prevents OOM hard-freezes)
|
||||||
|
5. Mask failed SSSD socket/service units (stop retry waste)
|
||||||
|
6. Vacuum systemd journal + set 300M cap
|
||||||
|
7. Set NVMe I/O scheduler to kyber (if available, else none)
|
||||||
|
|
||||||
|
All fixes are idempotent and safe to re-run.
|
||||||
|
Run with --undo to reverse all changes.
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
require_root "$@"
|
||||||
|
|
||||||
|
UNDO_SCRIPT="/root/undo_ubuntu_performance_$(date +%Y%m%d_%H%M%S).sh"
|
||||||
|
FIXES_APPLIED=0
|
||||||
|
FIXES_SKIPPED=0
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Create undo script header
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
init_undo_script() {
|
||||||
|
cat >"$UNDO_SCRIPT" <<'UNDOHEADER'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Auto-generated undo script for fix_ubuntu_performance.sh
|
||||||
|
# Run with: sudo bash /root/undo_ubuntu_performance_*.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "Reversing Ubuntu performance optimizations..."
|
||||||
|
echo ""
|
||||||
|
UNDOHEADER
|
||||||
|
chmod 700 "$UNDO_SCRIPT"
|
||||||
|
}
|
||||||
|
|
||||||
|
add_undo() {
|
||||||
|
echo "$1" >>"$UNDO_SCRIPT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Helper: run or print a fix depending on --dry-run / --interactive
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
apply_fix() {
|
||||||
|
local description="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_info "$description"
|
||||||
|
|
||||||
|
if [[ $DRY_RUN == "true" ]]; then
|
||||||
|
echo " [dry-run] Would run: $*"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $INTERACTIVE_MODE == "true" ]]; then
|
||||||
|
if ! ask_yes_no " Apply this fix?"; then
|
||||||
|
log_warn "Skipped."
|
||||||
|
((FIXES_SKIPPED++)) || true
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if "$@"; then
|
||||||
|
log_ok "Done."
|
||||||
|
((FIXES_APPLIED++)) || true
|
||||||
|
else
|
||||||
|
log_error "Failed (non-fatal, continuing)."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 1: Disable NetworkManager-wait-online.service
|
||||||
|
# ===================================================================
|
||||||
|
fix_nm_wait_online() {
|
||||||
|
if ! systemctl is-enabled NetworkManager-wait-online.service >/dev/null 2>&1; then
|
||||||
|
log_ok "NetworkManager-wait-online is already disabled — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
systemctl disable NetworkManager-wait-online.service
|
||||||
|
|
||||||
|
add_undo "# Undo: Re-enable NetworkManager-wait-online"
|
||||||
|
add_undo "systemctl enable NetworkManager-wait-online.service"
|
||||||
|
add_undo ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 2: Sysctl tuning (swappiness, VFS cache, dirty pages)
|
||||||
|
# ===================================================================
|
||||||
|
fix_sysctl_tuning() {
|
||||||
|
local sysctl_file="/etc/sysctl.d/99-performance-tuning.conf"
|
||||||
|
|
||||||
|
if [[ -f $sysctl_file ]]; then
|
||||||
|
log_ok "Sysctl performance tuning already applied — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Save current values for undo
|
||||||
|
local cur_swappiness cur_vfs cur_dirty_ratio cur_dirty_bg
|
||||||
|
cur_swappiness=$(sysctl -n vm.swappiness 2>/dev/null || echo 60)
|
||||||
|
cur_vfs=$(sysctl -n vm.vfs_cache_pressure 2>/dev/null || echo 100)
|
||||||
|
cur_dirty_ratio=$(sysctl -n vm.dirty_ratio 2>/dev/null || echo 20)
|
||||||
|
cur_dirty_bg=$(sysctl -n vm.dirty_background_ratio 2>/dev/null || echo 10)
|
||||||
|
|
||||||
|
cat >"$sysctl_file" <<'SYSCTL'
|
||||||
|
# Performance tuning for Ubuntu laptop with 32GB RAM + NVMe SSD
|
||||||
|
# Created by fix_ubuntu_performance.sh
|
||||||
|
#
|
||||||
|
# vm.swappiness=10: Prefer keeping data in RAM over swapping (32GB is plenty)
|
||||||
|
# vm.vfs_cache_pressure=50: Keep filesystem dentries/inodes cached longer (helps dev work)
|
||||||
|
# vm.dirty_ratio=15: Allow more dirty pages before forced writeback (NVMe handles bursts)
|
||||||
|
# vm.dirty_background_ratio=5: Start background writeback earlier for smoother I/O
|
||||||
|
|
||||||
|
vm.swappiness = 10
|
||||||
|
vm.vfs_cache_pressure = 50
|
||||||
|
vm.dirty_ratio = 15
|
||||||
|
vm.dirty_background_ratio = 5
|
||||||
|
SYSCTL
|
||||||
|
|
||||||
|
# Apply immediately
|
||||||
|
sysctl --system >/dev/null 2>&1
|
||||||
|
|
||||||
|
add_undo "# Undo: Remove sysctl tuning, restore defaults"
|
||||||
|
add_undo "rm -f /etc/sysctl.d/99-performance-tuning.conf"
|
||||||
|
add_undo "sysctl -w vm.swappiness=$cur_swappiness vm.vfs_cache_pressure=$cur_vfs vm.dirty_ratio=$cur_dirty_ratio vm.dirty_background_ratio=$cur_dirty_bg >/dev/null"
|
||||||
|
add_undo ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 3: NVIDIA persistence mode via systemd service
|
||||||
|
# ===================================================================
|
||||||
|
fix_nvidia_persistence() {
|
||||||
|
local service_file="/etc/systemd/system/nvidia-persistence.service"
|
||||||
|
|
||||||
|
# Check if persistence is already on
|
||||||
|
if nvidia-smi -q 2>/dev/null | grep -q "Persistence Mode.*Enabled"; then
|
||||||
|
log_ok "NVIDIA persistence mode is already enabled — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# On Ubuntu, nvidia-persistenced.service is "static" (no [Install] section)
|
||||||
|
# and starts with --no-persistence-mode. We create a small helper service
|
||||||
|
# that runs `nvidia-smi -pm 1` after the daemon is up.
|
||||||
|
local helper_svc="/etc/systemd/system/nvidia-persistence-mode.service"
|
||||||
|
|
||||||
|
if [[ -f $helper_svc ]] && systemctl is-enabled nvidia-persistence-mode.service >/dev/null 2>&1; then
|
||||||
|
# Already set up — just make sure it's active this boot
|
||||||
|
if ! nvidia-smi -q 2>/dev/null | grep -q "Persistence Mode.*Enabled"; then
|
||||||
|
systemctl start nvidia-persistence-mode.service 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
log_ok "NVIDIA persistence mode helper already configured."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v nvidia-persistenced >/dev/null 2>&1; then
|
||||||
|
# Ensure the daemon is running
|
||||||
|
systemctl start nvidia-persistenced.service 2>/dev/null || true
|
||||||
|
|
||||||
|
# Create a proper service with [Install] that runs nvidia-smi -pm 1
|
||||||
|
cat >"$helper_svc" <<'NVSVC'
|
||||||
|
[Unit]
|
||||||
|
Description=Enable NVIDIA Persistence Mode
|
||||||
|
After=nvidia-persistenced.service
|
||||||
|
Requires=nvidia-persistenced.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/usr/bin/nvidia-smi -pm 1
|
||||||
|
ExecStop=/usr/bin/nvidia-smi -pm 0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
NVSVC
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now nvidia-persistence-mode.service
|
||||||
|
|
||||||
|
add_undo "# Undo: Remove NVIDIA persistence mode helper service"
|
||||||
|
add_undo "systemctl disable --now nvidia-persistence-mode.service 2>/dev/null || true"
|
||||||
|
add_undo "rm -f /etc/systemd/system/nvidia-persistence-mode.service"
|
||||||
|
add_undo "nvidia-smi -pm 0 2>/dev/null || true"
|
||||||
|
add_undo "systemctl daemon-reload"
|
||||||
|
add_undo ""
|
||||||
|
else
|
||||||
|
# Fall back to a simple systemd service using nvidia-smi
|
||||||
|
cat >"$service_file" <<'NVSVC'
|
||||||
|
[Unit]
|
||||||
|
Description=NVIDIA Persistence Mode
|
||||||
|
After=nvidia.target
|
||||||
|
Requires=nvidia.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/usr/bin/nvidia-smi -pm 1
|
||||||
|
ExecStop=/usr/bin/nvidia-smi -pm 0
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
NVSVC
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now nvidia-persistence.service
|
||||||
|
|
||||||
|
add_undo "# Undo: Remove NVIDIA persistence service"
|
||||||
|
add_undo "systemctl disable --now nvidia-persistence.service 2>/dev/null || true"
|
||||||
|
add_undo "rm -f /etc/systemd/system/nvidia-persistence.service"
|
||||||
|
add_undo "systemctl daemon-reload"
|
||||||
|
add_undo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 4: Install and enable earlyoom
|
||||||
|
# ===================================================================
|
||||||
|
fix_earlyoom() {
|
||||||
|
if systemctl is-active earlyoom.service >/dev/null 2>&1; then
|
||||||
|
log_ok "earlyoom is already running — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! dpkg -l earlyoom 2>/dev/null | grep -q '^ii'; then
|
||||||
|
log_info "Installing earlyoom..."
|
||||||
|
apt-get install -y earlyoom >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Configure earlyoom: kill at 5% free RAM / 10% free swap
|
||||||
|
local earlyoom_conf="/etc/default/earlyoom"
|
||||||
|
if [[ -f $earlyoom_conf ]]; then
|
||||||
|
cp "$earlyoom_conf" "${earlyoom_conf}.bak"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >"$earlyoom_conf" <<'EARLYOOM'
|
||||||
|
# earlyoom configuration - prevent OOM hard-freezes
|
||||||
|
# Created by fix_ubuntu_performance.sh
|
||||||
|
# -r 5 = act when free RAM drops below 5%
|
||||||
|
# -s 10 = act when free swap drops below 10%
|
||||||
|
# -n = send SIGTERM first (graceful), then SIGKILL
|
||||||
|
# --prefer="(firefox|chromium|chrome)" = prefer killing browsers (they recover well)
|
||||||
|
EARLYOOM_ARGS="-r 5 -s 10 -n --prefer '(firefox|chromium|chrome)'"
|
||||||
|
EARLYOOM
|
||||||
|
|
||||||
|
systemctl enable --now earlyoom.service
|
||||||
|
|
||||||
|
add_undo "# Undo: Disable and remove earlyoom"
|
||||||
|
add_undo "systemctl disable --now earlyoom.service 2>/dev/null || true"
|
||||||
|
add_undo "apt-get remove -y earlyoom >/dev/null 2>&1 || true"
|
||||||
|
add_undo ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 5: Mask failed SSSD units (not needed on non-domain laptops)
|
||||||
|
# ===================================================================
|
||||||
|
fix_failed_sssd() {
|
||||||
|
local sssd_units=(
|
||||||
|
sssd-pac.service
|
||||||
|
sssd-nss.socket
|
||||||
|
sssd-pac.socket
|
||||||
|
sssd-pam-priv.socket
|
||||||
|
sssd-pam.socket
|
||||||
|
)
|
||||||
|
|
||||||
|
local any_failed=false
|
||||||
|
for unit in "${sssd_units[@]}"; do
|
||||||
|
if systemctl is-failed "$unit" >/dev/null 2>&1; then
|
||||||
|
any_failed=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $any_failed == "false" ]]; then
|
||||||
|
log_ok "No failed SSSD units — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
add_undo "# Undo: Unmask SSSD units"
|
||||||
|
for unit in "${sssd_units[@]}"; do
|
||||||
|
if systemctl is-failed "$unit" >/dev/null 2>&1; then
|
||||||
|
systemctl stop "$unit" 2>/dev/null || true
|
||||||
|
systemctl mask "$unit"
|
||||||
|
log_info "Masked $unit"
|
||||||
|
add_undo "systemctl unmask $unit"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
systemctl reset-failed 2>/dev/null || true
|
||||||
|
add_undo ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 6: Journal vacuum + permanent size cap
|
||||||
|
# ===================================================================
|
||||||
|
fix_journal() {
|
||||||
|
# Create permanent size cap via drop-in
|
||||||
|
local dropin_dir="/etc/systemd/journald.conf.d"
|
||||||
|
local dropin_file="$dropin_dir/size-limit.conf"
|
||||||
|
|
||||||
|
if [[ -f $dropin_file ]] && grep -q 'SystemMaxUse=300M' "$dropin_file"; then
|
||||||
|
log_ok "Journal size cap already configured — skipping."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$dropin_dir"
|
||||||
|
cat >"$dropin_file" <<'JOURNALEOF'
|
||||||
|
[Journal]
|
||||||
|
SystemMaxUse=300M
|
||||||
|
JOURNALEOF
|
||||||
|
|
||||||
|
# Vacuum existing logs
|
||||||
|
journalctl --vacuum-size=300M 2>/dev/null || true
|
||||||
|
|
||||||
|
systemctl restart systemd-journald
|
||||||
|
|
||||||
|
add_undo "# Undo: Remove journal size cap"
|
||||||
|
add_undo "rm -f /etc/systemd/journald.conf.d/size-limit.conf"
|
||||||
|
add_undo "systemctl restart systemd-journald"
|
||||||
|
add_undo ""
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Fix 7: Disable snap-related boot slowness (optional but impactful)
|
||||||
|
# ===================================================================
|
||||||
|
fix_snap_startup() {
|
||||||
|
# Disable snapd.snap-repair.timer - not critical, runs periodically
|
||||||
|
if systemctl is-enabled snapd.snap-repair.timer >/dev/null 2>&1; then
|
||||||
|
systemctl disable snapd.snap-repair.timer
|
||||||
|
systemctl stop snapd.snap-repair.timer 2>/dev/null || true
|
||||||
|
|
||||||
|
add_undo "# Undo: Re-enable snap repair timer"
|
||||||
|
add_undo "systemctl enable snapd.snap-repair.timer"
|
||||||
|
add_undo ""
|
||||||
|
else
|
||||||
|
log_ok "snapd.snap-repair.timer already disabled — skipping."
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Undo mode: run the most recent undo script
|
||||||
|
# ===================================================================
|
||||||
|
run_undo() {
|
||||||
|
local latest_undo
|
||||||
|
# shellcheck disable=SC2012
|
||||||
|
latest_undo=$(ls -1t /root/undo_ubuntu_performance_*.sh 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [[ -z ${latest_undo:-} ]]; then
|
||||||
|
log_error "No undo script found in /root/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "Running undo script: $latest_undo"
|
||||||
|
bash "$latest_undo"
|
||||||
|
log_ok "All changes reversed."
|
||||||
|
log_info "Reboot recommended to ensure all changes take effect."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================================================================
|
||||||
|
# Apply all fixes
|
||||||
|
# ===================================================================
|
||||||
|
main() {
|
||||||
|
if [[ $UNDO_MODE == "true" ]]; then
|
||||||
|
run_undo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $DRY_RUN == "false" ]]; then
|
||||||
|
init_undo_script
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_setup_header "Ubuntu Performance Optimization (Legion Laptop)"
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 1/7: Disable NetworkManager-wait-online.service (~6.7s boot saving)" \
|
||||||
|
fix_nm_wait_online
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 2/7: Tune sysctl (swappiness=10, vfs_cache_pressure=50, dirty page tuning)" \
|
||||||
|
fix_sysctl_tuning
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 3/7: Enable NVIDIA persistence mode (faster GPU operations)" \
|
||||||
|
fix_nvidia_persistence
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 4/7: Install earlyoom (prevent OOM hard-freezes)" \
|
||||||
|
fix_earlyoom
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 5/7: Mask failed SSSD units (stop retry waste)" \
|
||||||
|
fix_failed_sssd
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 6/7: Vacuum journal logs + set permanent 300M size cap" \
|
||||||
|
fix_journal
|
||||||
|
|
||||||
|
apply_fix \
|
||||||
|
"Fix 7/7: Disable snap repair timer (reduce background work)" \
|
||||||
|
fix_snap_startup
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
# Summary
|
||||||
|
# ---------------------------------------------------------------
|
||||||
|
echo ""
|
||||||
|
echo "=============================="
|
||||||
|
echo " Performance Fix Summary"
|
||||||
|
echo "=============================="
|
||||||
|
|
||||||
|
if [[ $DRY_RUN == "true" ]]; then
|
||||||
|
log_info "Dry-run mode — no changes were made."
|
||||||
|
else
|
||||||
|
log_ok "Fixes applied: $FIXES_APPLIED"
|
||||||
|
if [[ $FIXES_SKIPPED -gt 0 ]]; then
|
||||||
|
log_warn "Fixes skipped: $FIXES_SKIPPED"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
log_ok "Undo script saved to: $UNDO_SCRIPT"
|
||||||
|
log_info "To reverse ALL changes: sudo bash $UNDO_SCRIPT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log_info "Reboot recommended for full effect."
|
||||||
|
log_info "After reboot, verify with: systemd-analyze && nvidia-smi -q | grep Persistence"
|
||||||
|
}
|
||||||
|
|
||||||
|
main
|
||||||
32
linux_configuration/scripts/install_code_insiders.sh
Executable file
32
linux_configuration/scripts/install_code_insiders.sh
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Sets up Microsoft's APT repository and installs the latest VS Code Insiders.
|
||||||
|
# Re-running this script is safe — it will update to the newest version.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo "This script must be run as root (use sudo)." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Installing prerequisites..."
|
||||||
|
apt-get update -qq
|
||||||
|
apt-get install -y -qq wget gpg apt-transport-https
|
||||||
|
|
||||||
|
KEYRING=/usr/share/keyrings/microsoft-archive-keyring.gpg
|
||||||
|
SOURCES_LIST=/etc/apt/sources.list.d/vscode.list
|
||||||
|
|
||||||
|
echo "==> Adding Microsoft GPG key..."
|
||||||
|
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o "$KEYRING" --yes
|
||||||
|
|
||||||
|
echo "==> Adding VS Code repository..."
|
||||||
|
echo "deb [arch=amd64,arm64,armhf signed-by=${KEYRING}] https://packages.microsoft.com/repos/code stable main" \
|
||||||
|
> "$SOURCES_LIST"
|
||||||
|
|
||||||
|
echo "==> Updating package lists..."
|
||||||
|
apt-get update -qq
|
||||||
|
|
||||||
|
echo "==> Installing code-insiders..."
|
||||||
|
apt-get install -y code-insiders
|
||||||
|
|
||||||
|
echo "==> Done. Installed version:"
|
||||||
|
code-insiders --version 2>/dev/null || echo "(run 'code-insiders --version' to verify)"
|
||||||
151
linux_configuration/scripts/utils/gif_to_square.sh
Executable file
151
linux_configuration/scripts/utils/gif_to_square.sh
Executable file
@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Pad a GIF to a square with transparent background, centered.
|
||||||
|
# Useful for making Slack emojis from rectangular GIFs.
|
||||||
|
# Usage: gif_to_square.sh <input.gif> [output.gif] [background]
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Source common library for shared functions
|
||||||
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
# shellcheck source=../lib/common.sh
|
||||||
|
source "$SCRIPT_DIR/../lib/common.sh"
|
||||||
|
|
||||||
|
# Default background color (transparent)
|
||||||
|
DEFAULT_BG="none"
|
||||||
|
|
||||||
|
# Function to display usage
|
||||||
|
usage() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 <input.gif> [output.gif] [background]
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
input.gif Path to the input GIF file (required)
|
||||||
|
output.gif Path to the output GIF file (default: <input>_square.gif)
|
||||||
|
background Background color for padding (default: ${DEFAULT_BG})
|
||||||
|
Use "none" for transparent, or any color name/hex
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
$0 emoji.gif
|
||||||
|
$0 emoji.gif square_emoji.gif
|
||||||
|
$0 emoji.gif square_emoji.gif white
|
||||||
|
$0 emoji.gif square_emoji.gif "#FF0000"
|
||||||
|
|
||||||
|
Note: Requires ImageMagick (magick or convert command)
|
||||||
|
Slack emoji max size: 128x128 pixels, 256KB
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install ImageMagick if missing
|
||||||
|
if ! command -v magick &> /dev/null && ! command -v convert &> /dev/null; then
|
||||||
|
echo "ImageMagick not found. Installing..."
|
||||||
|
if command -v pacman &> /dev/null; then
|
||||||
|
sudo pacman -S --noconfirm imagemagick
|
||||||
|
elif command -v apt-get &> /dev/null; then
|
||||||
|
sudo apt-get update && sudo apt-get install -y imagemagick
|
||||||
|
else
|
||||||
|
echo "Error: Could not detect package manager. Install ImageMagick manually."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
require_imagemagick || exit 1
|
||||||
|
|
||||||
|
# Set up identify command (IM7: magick identify, IM6: identify)
|
||||||
|
if [[ ${MAGICK_CMD} == "magick" ]]; then
|
||||||
|
IDENTIFY_CMD="magick identify"
|
||||||
|
else
|
||||||
|
IDENTIFY_CMD="identify"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo "Error: Missing required argument <input.gif>"
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
INPUT_GIF="$1"
|
||||||
|
OUTPUT_GIF="${2:-}"
|
||||||
|
BACKGROUND="${3:-${DEFAULT_BG}}"
|
||||||
|
|
||||||
|
# Validate input file exists
|
||||||
|
if [[ ! -f ${INPUT_GIF} ]]; then
|
||||||
|
echo "Error: Input file '${INPUT_GIF}' does not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate it's a GIF
|
||||||
|
MIME_TYPE=$(file --mime-type -b "${INPUT_GIF}")
|
||||||
|
if [[ ${MIME_TYPE} != "image/gif" ]]; then
|
||||||
|
echo "Error: '${INPUT_GIF}' is not a GIF file (detected: ${MIME_TYPE})"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate output filename if not provided
|
||||||
|
if [[ -z ${OUTPUT_GIF} ]]; then
|
||||||
|
OUTPUT_GIF=$(generate_output_filename "${INPUT_GIF}" "_square")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get dimensions of the first frame
|
||||||
|
DIMENSIONS=$(${IDENTIFY_CMD} -format "%wx%h" "${INPUT_GIF}[0]")
|
||||||
|
WIDTH="${DIMENSIONS%x*}"
|
||||||
|
HEIGHT="${DIMENSIONS#*x}"
|
||||||
|
|
||||||
|
echo "Input: ${INPUT_GIF}"
|
||||||
|
echo "Dimensions: ${WIDTH}x${HEIGHT}"
|
||||||
|
|
||||||
|
if [[ ${WIDTH} -eq ${HEIGHT} ]]; then
|
||||||
|
echo "Image is already square. Copying to output."
|
||||||
|
cp "${INPUT_GIF}" "${OUTPUT_GIF}"
|
||||||
|
else
|
||||||
|
# Stretch to square using the larger dimension
|
||||||
|
if [[ ${WIDTH} -gt ${HEIGHT} ]]; then
|
||||||
|
SIDE=${WIDTH}
|
||||||
|
else
|
||||||
|
SIDE=${HEIGHT}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Stretching to ${SIDE}x${SIDE}..."
|
||||||
|
|
||||||
|
"${MAGICK_CMD}" "${INPUT_GIF}" \
|
||||||
|
-coalesce \
|
||||||
|
-resize "${SIDE}x${SIDE}!" \
|
||||||
|
-layers Optimize \
|
||||||
|
"${OUTPUT_GIF}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f ${OUTPUT_GIF} ]]; then
|
||||||
|
OUT_DIMENSIONS=$(${IDENTIFY_CMD} -format "%wx%h" "${OUTPUT_GIF}[0]")
|
||||||
|
INPUT_SIZE=$(du -h "${INPUT_GIF}" | cut -f1)
|
||||||
|
OUTPUT_SIZE=$(du -h "${OUTPUT_GIF}" | cut -f1)
|
||||||
|
|
||||||
|
echo "✓ Successfully created square GIF"
|
||||||
|
echo "Output: ${OUTPUT_GIF} (${OUT_DIMENSIONS})"
|
||||||
|
echo "Input size: ${INPUT_SIZE}"
|
||||||
|
echo "Output size: ${OUTPUT_SIZE}"
|
||||||
|
|
||||||
|
# Auto-shrink if over Slack's 128KB emoji limit (target 124KB for safety margin)
|
||||||
|
MAX_BYTES=126976
|
||||||
|
OUTPUT_BYTES=$(stat -c%s "${OUTPUT_GIF}" 2>/dev/null || stat -f%z "${OUTPUT_GIF}" 2>/dev/null)
|
||||||
|
if [[ ${OUTPUT_BYTES} -gt ${MAX_BYTES} ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "Output is over 128KB (${OUTPUT_BYTES} bytes). Auto-shrinking for Slack..."
|
||||||
|
CURRENT_SIDE=$(${IDENTIFY_CMD} -format "%w" "${OUTPUT_GIF}[0]")
|
||||||
|
while [[ ${OUTPUT_BYTES} -gt ${MAX_BYTES} && ${CURRENT_SIDE} -gt 16 ]]; do
|
||||||
|
# Reduce by ~25% each iteration
|
||||||
|
CURRENT_SIDE=$(( CURRENT_SIDE * 75 / 100 ))
|
||||||
|
echo " Trying ${CURRENT_SIDE}x${CURRENT_SIDE}..."
|
||||||
|
"${MAGICK_CMD}" "${OUTPUT_GIF}" \
|
||||||
|
-coalesce \
|
||||||
|
-resize "${CURRENT_SIDE}x${CURRENT_SIDE}!" \
|
||||||
|
-layers Optimize \
|
||||||
|
"${OUTPUT_GIF}"
|
||||||
|
OUTPUT_BYTES=$(stat -c%s "${OUTPUT_GIF}" 2>/dev/null || stat -f%z "${OUTPUT_GIF}" 2>/dev/null)
|
||||||
|
done
|
||||||
|
OUTPUT_SIZE=$(du -h "${OUTPUT_GIF}" | cut -f1)
|
||||||
|
echo "✓ Shrunk to ${CURRENT_SIDE}x${CURRENT_SIDE} (${OUTPUT_SIZE}, ${OUTPUT_BYTES} bytes)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "✗ Error: Failed to create output file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
123
linux_configuration/scripts/utils/upgrade.sh
Executable file
123
linux_configuration/scripts/utils/upgrade.sh
Executable file
@ -0,0 +1,123 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# System upgrade script with automatic apt source hygiene
|
||||||
|
# Fixes common warnings/errors before running upgrades.
|
||||||
|
# All fixes are idempotent and safe to re-run.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
log() { printf '[upgrade] %s\n' "$*"; }
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# Fix 1: Duplicate repository — microsoft-edge.list is a copy of
|
||||||
|
# google-chrome.list (both point to dl.google.com/linux/chrome)
|
||||||
|
# =====================================================================
|
||||||
|
fix_duplicate_chrome_edge_repo() {
|
||||||
|
local edge="/etc/apt/sources.list.d/microsoft-edge.list"
|
||||||
|
local chrome="/etc/apt/sources.list.d/google-chrome.list"
|
||||||
|
|
||||||
|
if [[ ! -f $edge ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only act if edge list points to the chrome repo (the known bug)
|
||||||
|
if grep -q 'dl.google.com/linux/chrome' "$edge" 2>/dev/null; then
|
||||||
|
log "Disabling duplicate microsoft-edge.list (identical to google-chrome.list)"
|
||||||
|
mv "$edge" "${edge}.disabled"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# Fix 2: Expired Cloudflare WARP GPG key (expired 2025-12-03)
|
||||||
|
# =====================================================================
|
||||||
|
fix_cloudflare_key() {
|
||||||
|
local keyring="/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg"
|
||||||
|
local source_list="/etc/apt/sources.list.d/cloudflare-client.list"
|
||||||
|
|
||||||
|
if [[ ! -f $source_list ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if key is expired
|
||||||
|
local expired
|
||||||
|
expired=$(gpg --no-default-keyring --keyring "$keyring" --list-keys 2>&1 | grep -c 'expired' || true)
|
||||||
|
|
||||||
|
if [[ ${expired:-0} -gt 0 ]]; then
|
||||||
|
log "Refreshing expired Cloudflare WARP GPG key..."
|
||||||
|
curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg \
|
||||||
|
| gpg --yes --dearmor -o "$keyring" 2>/dev/null \
|
||||||
|
&& log "Cloudflare key refreshed." \
|
||||||
|
|| log "WARNING: Could not refresh Cloudflare key (network issue?). Skipping."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# Fix 3: WineHQ key in legacy trusted.gpg + repo targets focal not noble
|
||||||
|
# =====================================================================
|
||||||
|
fix_wine_legacy_key() {
|
||||||
|
local legacy_keyring="/etc/apt/trusted.gpg"
|
||||||
|
local wine_key_id="D43F640145369C51D786DDEA76F1A20FF987672F"
|
||||||
|
local modern_keyring="/usr/share/keyrings/winehq-archive.gpg"
|
||||||
|
local wine_source="/etc/apt/sources.list.d/winehq-focal.list"
|
||||||
|
|
||||||
|
# Check if wine key is in the legacy keyring
|
||||||
|
if ! gpg --no-default-keyring --keyring "$legacy_keyring" --list-keys "$wine_key_id" >/dev/null 2>&1; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Migrating WineHQ key from legacy trusted.gpg to modern keyring..."
|
||||||
|
|
||||||
|
# Export key to modern location
|
||||||
|
gpg --no-default-keyring --keyring "$legacy_keyring" \
|
||||||
|
--export "$wine_key_id" \
|
||||||
|
| gpg --yes --dearmor -o "$modern_keyring" 2>/dev/null
|
||||||
|
|
||||||
|
# Remove from legacy keyring (suppress the deprecation warning)
|
||||||
|
apt-key del "$wine_key_id" >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
# Fix the source file to use signed-by and correct distro codename
|
||||||
|
local codename
|
||||||
|
codename=$(lsb_release -cs 2>/dev/null || echo "noble")
|
||||||
|
|
||||||
|
# Find all wine source files
|
||||||
|
for src in /etc/apt/sources.list.d/*wine*.list; do
|
||||||
|
[[ -f $src ]] || continue
|
||||||
|
|
||||||
|
# Check if already using signed-by
|
||||||
|
if grep -q 'signed-by=' "$src" 2>/dev/null; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local old_codename
|
||||||
|
old_codename=$(grep -oP 'ubuntu/?\s+\K\w+' "$src" | head -1)
|
||||||
|
|
||||||
|
log "Updating $src: ${old_codename:-unknown} → $codename, adding signed-by"
|
||||||
|
sed -i \
|
||||||
|
-e "s|deb https://|deb [arch=amd64 signed-by=$modern_keyring] https://|" \
|
||||||
|
-e "s|deb-src https://|# deb-src [arch=amd64 signed-by=$modern_keyring] https://|" \
|
||||||
|
-e "s|ubuntu/ ${old_codename}|ubuntu/ ${codename}|g" \
|
||||||
|
-e "s|ubuntu ${old_codename}|ubuntu ${codename}|g" \
|
||||||
|
"$src"
|
||||||
|
done
|
||||||
|
|
||||||
|
log "WineHQ key migrated and source updated."
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# Run all fixes, then upgrade
|
||||||
|
# =====================================================================
|
||||||
|
log "Running apt source hygiene checks..."
|
||||||
|
fix_duplicate_chrome_edge_repo
|
||||||
|
fix_cloudflare_key
|
||||||
|
fix_wine_legacy_key
|
||||||
|
log "Apt source checks complete."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
log "Installing aptitude if needed..."
|
||||||
|
apt-get install -y aptitude
|
||||||
|
|
||||||
|
log "Starting system upgrade..."
|
||||||
|
apt-get -y update && apt-get -y upgrade && apt-get -y dist-upgrade
|
||||||
|
apt-get -y autoremove
|
||||||
|
aptitude -y update && aptitude -y safe-upgrade && aptitude -y dist-upgrade
|
||||||
|
|
||||||
|
log "Upgrade complete."
|
||||||
Loading…
Reference in New Issue
Block a user