Forum teuk.org

πŸ°βš™οΈ Mediabot v3 β€” The Castle Learns to Rebuild Itself

in Mediabot Β· started by TeuK Β· 1w ago

TeuK Β· 1w ago

Development chronicle β€” mb632 to mb635 Β· Guarded IRC self-update, exact-host production protection and safer zero-surprise deployment

This round gives Mediabot one of its most operational features yet:

m update
m update now

A trusted operator can now ask the bot whether a newer version exists on GitHub and, when appropriate, launch the existing deployment machinery directly from IRC.

The important part is not the command itself.

The important part is everything that prevents a convenient update button from becoming a dangerous one.

No database schema change was required.


πŸͺ„ mb632 β€” m update arrives on IRC

The new command is available from a channel or private message and requires Master access.

A diagnostic call:

m update

compares the local Mediabot version with the version published on GitHub and distinguishes between an available update, an already current installation, a local version ahead of GitHub, an unreadable version and versions that cannot safely be compared.

Only a genuine newer remote release is eligible for deployment.

A development build ahead of GitHub is therefore never silently downgraded.

Running m update remains informational. The operator must explicitly request the action:

m update now

Unknown action words are rejected rather than guessed.


πŸ”§ One deployment engine, not two

The IRC command does not duplicate the deployment logic in Perl.

It delegates the heavy work to:

install/deploy_update.sh

The IRC layer handles permissions, version comparison, safety checks and operator feedback.

The shell updater remains responsible for cloning, validation, private-state preservation, rotation, activation and rollback.

One deployment engine means one behaviour to maintain.


πŸ” mb633–mb634 β€” Protect the right machine

The first version of the safety rule was too broad.

/home/mediabot/mediabot_v3 is not inherently a production-only path. It is also a perfectly normal Mediabot installation path on another server.

The built-in protected instance is therefore the exact pair:

/home/mediabot/mediabot_v3
+
teuk.org

Both must match.

teuk.org means exactly teuk.org

Hostname comparison is case-insensitive and accepts the optional trailing DNS dot:

teuk.org     β†’ protected
TEUK.ORG     β†’ protected
teuk.org.    β†’ protected

But a hostname merely containing that string is not the production host:

mediabot.teuk.org   β†’ allowed
foo-teuk.org        β†’ allowed
teuk.org.example    β†’ allowed
notteuk.org         β†’ allowed
nbot.soyou.rocks    β†’ allowed

This distinction is deliberate.

A substring is not a hostname identity.

The guard protects the real production instance without making the normal installation path unusable everywhere else.

The Unix account running the updater does not bypass this rule either: protection is based on the exact host/path pair, not on whether the process happens to run as mediabot, root or another account.


βš™οΈ Additional protected targets remain configurable

The configuration can add more safety rules.

For example:

/path/to/mediabot_v3@backup.example.org

protects one exact host/path pair.

A bare path protects that path on every host.

The built-in production protection remains independent of configuration: configuration may add protections, but cannot remove the teuk.org rule.


πŸ›‘οΈ mb635 β€” Prepare the replacement before stopping the bot

The final audit found a more important deployment-order problem.

The updater originally stopped the bot before cloning GitHub.

That meant a slow network, an unavailable GitHub repository or a broken candidate could create downtime before a replacement tree even existed.

The order is now deliberately reversed.

While the current bot is still running:

git clone
    ↓
Perl syntax validation
    ↓
startup integrity validation

Only a candidate that passes those checks is allowed to reach the shutdown stage.

A failed clone therefore leaves the live bot untouched.

A syntax error leaves the live bot untouched.

A failed staged integrity check leaves the live bot untouched.


πŸ›‘ SIGTERM now begins the short critical section

Once the candidate is ready:

validated candidate
        ↓
stop current Mediabot
        ↓
copy mediabot.conf
copy latest Hailo .brn
        ↓
archive current release
        ↓
activate staged release
        ↓
validate live path

The expensive and unpredictable network work happens before downtime.

After SIGTERM, the updater mostly performs local filesystem operations.

This is also much safer with systemd: the service manager no longer gets a large clone/validation window in which it could race against the deployment and restart the old tree.


🧠 Private runtime state remains private

The updater preserves:

mediabot.conf

and the latest Hailo brain:

*.brn

The brain is copied after the running process has stopped, avoiding a deliberate snapshot while the bot may still be modifying its state.

The Git checkout remains public code; runtime configuration and learned state remain separate.


πŸ“¦ The previous release is archived

The current installation is rotated to a numbered directory and the already validated candidate becomes the new:

mediabot_v3

The updater does not overwrite the live tree file by file.

The previous release remains available as an archive.


↩️ A final live-path validation still protects the switch

After activation, Mediabot’s entry point is checked again from its final location.

If that validation fails, the updater attempts to restore the archived release.

The deployment therefore has two defensive stages:

before switch
    reject a bad candidate

after switch
    detect an activation failure and roll back

🧡 The updater survives the bot that launched it

m update now eventually stops the very Mediabot process that initiated the update.

The deployment process therefore detaches from the bot and redirects its output to:

var/update.log

The update can continue after the requesting bot process disappears.


πŸ”„ systemd and manually launched bots remain different

deploy_update.sh intentionally does not blindly start Mediabot itself.

When the instance is managed by systemd, the service manager can bring it back using the newly activated tree.

When Mediabot was launched manually β€” foreground, screen or tmux β€” it remains stopped after the deployment and the operator must start it again.

The IRC command warns about that before performing the update.


πŸ§ͺ Regression map

This round is protected by:

814  mb632 β€” IRC update command, permissions, version states and launch
815  mb634 β€” exact hostname semantics
816  mb635 β€” staged validation before shutdown

The hostname contract is explicit:

teuk.org             β†’ protected
mediabot.teuk.org    β†’ allowed

And the deployment ordering is locked as:

clone
  < syntax validation
  < integrity validation
  < SIGTERM
  < private-state restore
  < rotation
  < activation

The final targeted validation completed green before commit.


🏰 Final parchment

Mediabot can now help rebuild its own castle.

But it does not swing the wrecking ball first.

It fetches the new stones, checks the walls and inspects the replacement wing while everyone is still safely inside the old one.

Only when the candidate is ready does it close the doors for the short switch.

And one door carries a very precise seal:

/home/mediabot/mediabot_v3
on
teuk.org

Not a similar hostname.

Not a subdomain.

Not a machine whose name merely contains the same letters.

The exact production castle stays protected; the others remain free to update. ::: ​​

You must be logged in to reply.