Aspic
A signed package repository. Add it once with the snippet for your system, then install and update everything on it through your normal package manager.
install its name. Each project has its own page explaining what
it is and how to run it; this page is only about getting the repository in
place.Nothing is signed on this host. Packages and indexes are signed on a workstation and pushed here as static files, so a compromise of this box can serve you something stale or missing but cannot forge a package your package manager will accept. That is what the key in every snippet below is for.
Breeze Core
breeze-core — self-hosted, LAN-first control for Midea air conditioners: REST API, web panel, schedules and temperature curves.
Breeze
.apk — the Android app for Breeze Core: one air conditioner per screen, widgets and schedules. Android 7.0+.
Debian family
Debian · Ubuntu · Mint · Pop!_OS · Raspberry Pi OS · Devuan —apt
# the key gets its own keyring, named by the sources entry that uses it
curl -fsSL https://aspic.salataputarica.hr.eu.org/aspic.asc \
| sudo gpg --dearmor -o /usr/share/keyrings/aspic.gpg
echo "deb [signed-by=/usr/share/keyrings/aspic.gpg] https://aspic.salataputarica.hr.eu.org/deb stable main" \
| sudo tee /etc/apt/sources.list.d/aspic.list
sudo apt update
amd64 · arm64 · armhf (every Raspberry Pi, the Zero included) · i386 · riscv64 · ppc64el · s390x · loong64.
Fedora / RHEL family
Fedora · RHEL · AlmaLinux · Rocky · CentOS Stream —dnf
# import the key first: dnf 5 will not fetch it from gpgkey= on its own
sudo rpm --import https://aspic.salataputarica.hr.eu.org/aspic.asc
sudo curl -fsSL -o /etc/yum.repos.d/aspic.repo \
https://aspic.salataputarica.hr.eu.org/rpm/aspic.repo
sudo dnf makecache
repo_gpgcheck=1, so the metadata is verified and
not only the packages, and metadata_expire=1h. dnf's default
is 48 hours: once it has refreshed it will not look here again for
two days, so a release published inside that window stays invisible and the
only apparent cure is dnf clean all.x86_64 · aarch64 · armv7hl · riscv64 · ppc64le · s390x · loongarch64 (openEuler).
openSUSE / SLE
Leap · Tumbleweed · SLES —zypper
sudo rpm --import https://aspic.salataputarica.hr.eu.org/aspic.asc
# swap x86_64 for your architecture
sudo zypper addrepo --refresh --gpgcheck \
https://aspic.salataputarica.hr.eu.org/rpm/x86_64/ aspic
sudo zypper --gpg-auto-import-keys refresh
The same rpms as the section above — zypper just adds and refreshes repositories its own way.
Arch family
Arch · Manjaro · Artix · EndeavourOS —pacman
# fetch once, then add and locally sign the key by its fingerprint
curl -fsSL -o /tmp/aspic.asc https://aspic.salataputarica.hr.eu.org/aspic.asc
sudo pacman-key --add /tmp/aspic.asc
sudo pacman-key --lsign-key "$(gpg --show-keys --with-colons /tmp/aspic.asc \
| awk -F: '/^fpr/{print $10; exit}')"
sudo tee -a /etc/pacman.conf <<'EOF'
[aspic]
SigLevel = Required
Server = https://aspic.salataputarica.hr.eu.org/arch/$arch
EOF
sudo pacman -Sy
x86_64 · aarch64 · armv7h. SigLevel = Required
makes pacman refuse both an unsigned database and an unsigned package,
which is the point of adding the key at all.
Alpine
Alpine Linux, and anything else usingapk
# apk needs RSA — it has no ed25519 option, so this key is its own sudo curl -fsSL -o /etc/apk/keys/aspic-alpine.rsa.pub \ https://aspic.salataputarica.hr.eu.org/aspic-alpine.rsa.pub # no architecture in the URL: apk appends it itself echo "https://aspic.salataputarica.hr.eu.org/alpine" \ | sudo tee -a /etc/apk/repositories sudo apk update
x86_64 · x86 · aarch64 · armv7 · armhf · riscv64 · ppc64le · s390x, and
big-endian ppc64 for Adélie Linux, which uses the same apk. Without
that key in /etc/apk/keys, apk refuses the index rather than
asking you about it.
OpenWrt
Two feeds, because OpenWrt 25.12 replaced opkg with apk-tools 3 — each signed with OpenWrt's own kind of key# OpenWrt 25.12 and later: apk . /etc/openwrt_release wget -qO /etc/apk/keys/aspic-openwrt.pem https://aspic.salataputarica.hr.eu.org/aspic-openwrt.pem echo "https://aspic.salataputarica.hr.eu.org/openwrt-apk/$DISTRIB_ARCH/packages.adb" \ >> /etc/apk/repositories.d/customfeeds.list apk update && apk add breeze-core # OpenWrt 24.10 and older: opkg . /etc/openwrt_release wget -qO /tmp/aspic-usign.pub https://aspic.salataputarica.hr.eu.org/aspic-usign.pub cp /tmp/aspic-usign.pub /etc/opkg/keys/$(usign -F -p /tmp/aspic-usign.pub) echo "src/gz aspic https://aspic.salataputarica.hr.eu.org/openwrt/$DISTRIB_ARCH" \ >> /etc/opkg/customfeeds.conf opkg update && opkg install breeze-core
x86_64 · aarch64_generic · aarch64_cortex-a53 ·
aarch64_cortex-a72 · arm_cortex-a7_neon-vfpv4 · arm_arm1176jzf-s_vfp
(Raspberry Pi Zero and 1) · i386_pentium4 · riscv64_riscv64 ·
loongarch64_generic · mipsel_24kc (MediaTek: MT7621, MT76x8) ·
mips_24kc (Atheros: ath79) · mips64_octeonplus (Cavium
Octeon: EdgeRouter) — the MIPS ones being what most routers are. $DISTRIB_ARCH
is your router's exact package architecture, which is what both feeds are
laid out by. For opkg, the key file has to be named after its own
fingerprint: opkg looks it up by that name, so a sensible filename silently
fails to verify. apk does not care what the key file is called.
Termux
Android, inside the Termux app — Termux's ownapt, the same key as Debian
# no sudo: everything belongs to the Termux app, under $PREFIX
mkdir -p $PREFIX/etc/apt/keyrings $PREFIX/etc/apt/sources.list.d
curl -fsSL https://aspic.salataputarica.hr.eu.org/aspic.asc \
-o $PREFIX/etc/apt/keyrings/aspic.asc
echo "deb [signed-by=$PREFIX/etc/apt/keyrings/aspic.asc] https://aspic.salataputarica.hr.eu.org/termux stable main" \
> $PREFIX/etc/apt/sources.list.d/aspic.list
pkg update && pkg install breeze-core
aarch64 · arm · x86_64. A real Android build rather than the
static Linux one, so it reads the phone's own timezone and schedules fire
at the right hour. It runs under termux-services and is installed
switched off: pair a unit, then sv-enable breeze-core.
termux-wake-lock so it keeps running with the screen off, and
add the Termux:Boot add-on to start it after a reboot.FreeBSD
A real RSA-signedpkg repository — amd64,
built and verified on FreeBSD 15.1
sudo mkdir -p /usr/local/etc/pkg/keys /usr/local/etc/pkg/repos
sudo fetch -o /usr/local/etc/pkg/keys/aspic.pub \
https://aspic.salataputarica.hr.eu.org/freebsd/aspic-freebsd.pub
sudo tee /usr/local/etc/pkg/repos/aspic.conf <<'EOF'
aspic: {
url: "https://aspic.salataputarica.hr.eu.org/freebsd",
signature_type: "pubkey",
pubkey: "/usr/local/etc/pkg/keys/aspic.pub",
enabled: yes
}
EOF
sudo pkg update && sudo pkg install breeze-core
# then enable and start it
sudo sysrc breeze_core_enable=YES
sudo service breeze_core start
The package declares no dependencies — the Python line
needed python312 and a wheel for every extension — and keeps
/usr/local/etc/breeze-core on deinstall, so an upgrade over
3.2.0 leaves your config and device tokens alone. This repository is the
only one here whose catalogue is signed on the machine that builds it,
because pkg repo signs locally; the key goes there, gets used,
and is destroyed with rm -P.
NetBSD
Apkgin feed — amd64, built on a real NetBSD
machine because nothing cross-builds for it
echo "https://aspic.salataputarica.hr.eu.org/netbsd/All" \
> /usr/pkg/etc/pkgin/repositories.conf
pkgin -y update && pkgin -y install breeze-core
# or, without pkgin:
pkg_add https://aspic.salataputarica.hr.eu.org/netbsd/All/breeze-core-4.3.2.tgz
pkg_add's
GPG support wants a signed-package format this does not use — so what you
get is HTTPS and nothing more. Every other section on this page verifies a
signature made off this host; this one does not, and it would be dishonest
to imply otherwise.The package declares no dependencies at all — where the
Python line needed python312 — and installs over it in place
with pkg_add -U, keeping
/usr/pkg/etc/breeze-core.
OpenBSD
Asignify-signed package — amd64, built and
verified on OpenBSD 7.9
# the key's filename is not cosmetic - see below doas ftp -o /etc/signify/aspic-pkg.pub \ https://aspic.salataputarica.hr.eu.org/openbsd/aspic-pkg.pub doas pkg_add https://aspic.salataputarica.hr.eu.org/openbsd/7.9/packages/amd64/breeze-core-4.3.2.tgz doas rcctl enable breeze_core && doas rcctl start breeze_core # optional: let `pkg_add -u` find this repository too export PKG_PATH="https://aspic.salataputarica.hr.eu.org/openbsd/%c/packages/%a/:$(cat /etc/installurl)/%c/packages/%a/"
pkg_add reads the signing key's name out of the
package's signature and then opens
/etc/signify/<that name>.pub. Save it as anything else
and every install fails with signify: can't open
/etc/signify/aspic-pkg.pub — which is also exactly what you get if
you skip the key, so the refusal is the feature.Release-specific on purpose: OpenBSD moves its libc every six
months, so the path carries 7.9 rather than pretending one
build serves every release. The service account comes from the packing
list (@newuser), so pkg_delete takes it away
again, and /etc/breeze-core is a @sample — an
edited config is never overwritten and never removed. This is the first
OpenBSD package the project has had: the Python line could only
manage a source install here, because a virtualenv full of absolute paths
is not something you can hand to pkg_add.
Void Linux
xbps, glibc and musl alikeecho "repository=https://aspic.salataputarica.hr.eu.org/xbps" | sudo tee /etc/xbps.d/20-aspic.conf sudo xbps-install -S breeze-core
x86_64 · aarch64 · armv7l · armv6l · riscv64 · ppc64le, each in both glibc and musl flavours, and i686 — thirteen packages holding the same bytes per architecture, because the binary is static and does not care which libc you run, but xbps keeps separate repodata per architecture and would otherwise show the package to only half of Void. No dependencies at all.
The package ships the runit service disabled, which is what Void expects. Enabling it is one symlink, and the breeze-core page has that plus the other twelve init systems.
0a:9c:c0:1b:79:2c:eb:7a:97:70:3d:a3:f0:4b:db:22 — also published at
/aspic-xbps.fingerprint, so you can
compare rather than accept it blind.Gentoo
An overlay,app-misc/breeze-core-bin
# needs app-eselect/eselect-repository
sudo eselect repository add aspic git \
https://aspic.salataputarica.hr.eu.org/portage/breeze.git
sudo emerge --sync aspic
sudo emerge -av app-misc/breeze-core-bin
A -bin package, which on Gentoo usually needs an
apology and here does not: the binary is statically linked, so it is
independent of your USE flags, your CHOST and your libc, and there is
nothing a local build could specialise. Ships both an OpenRC service and
a systemd unit, plus acct-user/breeze and
acct-group/breeze so the account is managed the Gentoo way
rather than by a script.
On Gentoo the settings live in
/etc/conf.d/breeze-core, not in breeze-core.env.
Enabling and starting it:
the breeze-core page.
/etc/portage/repos.conf/aspic.conf holding
[aspic], location = /var/db/repos/aspic,
sync-type = git and
sync-uri = https://aspic.salataputarica.hr.eu.org/portage/breeze.git.
There is no git server here — it is a plain static tree, which git clones
and pulls from perfectly well.arm keyword covers armv4 through armv7 and both
float ABIs, while the prebuilt binary is ARMv6 hard-float (which every
ARMv7 hard-float machine also runs). The ebuild checks your CHOST and
refuses soft-float and older ARM with an explanation rather than
installing something that cannot run. ppc64 covers both
endiannesses, and both binaries exist: it picks the one your CHOST is.
x86 needs SSE2.Homebrew
macOS, Apple silicon and Intel · Linux, x86-64 and ARM64 —brew
brew tap aspic/breeze https://aspic.salataputarica.hr.eu.org/homebrew/breeze.git brew trust aspic/breeze brew install breeze-core
brew trust is Homebrew's own step for any
tap outside its core, asked once: it loads no formula from a tap you have
not trusted.
One formula for both systems, installing a prebuilt binary:
on a Mac one built for macOS 13 or newer, on Linux the same static binary
the packages above carry, so any distribution will do. The formula pins
each download by its SHA-256 and itself comes over this site's HTTPS, and
brew upgrade picks up each release.
Its files live in $(brew --prefix)/etc/breeze-core,
and brew services start breeze-core runs it while you are
logged in. Setting it up:
the breeze-core page. Like the Gentoo
overlay, the tap is a plain static git repository; there is no git server
here.
OPNsense
A GUI plugin,os-breeze-core — one package,
installed by hand
pkg add https://aspic.salataputarica.hr.eu.org/opnsense/os-breeze-core-4.3.2.pkg
# then: Services > Breeze Core - set the listen address, then enable
Not a repository, deliberately: your firewall already has
pkg pointed at its own mirrors with its own ABI and its own
trust, and adding a third-party repository to a firewall is a much bigger
ask than fetching one file. Built on FreeBSD 14 and installs on both
OPNsense 26.1 (FreeBSD 14) and 26.7 (FreeBSD 15) — the ordinary FreeBSD
package above is built on 15, and FreeBSD binaries run forward, not
backward. No dependencies, where the
Python plugin vendored an entire interpreter, so nothing is ever compiled
on the firewall and nothing breaks when OPNsense changes its Python.
About this host
aspic.salataputarica.hr.eu.org — a small server on a domestic connection, so be kind to it| serves | static files over HTTPS, GET and
HEAD only; every other method is refused |
| holds | no key, no account, no database — verification happens on your machine, against the keys above |
| deploys | as a timestamped release with an atomically
swapped current symlink, so a push is never half-visible
and rolling back is one symlink |
| logs | request lines, for rate limiting and for spotting scanners. Nothing else is collected, and there is nothing here to collect it with |
| indexing | asked off, site-wide. Links are how anyone gets here |
| aria2 | every file you would download by hand — an
installer, an APK, a tarball — has a Metalink beside it, the same name
plus .meta4. aria2c given one fetches from
aspic and the project's GitHub release at once, and checks every
megabyte against its SHA-256 as it arrives. Range requests are served,
up to 24 connections at a time |