Files
terraria-server-manager/CHANGELOG.md
T
adamandClaude Opus 5.5 85da15a26f add rpm packaging; dnf and firewalld support
- packaging/rpm/terraria-server-manager.spec.in: installs via make
  install, plain scriptlets (no Fedora-only macros) mirroring the deb
  maintainer scripts; removal stops servers, disables boot/backups/
  daemon and removes only terractl's own drop-ins.
- make rpm (rpmbuild --nodeps, works on Debian/Ubuntu); make check
  parses the spec when rpmspec is installed.
- Release workflow builds deb and rpm, attaches both, publishes the rpm
  to Gitea's RPM registry. Job renamed to 'packages'.
- pkg_install: install hints use dnf or apt with the right package
  names (doctor, fetch, python3/openssl checks).
- firewalld: new prints the firewall-cmd command for its port; doctor
  lists instance and daemon ports firewalld doesn't allow.
- Docs, README, AGENTS.md and changelog; VERSION 0.0.13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:54:39 +00:00

17 KiB

Changelog

0.0.13 - unreleased

  • RPM package for Fedora, RHEL 9+ and compatible systems (AlmaLinux, Rocky Linux), built alongside the .deb and published to an RPM repository: add https://gitea.adbraun.lol/api/packages/adam/rpm.repo to /etc/yum.repos.d/ and sudo dnf install terraria-server-manager (see the guide's "Installation"). It installs the same files and works the same way as the Debian package. sudo dnf remove stops all instances (saving their worlds) and turns off starting at boot, scheduled backups and the daemon; worlds, backups and settings are kept. Build it with make rpm (needs rpmbuild, also on Debian and Ubuntu).
  • doctor checks the firewall when firewalld is running (the default on Fedora and RHEL): it lists instance ports, and the daemon's, that firewalld doesn't allow, with the firewall-cmd command to open them. new shows that command too. Opening ports is never done automatically.
  • Messages that suggest installing something (doctor, fetch, and when python3 or openssl is missing) now give the dnf install command on Fedora and RHEL instead of apt install, with the right package names (libicu, polkit).

0.0.12 - 2026-10-02

  • New fetch command to download server zips into dist/, named with their version:
    • terractl fetch tmodloader [<version>] downloads from tModLoader's GitHub releases (default: the latest stable) and checks it against the SHA-256 checksum GitHub publishes. terractl fetch vanilla [<version>] downloads from terraria.org (default: its newest; older versions by number, 1449 or 1.4.4.9).
    • --list shows the versions available (tModLoader: stable and preview), and which are already downloaded. --upgrade <name> switches an instance to the zip with upgrade right after.
    • Every zip is checked (complete, and the right kind) before it's put in dist/; zips already there aren't downloaded again. If a site doesn't have the version or can't be reached, it says so and where to download it by hand.
    • Members of the terraria group can use it without sudo (except --upgrade). Needs curl.
  • Scheduled backups, with a systemd timer per instance (terraria-backup@<name>.timer):
    • sudo terractl backup enable <name> [--every <when>] [--keep <number>] (default: daily, keeping the newest 14). --every takes hourly, daily, weekly, a time such as 04:30, or any systemd calendar expression. Missed backups are made after the machine starts again.
    • backup now <name> makes one immediately, backup disable <name> stops the schedule (existing backups are kept), and backup list [<name>] shows schedules, the last and next run, and the backups.
    • Each backup saves the world first if the server is running (as export does) and goes in /var/lib/terraria/backups/<name>/ (TERRARIA_BACKUPS in /etc/default/terractl), readable by the terraria group. Only scheduled backups are pruned.
    • rename takes the schedule along, delete turns it off, and purging the package removes the schedules (not the backups).
  • New doctor command: terractl doctor [<name>] [--fix] checks the system (user, programs including ICU and curl, folders, zips, the systemd units and old copies in /etc that replace them, sandbox access to moved folders, journal access, polkit, the daemon, leftovers of deleted instances) and each instance (file ownership and modes, its server zip, paths in serverconfig.txt, missing mods, shared ports, failed starts and backups). Each problem comes with the command that fixes it. --fix applies the safe fixes: fix-perms, folder and zip permissions, journal access, the ReadWritePaths= drop-in for moved folders, and boot links or backup schedules of instances that are gone. It exits with status 1 if a problem remains.
  • The daemon (terractld.service) may now write to /etc/systemd/system, so backup enable and doctor --fix also work through --host.
  • Warnings about moved folders now also suggest terractl doctor --fix.
  • New upgrade command to change an instance's server version, up or down:
    • terractl upgrade <name> lists the zips in dist/ for its type, marking the installed, pinned and newest ones. The terraria group can use it without sudo.
    • sudo terractl upgrade <name> <zip>|latest checks the zip first (right type, readable by terraria, contains the server, passes unzip -t), stops the server (saving the world), backs up its worlds and configs to /var/lib/terraria/backups/<name>/, pins ZIP=, unpacks the zip right away and starts the server again if it was running. If unpacking fails, the instance is left as it was. --no-backup skips the backup.
    • Going to an older version needs --downgrade, because worlds saved by a newer version can't be opened by an older one.
    • Bash completion offers the instance's zips. Works with --host.
  • reinstall now always unpacks the same version again. Before, an instance with a blank ZIP= picked the newest zip in dist/, so reinstall could silently upgrade it. It now pins the zip the instance runs first, and refuses if that zip is gone from dist/. It also keeps the record of the installed version (server/.installed) until the new unpack is done.
  • list, new, import and enable warn when TERRARIA_BASE or TERRARIA_DIST is somewhere the services' sandbox doesn't allow (the instances folder not in ReadWritePaths=, or either folder under /home), and print the exact drop-in to add. The daemon (terractld.service) is checked too when it's on. A server that can't create its folder now says why in its log, instead of only "Read-only file system".
  • The guide's "Changing locations" now covers bind mounts (the simplest way to use another disk) as well as drop-ins, and a new section explains keeping instances or zips under /home.
  • journal-access is offered by tab completion and listed in the guide's command reference.
  • upgrade, and prepare/run started as root, check first that the terraria user can run the terractl being used. A copy under /root is refused with an explanation, before upgrade stops the server, instead of failing with env: Permission denied.
  • terractl run by a relative path (e.g. sudo ./bin/terractl prepare <name> from a source tree) no longer fails to switch to the terraria user.
  • New fix-perms command: sudo terractl fix-perms <name> gives every file of an instance back to the terraria user and reapplies the usual modes (group can read, others nothing; server binaries executable), e.g. after copying worlds in as root. Symlinks are not followed. Works with --host too.
  • list warns about zips in dist/ that the terraria user can't read (e.g. copied in with scp -p from a private file), and info lists them as unreadable_zip=. A server that fails to install because of one now says how to fix it (sudo chmod 644 <zip>) instead of just "cannot read", and a missing zip is reported as not found.

0.0.11 - 2026-09-30

  • The servers now log to their own journal (systemd log namespace terraria), which members of the terraria group can read. attach and cmd therefore show output to terraria group members without sudo or the systemd-journal group, and without access to the rest of the system's logs. Read it directly with journalctl --namespace=terraria -u terraria@<name>.
  • New /etc/systemd/journald@terraria.conf for the servers' journal size and retention (default: up to 256 MB).
  • New internal terractl journal-access, run as root before each server start: creates the servers' journal folder (never /var/log/journal itself) and gives the terraria group read access, repairing existing journal files too.
  • The note shown by attach and cmd when output can't be read now distinguishes "not in the terraria group" from "in it, but the journal isn't set up yet".
  • New polkit rule (/usr/share/polkit-1/rules.d/50-terractl.rules): members of the terraria group can systemctl start, stop and restart terraria@<name> without sudo. enable, disable and all other units still need root. Needs polkitd 0.106 or newer, now a recommended package; Ubuntu 22.04's polkit can't run the rule.
  • New enable and disable commands: terractl enable <name> [--now] makes a server start at boot (--now also starts it), terractl disable <name> [--now] stops that (--now also stops it, saving the world). They need root, like systemctl enable. enable refuses names without an instance, so a typo can't create a new instance at boot. new and import now suggest terractl enable <name> --now.
  • list has a new BOOT column showing whether each server starts at boot (enabled, disabled, or e.g. masked).
  • Manage other hosts, like LXD/Incus remotes:
    • sudo terractl daemon enable starts terractld.service, a daemon other hosts connect to (HTTPS, TCP port 7776; TERRACTL_LISTEN in /etc/default/terractl changes it). It's off until enabled. daemon disable and daemon status turn it off and show its state.
    • daemon enable prints a command with a one-time token (valid for 24 hours); running it on another computer, terractl remote add <token>, adds the host as a remote named after its hostname (or remote add <name> <token>). sudo terractl daemon token makes tokens for more computers, daemon status lists the trusted ones, and daemon revoke <name> removes one. Adding a host again replaces the old remote, e.g. after a revoke. remote list and remote remove manage remotes, which are stored per user.
    • terractl --host <remote> <command> runs any command on a remote, including attach, watch and export/import/mods add with files from your computer. The daemon runs it as root there, with messages adjusted to terractl --host <remote> ....
    • terractl copy and terractl move copy, move or rename instances, on one host or between hosts ([<remote>:]<name>). Paths and ports follow the destination's settings, and a missing server zip is copied along. move stops the source first, starts it again if the transfer fails, and starts the moved instance where it was running before.
    • Security: the token carries the daemon's certificate fingerprint, which the client checks on every connection; each computer gets its own key, and the daemon stores only hashes. The daemon runs as root with systemd sandboxing.
    • Written in Python (standard library only), in /usr/lib/terraria-server-manager/terractl-remote. The package now depends on python3 and openssl.
  • New start, stop and restart commands, the same as systemctl start|stop|restart terraria@<name>, for this host and for --host. start refuses names that have no instance. The service's own stop step is now terractl service-stop; units that still call terractl stop <name> <pid> keep working.
  • New rename command: terractl rename <name> <new name> renames the folder, updates serverconfig.txt, and carries over the service (stopped and started again if it was running, and still starting at boot). The port and unpacked server are kept. move within one host uses it.
  • New info command: this host's folders, zips and instances, or an instance's type, port, server zip and state, as key=value lines.
  • import replaces a ZIP= pin that's an absolute path not present on this host with the zip of the same name in this host's dist/.
  • Messages that suggest a command now suggest terractl commands (terractl stop <name> rather than systemctl stop terraria@<name>), with sudo only when it's needed: not in a root shell, and not for terraria group members starting, stopping or restarting a server.
  • New watch command: terractl watch <name> [-n <lines>] [-q] follows the server's output like attach, but never sends input, so it's safe to leave open. Works for the terraria group without sudo, and while the server is stopped. -q leaves out the lines about what it's doing.
  • Bash completion for the new commands, remote names after --host, and <remote>:<name> for copy and move.
  • Clearer messages when run or prepare is typed without sudo (the old one, "must run as root or 'terraria'", read as if the terraria group were enough), and when stop is typed by hand.
  • Upgrading: running servers keep logging to the system journal until restarted; the package lists the ones to restart.

0.0.10 - 2026-09-30

  • cmd now prints the server's reply to the command, instead of only saying where to find it. It waits until the server has been quiet for a second, up to 5 seconds.
  • attach and cmd now explain when you can send commands but not see the server's output. That happens for members of the terraria group who aren't root or in systemd-journal. Previously attach showed nothing, without saying why.
  • Replaced a ${var:+...} expansion with an explicit if in import's summary message (ShellCheck SC2016). The output is unchanged.

0.0.9 - 2026-09-28

  • New export command: terractl export <name> [file.tar.gz] [--with-server] archives an instance's instance.conf, serverconfig.txt and data/ (worlds, mods, mod configs). If the server is running under systemd, it is asked to save first. Archives are created readable only by their owner, since serverconfig.txt can contain the server password. --with-server also includes the unpacked server software (and tModLoader's .NET), for hosts without internet access.
  • New import command: terractl import <name> <file.tar.gz> creates an instance from an export, a delete backup, or an archive of an old /opt/terraria instance. Archives are checked before extracting (no paths outside the instance folder, no links or special files). Paths in serverconfig.txt are updated, a port already used by another instance is replaced with a free one, the server version the world was exported with is pinned, and ownership is set to the terraria user.
  • One server per instance: run holds a lock (<instance>/.lock) for the server's whole lifetime, released automatically when it exits or crashes. A second run, or starting the service while a copy started by hand is running, is refused.
  • prepare and reinstall --clean refuse to run while the instance's server is running, so server/ and .NET are never replaced or deleted under it.
  • delete refuses to continue if the server is still running outside systemd.
  • list shows servers started by hand as running (outside systemd).
  • stop typed by hand now explains to use systemctl stop instead of silently doing nothing.
  • Fixed relative paths given on the command line (e.g. terractl mods <name> add tmod-export) being looked up from / instead of the current directory.
  • Bash completion for export and import.

0.0.8 - 2026-09-28

  • Bash completion for terractl: commands, instance names, new types, console commands for cmd, reinstall/delete options, and mods actions and mod names. Installed to share/bash-completion/completions/terractl by both make install and the package.

0.0.7 - 2026-09-28

  • Fixed ShellCheck warnings that made make check (and therefore make deb) fail when ShellCheck is installed: simplified the development-copy check in --version (SC2140), and marked the intentional unquoted unit list in prerm (SC2086).

0.0.6 - 2026-09-28

  • Renamed the command from terraria-instance to terractl, and the package from terraria-instance to terraria-server-manager. The new package replaces the old one automatically; see "Upgrading from the terraria-instance package" in the guide.
  • Settings file moved from /etc/default/terraria-instance to /etc/default/terractl.
  • New terractl --version.
  • New Makefile: make check, make deb, make install, make uninstall.
  • Restructured the source into a git repository layout.

0.0.5 - 2026-09-28

  • Fixed attach: detaching with Ctrl-D printed "jpid: unbound variable" and left a journalctl process running.

0.0.4 - 2026-09-28

  • The .NET runtime that tModLoader downloads on first start (and its logs) is now kept when an instance is upgraded or re-unpacked.
  • New reinstall --clean to discard .NET as well and download it again.

0.0.3 - 2026-09-28

  • New mods command: list, add, enable, disable, remove. Accepts the Windows export folder directly and sets file ownership.
  • new and prepare now create data/Mods for tModLoader instances.

0.0.2 - 2026-09-28

  • Fixed prepare failing for tModLoader zips when run as root from a directory the terraria user can't enter (e.g. /root).

0.0.1 - 2026-09-28

  • First Debian package. Uses /var/lib/terraria instead of /opt/terraria and /terraria, creates the terraria user and directories with sysusers.d and tmpfiles.d, and stops instances cleanly when removed.
  • prepare and run switch to the terraria user when started as root, so no files end up owned by root.
  • New delete command, with an automatic backup.
  • list no longer aborts when an instance's config can't be read.