rostainer-archive
A rostainer plugin that archives a workspace's ROS logs and bags, and fetches the archives from deployed robots.
- On every container start (dev containers and packages alike), the
contents of the log directories move into an archive, with a snapshot of
the workspace's SQLite databases, and are tarred to
<archive_dir>/tar/<time>.tar.gz. Anything still open by a process (a node's log, a bag being recorded) is left for the next rotation, so nothing is archived half-written. rostainer archive rotaterotates now, in the workspace's running dev container(s), while ROS keeps running. On a robot, the installed package's own./rostainer archive rotatedoes the same.rostainer archive fetch [TARGET_OR_GROUP ...]downloads the tarballs from the robotsrostainer deploydeploys to, over the same ssh connections. There's no second list of hosts.
Install
pipx inject rostainer rostainer-archive # or: pip install rostainer-archive
It needs the deploy plugin (rostainer-deploy), which pip installs with it.
In the workspace's .rostainer.toml:
# Refuse to start without it, rather than run without log rotation.
requires_plugins = ["archive"]
[plugins.archive]
dirs = [".ros/log", "bags"] # archived; in the container, relative to the user's home
database_dir = "database" # SQLite *.db snapshotted (not moved) into each archive; "" for none
archive_dir = "archive" # where archives go
keep_unpacked = true # keep each archive's directory next to its tarball
download_dir = "~/rostainer-logs" # where 'fetch' saves, in a directory per target
rostainer init --with archive adds the table, with each setting described.
Mount the directories from the host with volume_mappings, so the logs and
archives outlive the container, and fetch can reach them:
volume_mappings = [
"data/logs:/home/$USER/.ros/log",
"data/bags:/home/$USER/bags",
"data/archive:/home/$USER/archive",
]
rostainer's own ROS log pruning starts before the plugin's rotation, so it could delete logs before they're archived. Turn it off:
ros_log_max_size_mb = 0
ros_log_max_age_days = 0
Rotation
The plugin's rotate.sh runs as a post-build hook: on every start, before
the workspace's own post-build script. Its files are at
/usr/local/lib/rostainer/plugins/archive/ in the container. A failed
rotation is a warning, and the start goes on.
Archives go to <archive_dir>/<time>/{log,bags,database}/ and
<archive_dir>/tar/<time>.tar.gz. The time is the newest archived file's
modification time, in the container's timezone (UTC by default). Only the
top-level entries of each directory are considered, so a bag directory or
a launch's run directory is archived whole or not at all. Hidden entries
and symlinks (ROS 1's latest) stay.
rostainer archive rotate # every running dev container of the workspace
rostainer archive rotate my_container # any container with the plugin's files
./rostainer archive rotate # on a robot, in the installed package's directory
Both run the plugin's rotate command inside the container, with the
settings that container (or package) was started or made with. Neither
needs a TTY, so either can run from cron or a systemd timer.
Fetching
rostainer archive fetch # the newest archive of every enabled robot
rostainer archive fetch divers --all # every archive, from a group
rostainer archive fetch robot1 --since 2026-10-23T00:00:00Z
rostainer archive fetch robot1 --rotate --delete
Robots are picked as rostainer deploy picks them: by name, by group from
[plugins.deploy.groups], or all (the default). Several are reached at
once, and one that fails doesn't stop the others.
On each robot, fetch finds the package's container (./rostainer container), and where archive_dir is mounted from on the robot
(docker inspect). It then downloads the tarballs into
<download_dir>/<target>/, or --output-dir DIR.
--since TIMEtakes every tarball modified at or after TIME, an ISO 8601 time with a timezone.--rotaterotates first, in the package's running container (./rostainer archive rotate, with the package's own settings).--deletedeletes each tarball on the robot once it's here and verified, after checking the robot's copy again. The unpacked directories stay.
Each download is checked against the robot's SHA-256 before it takes its name, so a file is never left half-written. A tarball that's already here with the same hash is skipped. One that's here but different is never overwritten.
fetch uses the settings of this checkout: keep archive_dir as it was
when the robot's package was made.
Tests
python -m unittest discover tests
Metadata
Release files for rostainer-archive 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| rostainer_archive-0.0.2.tar.gz | 12.3 MB | Without provenance | Details for rostainer_archive-0.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| rostainer_archive-0.0.2-py3-none-any.whl | Python 3 | none | any | Details for rostainer_archive-0.0.2-py3-none-any.whl |
Total release size: 12.3 MB
Release files / rostainer_archive-0.0.2.tar.gz
| Download URL | rostainer_archive-0.0.2.tar.gz |
|---|---|
| Size | 12.3 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4ff6c4424748d898b657ccd541d30bf01cf9d5df156c9c791aba8c8f552f156
|
|
BLAKE2b-256 checksum How to use checksums |
78fb3cd8a50d39eeb5dcd3dcca2fbe7ca0bdab19b3b1bf46568b0be9d7f62baf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.18
|
Release files / rostainer_archive-0.0.2-py3-none-any.whl
| Download URL | rostainer_archive-0.0.2-py3-none-any.whl |
|---|---|
| Size | 11.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ef9b86c14e92c109a9ec7989f0800990a32aba2efc3690337bc7255f56b80f7
|
|
BLAKE2b-256 checksum How to use checksums |
eb94bb35a8e93173e253ec36a9d2b0882481c091e83507b819d7daea2a0de738
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.18
|
Security for rostainer-archive 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.