_ _
| |_(_)_ __ _ _ _ __ ___ _ __ ___
| __| | '_ \| | | | '__/ _ \ '_ \ / _ \
| |_| | | | | |_| | | | __/ |_) | (_) |
\__|_|_| |_|\__, |_| \___| .__/ \___/
|___/ |_|
small local package repositories, one binary, no daemon
what it is
tinyrepo is a command line tool written in
Go that builds small local repositories for
Debian and its derivatives, and for
Arch Linux / Manjaro. Pick the format with type in
config.toml; the commands are the same for both.
It names the packages it wants, resolves their dependencies against the real upstream index, downloads only what that closure needs, and publishes the result over HTTP. No database, no daemon, no runtime dependencies.
quick start
$ ./tinyrepo -gc > config.toml # example config for Debian (-ga for Arch)
$ nano config.toml # set the mirror, the path and the packages
$ ./tinyrepo -di -ci -dp # download indexes, build the repo, download packages
$ ./tinyrepo -ws # publish it over HTTP
flags
| flag | what it does |
|---|---|
-di | download the package indexes from the mirror |
-ci | resolve the requested packages and build the repository |
-dp | download the packages themselves |
-ws | serve the repository over HTTP, until Ctrl+C |
-cl | remove packages that config.toml does not ask for |
-vp | check that every requested package exists on the mirror |
-gc / -ga | print an example config.toml for Debian / Arch |
-ec | list the exit codes |
-pw | hash a password for the web config panel, printed to stdout |
-sp | ask for a password and write it into config.toml |
-gs / -gr | print a systemd unit / an OpenRC service (Alpine) |
-help | show the help |
on demand
By default the repository is closed: it holds exactly the
packages config.toml asks for. Turn on onDemand and the
published index becomes the whole upstream archive, while the disk only ever
fills with what somebody actually installed — the first request for a package
streams it from the mirror to the client and to disk at the same time, and its
dependencies are warmed in the background.
checking the package list
-vp answers the question a typo raises: does the mirror really
have this name? It reads the index -di already cached, so it costs
nothing, and it exits 18 if anything is missing — straight into a CI job. The
same check is a button in the web panel.
$ ./tinyrepo -di -vp
MISSING nanoo nothing on the mirror answers to this name
ok astrometry-data-2mass in the index
finding packages to add
The panel's available tab is the mirror's whole catalog — ~64,000
packages for a Debian suite — searchable by name or description and paged, with
a button on each row that adds the name to [destination].packages.
The index is parsed once and kept until it changes, so the page stays quick. Its
downloaded tab answers the other question: what is on disk here.
web config panel
-ws can also publish /admin: a form that edits
config.toml, buttons that run the four actions with the log of
whichever is running, and the package check above. Off by default and behind a
login — the password is hashed with PBKDF2-SHA256, sessions are
HttpOnly and SameSite=Strict, every write carries a
CSRF token, and the panel ships no JavaScript at all.
$ ./tinyrepo -sp # asks for a password, writes it into config.toml
$ ./tinyrepo -pw # ...or just prints the hash, to place by hand
-sp rewrites the one passwordHash line and leaves
every comment exactly as it was. It refuses a field that is commented out — the
sample configs ship it that way — and says which line to uncomment.
the package list in the panel
/admin/packages lists every package file actually in the
repository — name, version, architecture, size and date — paged, filterable, and
each name links to the file. On demand the repository fills with packages nobody
declared, so one switch shows just those: exactly what -cl would
remove. A button on each row adopts a name into
[destination].packages or drops it again — which changes what the
next run does, not what is on disk now.
pointing a client at it
Debian — add it to sources.list:
deb [trusted=yes] http://<host>/ tinyrepo main
Arch / Manjaro — add it to /etc/pacman.conf:
[tinyrepo]
SigLevel = Optional TrustAll
Server = http://<host>/
Neither generated repository is signed, so each one has to be trusted explicitly. Publish it on a network you control, or behind TLS: over plain HTTP these lines tell the package manager to install whatever answers. Individual pacman packages keep their upstream signature.
running it as a service
Both files are filled in from where the binary and its config.toml
actually are, so there is nothing left to edit. The systemd unit is sandboxed —
ProtectSystem=strict, an empty capability set, and
ReadWritePaths naming only the repository directory.
$ ./tinyrepo -gs | sudo tee /etc/systemd/system/tinyrepo.service
$ ./tinyrepo -gr > /etc/init.d/tinyrepo # alpine
get it
$ git clone https://github.com/osniel/tinyrepo
$ cd tinyrepo
$ go build -ldflags="-s -w" -o tinyrepo ./cmd/tinyrepo