Building A DIY Fedora IoT OSTree
Now being fired up let’s familiarize ourselves with the essentials around Fedora IoT and OSTree to get our custom build going. What we are going to do is:
- Clone the upstream Fedora IoT git repository containing their OSTree configuration
- Merge our own repository with the custom configs into upstream
- Init an RPM-OSTree repository
- Build our first commit based on the merged configuration
There is one severe thing I want to get out of the way before we proceed: building the Fedora IoT OSTree does only work properly on SELinux enabled host systems. That’s because upstream Fedora IoT comes with SELinux enabled and I don’t want to mess with that. It’s certainly possible but out of scope to do this on other systems, at least for now. So if you are currently running Debian, Ubuntu or anything else without SELinux shipped (and enabled) you’ll probably have to resort to the automated CI approach I’ll be tackling in the future.
Let’s Have Some Fun
First make sure that your workstation has access to the tools
git. We’re going to need them when doing this manually. Spoiler: I’ve built a container image that brings all that packaged with tools that support this process. Skip this section if you can’t wait to get going - and consider contributing to the project btw.
We’ll need some temporary directories and files.
mkdir .cache .build-repo .deploy-repo .tmp
Next init the build and our target (production) OSTree repositories.
ostree --repo=".build-repo" init --mode=bare-user
ostree --repo=".deploy-repo" init --mode=archive
Let’s git clone the upstream git repository containing the Fedora IoT configuration.
git clone -b "f33" https://pagure.io/fedora-iot/ostree.git .source-repo
This will make sure that the upstream in version F33 is available in the
.source-repo directory. We now need some form of custom configuration to throw into the Remix. See this example repository for reference. The example repository will add a custom package
watchdog and it’s configuration file to the resulting OSTree.
Now copy everything together.
cp .source-repo/* .tmp/
cp ostree-files/* .tmp/
Some files we might want or have to merge. This applies to the so called
treecompose-post.sh-script. It’s a script which will be executed in the resulting target filesystem of our Fedora IoT Remix that allows us to make last-minute changes like changing file permissions, etc.
cat ".source-repo/treecompose-post.sh" "ostree-files/treecompose-post.sh" > ".tmp/treecompose-post.merged.sh"
chmod +x ".tmp/treecompose-post.merged.sh"
What’s left to do before we can execute the build is to specify build metadata and a ref by which we identify our Remix’ versions.
sed -i "s,OSTREE_REF,THEIoT/stable/x86_64," ".tmp/ostree.json"
export COMMIT_SUBJECT="MBuilt | Builddate $(date --rfc-3339=seconds)"
This will set the REF we use in
rpm-ostree rebase to
THEIoT/stable/x86_64. Neat. It’s also preparing a built-time tag as metadata for the commit. So let’s not wait any longer and start building. Grab a cup of coffee, depending on your machine that could take a while…
rpm-ostree compose tree --unified-core --cachedir=".cache" --repo=".build-repo" --write-commitid-to="$COMMIT_FILE" ".tmp/ostree.json"
After a coffee or two with a (hopefully) finished build we now can commit the changes and add the result to our production repository. Remember? The one we created an empty directory for at the beginning.
ostree --repo=".build-repo" commit -b "THEIoT/stable/x86_64" -s "$COMMIT_SUBJECT" --tree=ref="$(cat "$COMMIT_FILE")"
ostree --repo=".deploy-repo" pull-local ".build-repo" "THEIoT/stable/x86_64"
Last things to do is to update / generate a so-called summary file in our “production” repository. This summary file contains the contents of the OSTree repository so that clients like a Raspberry Pi with Fedora IoT can process this remote and apply it’s REFs and commits.
ostree --repo=".deploy-repo" summary -u
Optionally (but highly recommended) you can also add a gpg signature to your commits. This reduces the risk that someone rolls out malicious updates from your repository. This requires the clients to know the public key so they can check the signature. I’ll save that part for another time.
ostree --repo=".deploy-repo" gpg-sign <commit-id> <gpg-key-id>
Go Ahead And Upload
You’ve now successfully built your first Fedora IoT Remix! In theory you only have to expose it somewhere, e.g. using NGINX and your Fedora IoT devices can start using it. If you want to add more commits to an existing repo just don’t initialize the
.deploy-repo but keep it and repeat the steps on that one.
Now that we have done all those tedious steps, let’s make ourselves more comfortable. E.g. by using the FOSS project RPM-OSTree-Engine which is a container image packed with all the required dependencies and some tools easing out the steps we’ve just done.