Skip to content

Refactor: Extract shared helpers to lib/, improve error handling, add tests - #1

Merged
Xbot-me merged 2 commits into
mainfrom
claude/quirky-lamport-fyksj1
Sep 29, 2026
Merged

Xbot-me merged 2 commits into
mainfrom
claude/quirky-lamport-fyksj1

Conversation

@Xbot-me

@Xbot-me Xbot-me commented Sep 29, 2026

Copy link
Copy Markdown
Owner

Summary

Major refactoring to improve code organization, maintainability, and reliability. Extracts common functions into reusable library modules, strengthens error handling with better traps and logging, adds comprehensive unit tests, and updates all services/stacks to use the new modular structure.

Type of change

  • Improvement to existing script
  • New feature (shared library modules)
  • CI/CD change

Changes made

Core refactoring:

  • Created scripts/lib/common.sh — centralized logging, validation, package management, and utility functions (retry, password generation, IP detection, swap sizing, etc.)
  • Created scripts/lib/web.sh — web-stack helpers for PHP layout detection, package installation, and Nginx/Apache configuration
  • Created scripts/services/mysql.sh — extracted MySQL/MariaDB installation and configuration logic
  • Created tests/run.sh — unit tests for helper functions (conf_set, valid_port, pkg_available, etc.)

bootstrap.sh improvements:

  • Added bash 4+ version check at startup
  • Enhanced error trap to include filename and better formatting; output to stderr
  • Changed set -euo pipefail to set -Eeuo pipefail (ERR trap fires in functions)
  • Added validation that full checkout exists before proceeding
  • Updated default Node.js from 20 to 22; added PHP 8.4 support
  • Added new environment variables: PULSE_OPEN_PORTS, PULSE_REDIS_CONN, tracking flags for wizard state
  • Improved help text with clearer descriptions and examples
  • Changed declare -gA to declare -A (global is implicit at top level)

revert.sh improvements:

  • Refactored to use common.sh helpers
  • Added --no-confirm flag for automation (skip typed-YES prompts)
  • Added --purge-data flag to optionally delete databases/Redis/Docker data
  • Added --list flag to show detected components without making changes
  • Improved error handling and logging consistency
  • Renamed internal DO array to TARGET for clarity

Service modules updated:

  • firewall.sh — Added support for firewalld (dnf systems), port validation, configurable extra ports via OPEN_PORTS
  • docker.sh — Improved repo setup, better error handling, daemon.json management
  • redis.sh — Added connection type validation, improved readiness checks
  • php_tune.sh — Refactored to detect PHP version from filesystem, improved pool calculations
  • certbot.sh — Simplified to use distribution packages only (no snap), better plugin detection
  • swap.sh — Improved size parsing, better swap detection

Stack modules updated:

  • lemp.sh, lamp.sh, node.sh — Now source web.sh and mysql.sh helpers, removed duplicate code
  • All stacks now validate port availability before installation

OS modules updated:

  • ubuntu.sh, debian.sh, centos_rocky.sh, amazon_linux.sh — Now source common.sh, use retry wrapper for package operations, consistent error handling

Configuration files:

  • Added "Managed by PulseDeploy" headers to nginx/apache configs
  • Enhanced nginx default.conf with limits section

CI/CD:

  • Updated .github/workflows/ci.yml to lint both bootstrap.sh and revert.sh

Testing

  • Added comprehensive unit tests in tests/run.sh covering:
    • conf_set — config file manipulation (replace, comment, append)
    • valid_port — port number validation
    • pkg_available / pkg_installed — package detection
    • generate_password — password generation
    • swap_suggest_size — swap sizing logic
    • backup_file — file backup logic
    • Argument parsing for various flag formats
  • All tests pass without root or network access
  • ShellCheck passes on all modified scripts

Checklist

  • shellcheck -x passes on all modified .sh files
  • New scripts follow the existing module pattern (helpers in

https://claude.ai/code/session_01WF2SiSxEVxKmDEdmffxPbT

….04)

Root causes of "it doesn't work":
- generate_password used `tr … | head -c N` under pipefail (SIGPIPE, exit
  141) and killed LEMP right after MySQL installed
- MySQL hardening ran with `2>/dev/null || true`, then wrote /root/.my.cnf
  with a password that was never applied; root also kept auth_socket
- no `set -E`, so the ERR trap never fired inside functions
- every module prompted on stdin and ignored flags (hung non-interactive)
- redis maxmemory sed used `\|` with `|` delimiter and never matched
- php_tune overwrote opcache.ini, dropping its zend_extension line
- nginx default site / RHEL stock server{} shadowed the PulseDeploy site
- fail2ban jails referenced missing logs/backends and crashed the service
- RHEL base step installed+enabled firewalld before ports were opened
- docker cleanup cron ran `prune --volumes` (data loss); Compose v1 via pip
- revert.sh called dnf on Debian and apt on RHEL, aborting mid-run

Changes:
- scripts/lib/common.sh + web.sh: shared logging, validation, retry, apt
  lock handling, package/service helpers, idempotent conf_set, PHP layout,
  nginx/apache activation with `-t` validation and rollback, HTTP->PHP
  health check
- new services/mysql.sh: distro packages only, real password auth, checks
  before saving credentials, DB/user creation with validated identifiers
- bootstrap.sh: strict flag parsing (--flag=value, unknown flags error),
  input validation before any change, PID-file lock, preflight checks,
  guarded --disable-root-ssh, hostname/timezone handling, tee logging
- firewall never resets rules and always allows every SSH port first
- swap/redis/docker/certbot/php_tune rewritten to be idempotent and to
  verify that the service actually works before reporting success
- revert.sh rewritten OS-aware; keeps data unless --purge-data
- config templates: client_max_body_size, try_files guard, dotfile blocks
- tests/run.sh (75 unit tests) and CI jobs for lint/tests/structure

Tested on Ubuntu 24.04: LEMP, LAMP, Node (NodeSource stubbed), Redis,
swap, PHP tuning, fail2ban, SSH hardening, hostname/timezone, wizard via
PTY, re-run idempotency and revert. Debian, RHEL-family and Amazon Linux
paths follow the same design but are not yet run on real machines.

Claude-Session: https://claude.ai/code/session_01WF2SiSxEVxKmDEdmffxPbT

@Xbot-me Xbot-me left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid

@Xbot-me
Xbot-me merged commit c882f34 into main Sep 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants