We're going to use *nginx* as the reverse proxy in front of Home
Assistant, as well as the web consoles for Zigbee2MQTT and ZWaveJS2MQTT.
It will provide TLS termination for all of these applications.
Since *nginx* will not start without a certificate and private key file
for HTTPS, the *gen-nginx-cert.service* systemd unit generates a
self-signed certificate if one does not already exist. This ensures
that *nginx* can start by default, but still allows the administrator to
replace the certificate with a trusted one later.
The *nginx* container image has symlinks at `/var/log/nginx/error.log`
and `/var/log/nginx/access.log`, pointing to `/dev/stderr` and
`/dev/stdout`, respectively. The intent here is to send all log
messages to the container runtime. Unfortunately, when the the
container is managed by Podman from a systemd unit, the standard output
and standard error streams are connected to the systemd journal via a
UNIX socket. As a result, the `/dev/stdout` and `/dev/stderr`
pseudo-files cannot be "opened" like normal files or pipes. Thus, to
forward nginx's logs to the systemd journal correctly, we have to do a
bit of trickery. For the error log at least, setting `error_log stderr`
works well; nginx simply writes messages to the existing file
descriptor. Unfortunately, the access log has no such mechanism. For
that, we use nginx's syslog capabilities. The `/dev/log` socket is
bind-mounted into the container, and nginx is configured to connect to
it.
We'll use BURP for backups, just like the old Home Assistant server.
Note that Portage cannot correctly set the ownership of files when
installing to an alternate $ROOT. To work around this, we replace the
`fowners` function for the *app-backup/burp* ebuild with a no-op, and
then set the permissions of the relevant files using SquashFS
pseudo-file definitions. Relatedly, we're omitting the files and
directories used by the server-side of BURP.
The default Home Assistant configuration does not allow running a
reverse proxy in front of the application. To enable this, the
`use_x_forwarded_for` and `trusted_proxies` options have to be set.
Since we want `/var/lib/homeassistant` to be a Btrfs subvolume, we can't
simply include the necessary files in the correct location in the rootfs
image. Instead, we must define "copy tree" (`C`) actions for
`systemd-tmpfiles` to copy them from `/usr/share/factory`.
Unfortunately, `systemd-tmpfiles` considers `v` and `C` actions
conflicting, and thus will not copy the directory contents recursively.
Each file has to be listed explicitly.
Variants no longer need to specify the full contents of the
`squashfs.exclude` file. The "base" file in the source directory gets
combined with the one from the config directory (if it exists).
There's really no sense in having binary packages for
*sys-boot/raspberrypi-firmware*, since there is no "source" to build.
Having binary packages just wastes space.
Somewhat expectedly, attempting to avoid installing *app-admin/setools*
by listing it in `/etc/portage/profile/package.provided` proved more
trouble than it's worth.
The base Aimee OS build does not need any post-installation tasks.
Custom builds can provide a `post-build.sh` script to implement the
tasks they need. For example, builds targeting Raspberry Pi devices
can use this script to install the firmware files.
The `build.packages` and `install.packages` files in the CONFIGDIR now
only need to include *additional* packages to install. The packages
*required* for Aimee OS are always installed, listed in the
corresponding files in the source directory.
Since the container images we're using as a base for the build system
only contain stable packages, setting ACCEPT_KEYWORDS to allow unstable
packages globally can cause a lot of rebuilds and potentially break
things. Instead, we only set ~arch for the packages we actually need
recent versions on the host.
This does not affect packages installed in the target root, of course.
The persistent journal is stored in a subdirectory of `/var/log/journal`
named for the current machine ID. Since `/etc/machine-id` is not
writable, the machine ID changes with every boot. This effectively
makes the journal for previous boots inaccessible, so there's really not
much point in keeping them around.
In effort to support different builds of Aimee OS using the same
scripts, without necessarily having to fork this repository, the build
system now supports a `CONFIGDIR` setting. When this variable is set,
files defining the target environment, such as the lists of packages to
install, the kernel configuration, the Portage configuration, etc. are
found in the path it specifes.
The reference build, for the Home Assistant Yellow board, is configured
in the `yellow` directory. To build it, run:
```sh
CONFIGDIR=yellow ./vm-build.sh
```