Add uninstall support + test harness; fix install (config template) and SLES MySQL/AppArmor#38
Closed
DASimp wants to merge 12 commits into
Closed
Add uninstall support + test harness; fix install (config template) and SLES MySQL/AppArmor#38DASimp wants to merge 12 commits into
DASimp wants to merge 12 commits into
Conversation
## Test infrastructure (new)
- tests/run-tests.sh: orchestrates build → install → verify → uninstall → verify
across all 6 supported OSes; runs each OS sequentially with full logging to
tests/logs/<os-slug>/
- tests/verify-install.sh: 24-point post-install checklist (services running,
files present, DB accessible, SimpleRisk web UI reachable, cron job installed,
SSL cert present, PHP settings applied)
- tests/verify-uninstall.sh: 12-point post-uninstall checklist (packages removed,
files/dirs gone, DB dropped, cron job removed)
- tests/dockerfiles/Dockerfile.ubuntu-{22.04,24.04}: pre-install lamp-server^ with
policy-rc.d deny so services are installed but not started; start them before
running the setup script to match a real server state
- tests/dockerfiles/Dockerfile.debian-{12,13}: /etc/init.d/mysql shim that manages
mysqld directly (no systemd); /usr/sbin/policy-rc.d deny gate during image build
- tests/dockerfiles/Dockerfile.centos-stream-{9,10}: /usr/local/bin/systemctl shim
(takes PATH precedence over real systemctl installed by MySQL's systemd RPM dep)
that manages mysqld and httpd directly; no-op shims for firewall-cmd, setsebool,
chcon; innodb_use_native_aio=0 for Docker overlayfs compatibility
- .github/workflows/install-test.yml: CI matrix over all 6 OSes on push/PR to main
- CLAUDE.md: project documentation for Claude Code
## Bug fixes in simplerisk-setup.sh
- Add --uninstall flag: routes to per-OS uninstall functions with dedicated
ask_user_uninstall() prompt and uninstall_final_message(); previously the flag
was accepted but silently fell through to installation
- CentOS/RHEL: add php-cli to explicit dnf install list — on el10 it is a
Recommended (weak) dep of php and was being silently omitted
- CentOS/RHEL: add --exclude 'mysql8.4*' to mysql-community-server install —
CentOS Stream 10's AppStream ships mysql8.4-server which conflicts on
/usr/sbin/mysqld; the exclude is a no-op on el9/el8
All 6 OS tests (ubuntu-22.04, ubuntu-24.04, debian-12, debian-13,
centos-stream-9, centos-stream-10) pass the full 7-step suite locally on
Docker Desktop for Windows.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fix CentOS start Three CI failures fixed: 1. Dockerfile heredoc parse error (Debian-12, Debian-13, CentOS-9, CentOS-10) Docker's standard Dockerfile parser treats `RUN cat > /file << 'EOF'` as a single-line RUN — subsequent lines are parsed as new Dockerfile instructions, causing "unknown instruction: PIDFILE=..." errors on the Linux CI runner. Fix: extract the mysql init script and systemctl shim to separate files (mysql-init-debian.sh, systemctl-shim-centos.sh) and use COPY + chmod. Also add eol=lf to .gitattributes for *.sh, Dockerfile*, and *.yml so CRLF conversion on Windows never affects files parsed on Linux. 2. Ubuntu Apache restart timeout during apt post-install triggers The libapache2-mod-php post-install script fires `service apache2 restart` multiple times in quick succession. Without --init (tini as PID 1), child processes are not properly reaped and a graceful restart can hang for the full 60s timeout. Fix: add --init to all docker run commands in the CI workflow (matches what run-tests.sh already does locally). 3. CentOS CI container start used the systemd path The CI workflow started CentOS containers with --cgroupns=host / --tmpfs expecting systemd as PID 1, then waited for multi-user.target. But the Dockerfiles use the /usr/local/bin/systemctl shim (no real systemd). Fix: unify container start for all OSes to --init + tail -f /dev/null; remove the separate CentOS systemd-start step and the "Wait for systemd" step entirely. Also adds a "Start pre-installed services" step in CI for Ubuntu only, to mirror what run-tests.sh does locally: start MySQL and Apache before the setup script runs, since Ubuntu images pre-install lamp-server^ during the Docker build (services blocked by policy-rc.d). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On CentOS/RHEL with MySQL 8.4.9, appending sql_mode to /etc/my.cnf did not take effect after restart — the vendor-supplied files in /etc/my.cnf.d/ appear to override it. Two-part fix: 1. Write sql_mode to /etc/my.cnf.d/zz-simplerisk.cnf (the "zz-" prefix ensures it sorts last alphabetically among included files, so it wins regardless of what other files the MySQL RPM installs). 2. After the restart, also run SET GLOBAL sql_mode=... so the change is applied to the running instance immediately, without relying solely on config-file parsing order. Also enhances the CI diagnostics step to dump /etc/my.cnf, all files in /etc/my.cnf.d/, and the live sql_mode value on failure. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch all package removal steps in uninstall_ubuntu_debian, uninstall_centos_rhel, and uninstall_suse from exec_cmd (bail on failure) to exec_cmd_nobail so the uninstaller continues even when packages were never installed or only partially set up. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The mysql84-community-release RPM (updated in-place to -3) now also enables a mysql-9.7-lts-community repo. DNF was resolving mysql-community-server to 9.7.0 instead of 8.4.x. Add --disablerepo='mysql-9*' to the install command so we always get the 8.4 LTS release. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidates the unique SLES work onto this branch so it is the single canonical line (install + uninstall + tests + docs): - SSL: use OpenSSL 3 / FIPS-compatible `openssl genpkey` instead of the `genrsa -des3` + passphrase-file dance - cron: install cron via zypper before setting up the backup cronjob - firewall: configure firewalld (enable/start + open http/https/ssh), but guard on `firewall-cmd` being present so the install does not abort with "Unit file firewalld.service does not exist" on minimal/JeOS images - uninstall_suse: mirror the firewall teardown (http/https only, leaving ssh intact to avoid locking out remote access), also guarded Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- exec_cmd_sensitive: new helper that runs a command without echoing it. set_up_database now uses it for every MySQL statement that embeds a password (plus the config.php DB_PASSWORD sed), so credentials no longer leak into --debug output or CI log artifacts (the test harness runs --debug). - perform_installation: abort with a clear message if the SimpleRisk version lookup returns empty (e.g. no network) instead of a confusing wget failure. - setup: when run via a pipe (curl | bash) with no TTY, default installs to headless. Uninstall is excluded so the destructive confirmation still requires an explicit --yes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The SLES install was dying at `zypper -n install mysql-community-server`. Root cause: SLES ships MariaDB, whose packages "provide" the mysql RPM namespace and conflict with mysql-community-server. Interactively zypper asks which to keep; with -n it aborts, so MySQL never installs and every later step (start mysql, set_up_database) fails. Changes in setup_suse: - Install with `--allow-vendor-change --force-resolution` so the resolver applies the "replace MariaDB with MySQL" solution non-interactively. - Switch to the unversioned `mysql84-community-release-sl15.rpm` (defaults to the 8.4 LTS subrepo) instead of the stale `-1` pin. - Replace the hardcoded `rpm --import` with `zypper --gpg-auto-import-keys refresh` so a rotated MySQL signing key can't cause repomd.xml signature failures. - Defensively disable the mysql-innovation-community (9.x) track to stay on 8.4 LTS, mirroring the CentOS/RHEL fix. NOTE: pending validation on a registered SLES 15 box. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Upstream SimpleRisk release bundles changed: they no longer ship includes/config.php. Instead they ship includes/config.sample.php, a template whose values are __PLACEHOLDER__ tokens, and SimpleRisk now treats the mere existence of config.php as the install marker (the old SIMPLERISK_INSTALLED flag is gone). The script's set_up_database edited config.php in place, so every install failed with: sed: can't read /var/www/simplerisk/includes/config.php: No such file Fix (shared, affects all OSes): - set_up_simplerisk: create config.php from config.sample.php after extract. - set_up_database: replace the obsolete DB_PASSWORD/SIMPLERISK_INSTALLED seds with substitution of the new tokens (DB_HOSTNAME=localhost, DB_PORT=3306, DB_USERNAME=simplerisk, DB_PASSWORD=<generated>, DB_DATABASE=simplerisk, USE_DATABASE_FOR_SESSIONS=true). Placeholder substitution validated on an openSUSE Leap 15.6 instance against the current bundle (20260519-001). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Validated on openSUSE Leap 15.6 (SLES 15 SP6 equivalent) against the live MySQL repo. Two issues the first pass missed: - The mysql84-community-release-sl15 RPM actually enables the newest LTS repo (currently mysql-9.7-lts-community) and leaves mysql-8.4-lts-community DISABLED, so `mysql-community-server` resolved to 9.7. Now we explicitly enable the 8.4 repos, disable the 9.x ones, and bound the install to `mysql-community-server<9` so it can only resolve to 8.4 LTS (got 8.4.9). - Re-add `rpm --import $MYSQL_KEY_URL`: importing the key into the rpm keyring is required for package-signature verification (the install was warning NOKEY for key a8d3785c); `--gpg-auto-import-keys` only covers zypper repo metadata, not rpm package signatures. Reproduced the original MariaDB-vs-MySQL conflict (zypper aborts under -n) and confirmed the fix resolves it: MariaDB replaced, MySQL 8.4.9 installed, zero NOKEY warnings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…STALLED The verify-install check `SIMPLERISK_INSTALLED is set to true` tested for a flag the redesigned config.php no longer has (existence of config.php is now the install marker). Replace it with checks that the installer substituted the __PLACEHOLDER__ tokens and populated DB_PASSWORD. Validated locally via tests/run-tests.sh ubuntu-22.04: install verify 24/0, uninstall verify 13/0, ALL TESTS PASSED. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stock SLES ships no AppArmor profile for Apache, but hardened/STIG/CIS baselines commonly add one in enforce mode, which blocks SimpleRisk's writes (uploads, log dir, config.php). setup_suse now detects a loaded Apache profile and disables it (disable symlink + apparmor_parser -R) so Apache runs unconfined; uninstall_suse re-enables it to restore the original posture. Both are guarded: a clean no-op when AppArmor is off or no Apache profile exists (the default-SLES case), so nothing changes on unhardened systems. Detection/no-op logic validated on openSUSE Leap 15.6. The enforce-mode unload itself requires a real AppArmor-enabled SLES box to exercise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Closing: setup-scripts-dev is the canonical source (it syncs to this public repo). These fixes are being ported into setup-scripts-dev as a focused PR (SLES AppArmor + MariaDB-conflict resolution); the rest (uninstall, config-template handling, tests) already exist there. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds full uninstall support and a Docker-based local/CI test harness, fixes the install flow that upstream changes had broken across all OSes, and resolves the SLES MySQL failure plus initial government/STIG hardening for SLES.
All six Docker-testable OSes pass install and uninstall locally via
tests/run-tests.sh(install verify 24/0; uninstall verify 10–13/0).Install correctness (all OSes)
includes/config.sample.php(a__PLACEHOLDER__template) instead ofconfig.php, and use the file's existence as the install marker (no moreSIMPLERISK_INSTALLED).set_up_simplerisknow createsconfig.phpfrom the sample andset_up_databasesubstitutes the tokens (DB_HOSTNAME/PORT/USERNAME/PASSWORD/DATABASE, USE_DATABASE_FOR_SESSIONS). This was breaking every install.tests/verify-install.shupdated to the new config model.SLES (the client's blocker)
mysqlnamespace and conflicts withmysql-community-server; underzypper -nthe install aborted. Now installs with--allow-vendor-change --force-resolutionto apply the "replace MariaDB with MySQL" resolution.mysql-community-server<9(validated: installs 8.4.9, not 9.7).Security / robustness
exec_cmd_sensitive: MySQL passwords are no longer echoed into--debugoutput / CI logs.curl | bashinstalls default to headless; uninstall still requires explicit--yes.Test plan
tests/run-tests.shgreen for all 6 OSes (ubuntu 22.04/24.04, debian 12/13, centos-stream 9/10), install + uninstall.Still open (not in this PR)
SLES gov-hardening follow-ups: exact-
15.7version gate, FIPS cert-sha256/SAN,--validate-os-onlyside-effect safety, non-root backup cron.🤖 Generated with Claude Code