Forum teuk.org

Installer Hardening, Perl Cleanups, and Live Test Stability

in Mediabot · started by TeuK · 1w ago

TeuK · 1w ago

Installer Hardening, Perl Cleanups, and Live Test Stability

Suggested forum title

Mediabot v3: installer hardening, Perl cleanups, and stronger regression tests

Article

This update is a maintenance and reliability pass focused on the installer, helper scripts, regression tests, and a few small Perl runtime details.

The goal was not to add visible IRC commands, but to make Mediabot v3 cleaner to install, easier to test, and less fragile during a fresh deployment.

Fresh install fixes

A real from-scratch install revealed an important bug in install/db_install.sh.

The script was generating SQL like this inside a Bash double-quoted string:

printf "DROP DATABASE IF EXISTS `%s`;\n" "$MYSQL_DB"

That is wrong in Bash because raw backticks are treated as command substitution before MySQL ever sees the query.

The fix was to escape SQL identifier backticks properly:

printf "DROP DATABASE IF EXISTS \`%s\`;\n" "$MYSQL_DB"

The same fix was applied to the CREATE DATABASE query.

This prevents the broken SQL case where MariaDB receives an incomplete statement such as:

DROP DATABASE IF EXISTS

Better database installer error handling

install/db_install.sh also received cleaner failure handling when verifying the application database user.

The old logic used an inverted shell command pattern:

if ! echo "SELECT 1;" | mysql ...; then
    ok_failed $?
fi

That can produce confusing return code handling because $? is affected by the shell !.

The installer now captures the MySQL verification return code explicitly:

echo "SELECT 1;" | mysql ...
verify_rc=$?

if [ "$verify_rc" -ne 0 ]; then
    ...
    exit "$verify_rc"
fi

The script also now reports configuration file updates more honestly. It no longer says a config file was updated when no config file was provided or when the file was missing/unwritable.

CPAN install improvements

install/cpan_install.sh was cleaned up in two ways.

First, the manual Hailo fallback is now guarded. The script no longer downloads and recompiles Hailo if the normal CPAN/module flow already made Hailo available.

Second, wait_for_cmd() no longer builds a shell command string and runs it through bash -c. It now executes the command through normal argv handling:

wait_for_cmd ./install_perl_module.sh "$perl_module"

This is cleaner, safer, and avoids fragile quote composition.

A follow-up fix also corrected the path used by cpan_install.sh: since it runs from inside install/, the helper must be called as:

./install_perl_module.sh

not:

./install/install_perl_module.sh

Configure and installer cleanup

Several install scripts were cleaned up:

  • install/configure.pl no longer asks for a dead alternate nick value after CONN_NICK_ALTERNATE was removed.
  • install/configure.pl no longer uses SELECT * where explicit columns are enough.
  • install/conf_servers.pl had a duplicate MAIN_PROG_DDBNAME required check removed.
  • install/conf_servers.pl also had its SELECT * queries replaced by explicit column lists.
  • addIrcServer() logging in the server configuration helper now logs the local server hostname argument rather than an unrelated global prompt variable.

These are small changes individually, but they make the installer code easier to review and less prone to accidental copy/paste bugs.

Contrib Icecast helper fixes

The old Icecast helper scripts in contrib/icecast2/ were cleaned up.

The usage text now has proper spacing:

getIcecastTitle.pl --host ...

instead of:

getIcecastTitle.pl--host ...

The scripts also advertised --source but did not properly accept or use it. That was corrected.

More importantly, Icecast JSON can return icestats.source as either:

  • a hash when there is one mount;
  • an array when there are multiple mounts.

The helper scripts now handle both structures properly and use the --source index only when source is an array.

Runtime and live test stability

Two fractional sleep issues were cleaned up.

In Mediabot/Partyline.pm, the .eval watchdog used:

sleep(0.5);

That was replaced with:

usleep(500_000);

using Time::HiRes, so the child process really gets a 500ms grace period after TERM before KILL.

The same kind of fix was applied to t/test_live.pl, where live test teardown now uses usleep(500_000) rather than fractional sleep(0.5).

Small but useful CLI cleanup

The main mediabot.pl usage string had a missing space:

mediabot.pl--conf=<config_file>

It now displays correctly:

mediabot.pl --conf=<config_file>

That is small, but help output should be copy/paste friendly.

Regression tests added

This pass added more regression coverage around:

  • database installer SQL backtick escaping;
  • database user verification return codes;
  • database config update reporting;
  • Partyline .eval watchdog timing;
  • mediabot.pl usage formatting;
  • contrib Icecast usage and --source;
  • Icecast source selection for hash/array JSON forms;
  • duplicate installer checks;
  • removal of SELECT * in installer scripts;
  • removal of dead configure prompts;
  • CPAN Hailo fallback behavior;
  • safer wait_for_cmd() execution in CPAN installation;
  • live test teardown timing.

This continues the recent direction of turning cleanup decisions into tests, so the same regressions are less likely to come back later.

Why this matters

This update is about trust.

A fresh installer should fail clearly when something is wrong. A README command should be copy/pasteable. A helper script should not lie about accepted options. A test runner should not depend on ambiguous fractional sleep behavior. SQL queries in install scripts should be explicit.

None of this is flashy, but it makes Mediabot v3 healthier.

It reduces install friction, improves diagnostics, and makes the project easier to maintain for the next round of real feature work.

Suggested commit message

Protego Installum: harden the installer and banish brittle Perl gremlins

Full validation command

cd /home/mediabot/mediabot_v3 || exit 1

find Mediabot -name '*.pm' -print0 | xargs -0 -n1 runuser -u mediabot -- perl -I. -c

runuser -u mediabot -- perl -c mediabot.pl

bash -n install/db_install.sh
bash -n install/cpan_install.sh
bash -n install/install_perl_module.sh

runuser -u mediabot -- perl t/test_commands.pl

Suggested quick smoke tests

After a clean install:

cd /home/mediabot/mediabot_v3
perl -c mediabot.pl
perl mediabot.pl --conf=mediabot.conf

From IRC:

/msg mediabot register <owner> <password>

From Partyline:

.console 2

You must be logged in to reply.