/** * Terminal Configuration * Central configuration for the Terminal component across the site */ // Default terminal prompt settings export const TERMINAL_DEFAULTS = { promptPrefix: "[laforceit@argobox]", title: "argobox:~/blog", theme: "dark", // Default theme (dark or light) height: "auto", showTitleBar: true, showPrompt: true }; // Commonly used commands export const COMMON_COMMANDS = [ { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "ls -la ./infrastructure", output: [ "total 20", "drwxr-xr-x 5 laforceit users 4096 Apr 23 09:15 kubernetes/", "drwxr-xr-x 3 laforceit users 4096 Apr 20 17:22 docker/", "drwxr-xr-x 2 laforceit users 4096 Apr 19 14:30 networking/", "drwxr-xr-x 4 laforceit users 4096 Apr 22 21:10 monitoring/", "drwxr-xr-x 3 laforceit users 4096 Apr 21 16:45 storage/", ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "grep -r \"kubernetes\" --include=\"*.md\" ./posts | wc -l", output: ["7 matches found"] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "kubectl get nodes", output: [ "NAME STATUS ROLES AGE VERSION", "argobox-cp1 Ready control-plane,master 92d v1.27.3", "argobox-cp2 Ready control-plane,master 92d v1.27.3", "argobox-cp3 Ready control-plane,master 92d v1.27.3", "argobox-node1 Ready worker 92d v1.27.3", "argobox-node2 Ready worker 92d v1.27.3" ] } ]; // Advanced blog search command sequence export const BLOG_SEARCH_SEQUENCE = [ { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "cd ./posts && grep -r \"homelab\" --include=\"*.md\" | sort | head -5", output: [ "homelab-essentials.md:title: \"Essential Tools for Your Home Lab Setup\"", "homelab-essentials.md:description: \"A curated list of must-have tools for building your home lab infrastructure\"", "kubernetes-at-home.md:title: \"Running Kubernetes in Your Homelab\"", "proxmox-cluster.md:description: \"Building a resilient homelab foundation with Proxmox VE cluster\"", "storage-solutions.md:body: \"...affordable homelab storage solutions for a growing collection of VMs and containers...\"" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "find ./posts -type f -name \"*.md\" | xargs wc -l | sort -nr | head -3", output: [ "2567 total", " 842 ./posts/kubernetes-the-hard-way.md", " 756 ./posts/home-automation-guide.md", " 523 ./posts/proxmox-cluster.md" ] } ]; // System monitoring sequence export const SYSTEM_MONITOR_SEQUENCE = [ { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "htop", output: [ "Tasks: 143 total, 4 running, 139 sleeping, 0 stopped, 0 zombie", "%Cpu(s): 12.5 us, 4.2 sy, 0.0 ni, 82.3 id, 0.7 wa, 0.0 hi, 0.3 si, 0.0 st", "MiB Mem: 32102.3 total, 12023.4 free, 10654.8 used, 9424.1 buff/cache", "MiB Swap: 16384.0 total, 16384.0 free, 0.0 used. 20223.3 avail Mem", "", " PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND", " 23741 laforcei 20 0 4926.0m 257.9m 142.1m S 25.0 0.8 42:36.76 node", " 22184 root 20 0 743.9m 27.7m 17.6m S 6.2 0.1 27:57.21 dockerd", " 15532 root 20 0 1735.9m 203.5m 122.1m S 6.2 0.6 124:29.93 k3s-server", " 1126 prometheu 20 0 1351.5m 113.9m 41.3m S 0.0 0.4 3:12.52 prometheus" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "df -h", output: [ "Filesystem Size Used Avail Use% Mounted on", "/dev/nvme0n1p2 932G 423G 462G 48% /", "/dev/nvme1n1 1.8T 1.1T 638G 64% /data", "tmpfs 16G 12M 16G 1% /run", "tmpfs 32G 0 32G 0% /dev/shm" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "docker stats --no-stream", output: [ "CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS", "7d9915b1f946 blog-site 0.15% 145.6MiB / 32GiB 0.44% 648kB / 4.21MB 12.3MB / 0B 24", "c7823beac704 prometheus 2.33% 175.2MiB / 32GiB 0.53% 15.5MB / 25.4MB 29.6MB / 12.4MB 15", "db9d8512f471 postgres 0.03% 96.45MiB / 32GiB 0.29% 85.1kB / 106kB 21.9MB / 63.5MB 11", "f3b1c9e2a147 grafana 0.42% 78.32MiB / 32GiB 0.24% 5.42MB / 12.7MB 86.4MB / 1.21MB 13" ] } ]; // Blog deployment sequence export const BLOG_DEPLOYMENT_SEQUENCE = [ { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "git status", output: [ "On branch main", "Your branch is up to date with 'origin/main'.", "", "Changes not staged for commit:", " (use \"git add ...\" to update what will be committed)", " (use \"git restore ...\" to discard changes in working directory)", " modified: src/content/posts/kubernetes-at-home.md", " modified: src/components/Terminal.astro", "", "Untracked files:", " (use \"git add ...\" to include in what will be committed)", " src/content/posts/new-homelab-upgrades.md", "", "no changes added to commit (use \"git add\" and/or \"git commit -a\")" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "git add . && git commit -m \"feat: add new post about homelab upgrades\"", output: [ "[main f92d47a] feat: add new post about homelab upgrades", " 3 files changed, 214 insertions(+), 12 deletions(-)", " create mode 100644 src/content/posts/new-homelab-upgrades.md" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "npm run build && npm run deploy", output: [ " Building for production...", " Generating static routes", " Client side rendering with hydration", " Applying optimizations", " Complete! 187 pages generated in 43.2 seconds", "", "Deploying to production environment...", " Upload complete", " CDN cache invalidated", " DNS configuration verified", " Blog is live at https://laforceit.com!" ] } ]; // Kubernetes operation sequence export const K8S_OPERATION_SEQUENCE = [ { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "kubectl create namespace blog-prod", output: [ "namespace/blog-prod created" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "kubectl apply -f kubernetes/blog-deployment.yaml", output: [ "deployment.apps/blog-frontend created", "service/blog-frontend created", "configmap/blog-config created", "secret/blog-secrets created" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "kubectl get pods -n blog-prod", output: [ "NAME READY STATUS RESTARTS AGE", "blog-frontend-7d9b5c7b8d-2xprm 1/1 Running 0 35s", "blog-frontend-7d9b5c7b8d-8bkpl 1/1 Running 0 35s", "blog-frontend-7d9b5c7b8d-f9j7s 1/1 Running 0 35s" ] }, { prompt: TERMINAL_DEFAULTS.promptPrefix + "$", command: "kubectl get ingress -n blog-prod", output: [ "NAME CLASS HOSTS ADDRESS PORTS AGE", "blog-ingress blog.laforceit.com 192.168.1.50 80, 443 42s" ] } ]; // Predefined terminal content blocks export const TERMINAL_CONTENT = { fileExplorer: `
${TERMINAL_DEFAULTS.promptPrefix}
$ ls -la total 42 drwxr-xr-x 6 laforceit users 4096 Nov 7 22:15 . drwxr-xr-x 12 laforceit users 4096 Nov 7 20:32 .. -rw-r--r-- 1 laforceit users 182 Nov 7 22:15 .astro drwxr-xr-x 2 laforceit users 4096 Nov 7 21:03 components drwxr-xr-x 3 laforceit users 4096 Nov 7 21:14 content drwxr-xr-x 4 laforceit users 4096 Nov 7 21:42 layouts drwxr-xr-x 5 laforceit users 4096 Nov 7 22:10 pages -rw-r--r-- 1 laforceit users 1325 Nov 7 22:12 package.json`, tags: `
${TERMINAL_DEFAULTS.promptPrefix}
$ cat ./content/tags.txt cloudflare coding containers devops digital-garden docker file-management filebrowser flux git gitea gitops grafana homelab infrastructure k3s knowledge-management kubernetes learning-in-public monitoring networking observability obsidian prometheus proxmox quartz rancher remote-development security self-hosted terraform test tunnels tutorial virtualization vscode`, blogDeployment: `
${TERMINAL_DEFAULTS.promptPrefix}
$ git add src/content/posts/kubernetes-monitoring.md
${TERMINAL_DEFAULTS.promptPrefix}
$ git commit -m "feat: add new article on Kubernetes monitoring" [main 8fd43a9] feat: add new article on Kubernetes monitoring 1 file changed, 147 insertions(+) create mode 100644 src/content/posts/kubernetes-monitoring.md
${TERMINAL_DEFAULTS.promptPrefix}
$ git push origin main Enumerating objects: 8, done. Counting objects: 100% (8/8), done. Delta compression using up to 8 threads Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 2.12 KiB | 2.12 MiB/s, done. Total 5 (delta 3), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (3/3), completed with 3 local objects. Deployed to https://laforceit.com Article published successfully`, k8sInstall: `
${TERMINAL_DEFAULTS.promptPrefix}
$ curl -sfL https://get.k3s.io | sh - [INFO] Finding release for channel stable [INFO] Using v1.27.4+k3s1 as release [INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.27.4+k3s1/sha256sum-amd64.txt [INFO] Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.27.4+k3s1/k3s [INFO] Verifying binary download [INFO] Installing k3s to /usr/local/bin/k3s [INFO] Creating /usr/local/bin/kubectl symlink to k3s [INFO] Creating /usr/local/bin/crictl symlink to k3s [INFO] Creating /usr/local/bin/ctr symlink to k3s [INFO] Creating killall script /usr/local/bin/k3s-killall.sh [INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh [INFO] env: Creating environment file /etc/systemd/system/k3s.service.env [INFO] systemd: Creating service file /etc/systemd/system/k3s.service [INFO] systemd: Enabling k3s unit Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service. [INFO] systemd: Starting k3s K3s has been installed successfully
${TERMINAL_DEFAULTS.promptPrefix}
$ kubectl get pods -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system helm-install-traefik-crd-k7gxl 0/1 Completed 0 2m43s kube-system helm-install-traefik-pvvhg 0/1 Completed 1 2m43s kube-system metrics-server-67c658dc48-mxnxp 1/1 Running 0 2m43s kube-system local-path-provisioner-7b7dc8d6f5-q99nl 1/1 Running 0 2m43s kube-system coredns-b96499967-nkvnz 1/1 Running 0 2m43s kube-system svclb-traefik-bd0bfb17-ht8gq 2/2 Running 0 96s kube-system traefik-7d586bdc47-d6lzr 1/1 Running 0 96s`, dockerCompose: `
${TERMINAL_DEFAULTS.promptPrefix}
$ cat docker-compose.yaml version: '3.8' services: blog: image: node:18-alpine restart: unless-stopped volumes: - ./:/app working_dir: /app command: sh -c "npm install && npm run dev" ports: - "3000:3000" environment: - NODE_ENV=development db: image: postgres:14-alpine restart: unless-stopped volumes: - postgres_data:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=secure_password - POSTGRES_USER=bloguser - POSTGRES_DB=blogdb ports: - "5432:5432" volumes: postgres_data:
${TERMINAL_DEFAULTS.promptPrefix}
$ docker-compose up -d Creating network "laforceit-blog_default" with the default driver Creating volume "laforceit-blog_postgres_data" with default driver Pulling blog (node:18-alpine)... Pulling db (postgres:14-alpine)... Creating laforceit-blog_db_1 ... done Creating laforceit-blog_blog_1 ... done` }; // Helper function to create terminal presets export function createTerminalPreset(type) { switch (type) { case 'blog-search': return BLOG_SEARCH_SEQUENCE[Math.floor(Math.random() * BLOG_SEARCH_SEQUENCE.length)]; case 'system-monitor': return SYSTEM_MONITOR_SEQUENCE[Math.floor(Math.random() * SYSTEM_MONITOR_SEQUENCE.length)]; case 'blog-deploy': return BLOG_DEPLOYMENT_SEQUENCE[Math.floor(Math.random() * BLOG_DEPLOYMENT_SEQUENCE.length)]; case 'k8s-ops': return K8S_OPERATION_SEQUENCE[Math.floor(Math.random() * K8S_OPERATION_SEQUENCE.length)]; case 'k8s': return { title: "argobox:~/kubernetes", command: "kubectl get pods -A", output: `NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-66bff467f8-8p7z2 1/1 Running 0 15d kube-system coredns-66bff467f8-v68vr 1/1 Running 0 15d kube-system etcd-control-plane 1/1 Running 0 15d kube-system kube-apiserver-control-plane 1/1 Running 0 15d kube-system kube-controller-manager-control-plane 1/1 Running 0 15d kube-system kube-proxy-c84qf 1/1 Running 0 15d kube-system kube-scheduler-control-plane 1/1 Running 0 15d` }; case 'docker': return { title: "argobox:~/docker", command: "docker ps", output: `CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES d834f0efcf2f nginx:latest "/docker-entrypoint.…" Up 2 days 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp web 0b292940b4c0 postgres:13 "docker-entrypoint.s…" Up 2 days 0.0.0.0:5432->5432/tcp db a834fa3ede06 redis:6 "docker-entrypoint.s…" Up 2 days 0.0.0.0:6379->6379/tcp cache` }; case 'search': return { title: "argobox:~/blog", command: "grep -r \"kubernetes\" --include=\"*.md\" ./posts | wc -l", output: "7 matches found" }; case 'random-cool': // Pick a random sequence for a cool effect const sequences = [ TERMINAL_CONTENT.k8sInstall, TERMINAL_CONTENT.blogDeployment, TERMINAL_CONTENT.dockerCompose, ...BLOG_SEARCH_SEQUENCE.map(item => `
${item.prompt}
$ ${item.command}\n${item.output.join('\n')}`), ...SYSTEM_MONITOR_SEQUENCE.map(item => `
${item.prompt}
$ ${item.command}\n${item.output.join('\n')}`), ...BLOG_DEPLOYMENT_SEQUENCE.map(item => `
${item.prompt}
$ ${item.command}\n${item.output.join('\n')}`), ...K8S_OPERATION_SEQUENCE.map(item => `
${item.prompt}
$ ${item.command}\n${item.output.join('\n')}`) ]; return { title: "argobox:~/cool-stuff", content: sequences[Math.floor(Math.random() * sequences.length)] }; default: return { title: TERMINAL_DEFAULTS.title, command: "echo 'Hello from LaForceIT Terminal'", output: "Hello from LaForceIT Terminal" }; } }