M.A.R.K. Stack or M.A.R.K. OS #
The M.A.R.K. ( Macaroni Automated Repositories Kit ) stack could be see like a source-based OS with a name that reference the technologies used for his building, the automation that wants introduce and an acronym that reference the Iron Man Armor. The softwares change so fastly and to keep a system updates begin very hard for a distro. In MARK starting from the idea used in Funtoo, we want improve the automation and the pipeline of delivery of the packages in order to balance the speed and the choice of upgrading particular services and/or packages.
So, the main keys of MARK are:
-
automation: to reduce the effort on updates packages and keep the system updates is one of the main target. Automatic updates obviously will not be always easy to manage and a maintenance activity will be always needed, but the first target is try to reduce this effort and have a way to automatically receive news about the new versions. To do this, we use the
mark-devkit
tool that permits to define YAML file used to autogen new ebuild based on templates and to manage the comparition of ebuilds without kits and/or overlay available through Git repositories. The updates could be sent through direct commits or through Github PR. -
dynamicity: one of the pros of Gentoo and Funtoo is the easy way to add patches to upstream sources, at the same way we want follow this pattern and try to share an OS that is a good place for developers.
-
reproducibility: share technologies, how to configure it and using Opensource is one of the core and more important key of MARK OS. Without sharing the knowledge this world will never grow. So, another important point a bit complex, for a lot of reason and just for for the volume of the documentation will be sharing our Distro from Scratch steps used in MARK.
Now the we have described the main principles under this stack it’s time to describe how the magic is started and how will be improved.
After the Funtoo shutdown in August 2024, Macaroni OS thanks to the support of the ex-Funtoo developers decides to start a new adventure to keep the system independent from other distro in order to have a better control of the system and avoid that external changes could be dangerous in the Macaroni OS itself. Obviously, starting from zero was not possible, and so, based of the expirience get in Funtoo we have applied the first changed to the metatools, ego needed to create the base for what is been developed in one year and that will be evolved again in the future. But having a clear target, trying to join the two worlds and create a gate between the Anise/binary stack and the sourced-based world of MARK. But not only this, the Portage itself it’s a software created in Gentoo that will be replaced too in the future or at least we hope on this. Working on our free time doesn’t permit to share specific dates and/or milestone so what we can share is at least the plan.
Through this vision we are been really lucky to find our Sponsors, really thanks always for their support, and thourgh them we also oriented the development of our tools to be more connected to their technologies in order to share the better experience possible to our users.
For this reason, the mark-devkit
tool that is the main (but not the only) module used to keep
the distfiles server updated is been developed to have a better integration with Object Store S3
exposed in CDN77.
Before enter in the details of our releases we want try to compare Gentoo, Funtoo and MARK in order to help users from these distro to understand the differences:
🚀 MARK vs Gentoo vs Funtoo #
Feature | Gentoo | Funtoo | MARK |
---|---|---|---|
Package management | emerge |
emerge |
emerge and anise + anise-portage-converter |
Portage format | Monolitic tree + external overlays | Kits with main release | Kits with different branches, different targets and different stability levels. |
Software distribution | Pure source-based + xpak | Source-based with curated kits + xpak | Source-based with curated kits + xpak and anise binary packages |
Profiles/config | Portage profiles (eselect profile ) |
ego + mix-ins / arch / flavor |
ego + mix-ins / arch / flavor (replaced with mark soon) |
System updates | emerge --sync && emerge -avuDU @world |
ego sync && emerge -avuDU @world |
ego sync && emerge -avuDU @world or anise upgrade --sync-repos |
NVIDIA Drivers | Single SLOT installation | Single SLOT installation | multi slotted autogen managed by gpu-configurator tool. |
initramfs generator | genkernel | ramdisk | dracut |
Ebuild generator | - | metatools | mark-devkit autogen , mark-devkit kit merge , mark-devkit kit bump-release |
Stage tarballs generator | catalyst |
metro |
mark-devkit metro |
Stability level assurance | single tree where using KEYWORDS and portage.mask | single tree fully autogen with KEYWORDS and portage.mask | multiple versions for every package, portage.mask and different branches with different stability levels |
Installer | manual | manual | manual or calamares |
💂 Stability Levels #
🐳 Container/Server releases #
For support MARK releases containers and servers oriented don’t require necessary tons
of packages for Desktop stuff, and following this idea we have created the release
mark-xl
and mark-v
with a subset of the packages. In addition, having less desktop
packages with a lot of constraints and cross dependencies between permit to simplify
the life of the solver, speedup the dependencies calculation and permit to experiment
new new libraries, compiler, etc. reducing issues with the upgrade for ABI change not
yet supported. So, this permits to experiment and move ahead packages on this releases
without the pain on broken desktop softwares that are updates with less periodicity.

As visible from the schema, on mark-unstable
the mark-bot automatically create
new PR for the packages with autogen specs (through mark-devkit autogen
command).
But it’s also possible receive PR directly from contributors and/or developers.
After a testing period the new versions pushed with other PRs to the mark-xl
branch
could be merged and moved to testing environment.
The mark-devkit kit bump-release
is used to update the JSON files of the
meta-repo repository in the
branch related to the release that is later used by ego
to fetch the Portage
tree splitted in kits. This behaviour is also a protection about errors done in the
kits that could be fastly reverted because until a new bump is done users will be
synced to the git hash of the last bump in the kit updated. Cons is that until a
new bump is done new updates will be not visible to users. Normally, an automatic
task run every day in our CD/CI that try to bump a new update the align the JSON
files to last commit of every kits.
The mark-devkit kit clean
instead is used to generate PRs to remove versions
of the packages exceeded the max number of version admitted by the YAML specs.
Also in this case, the mark-bot task running for this is executed periodically
from our CD/CI chain.
So, the mark-unstable
release is the world of the chaos. We can push PR to upgrade and
break everything. But better in an organized mode if it’s possible. It’s easy that this
branch will be often broken because is where we do experiment with new versions and releases
of the packages.
When a new package is been merged on mark-unstable
the mark-bot checking for updates in
the mark-xl
branch creates new PRs for the testing branch that could be leave there until
a testing phase is been done or just merged directly. If the mark-bot’s task is executed
again and the PR for a specific package and version is already present, it just ignore
the upgrade because already in the queue for a validation.
Depending of the level of upgrade, for example for patch release version (I mean following
the semver paradigm) we could merge new versions with less attention because at the end
also mark-xl
is a testing branch and it’s possible that sometime a specific version could
be broken. In that case, the developers can choice to fix the issue or just create a PR that
revert the previous and waiting for a fix from mark-unstable.
At the end, after a testing period of the mark-xl
branch, normally, this is also been with
the creation of the new versions over the Macaroni Terragon and Eagle releases that
automatically test the existing tree a manual task is fired over our CD/CI to execute
mark-devkit kit merge
that doesn’t use PR but just merge versions as a commits. Potentially,
could be used PRs also on mark-v but we prefer using directly commit because when the new
release is tagged through goreleaser tool we generate the ChangeLog automatically with the
list of the new versions availables.
The upgrade of the core packages (GCC, Glibc, etc.) will be always done before in these releases and later to the Desktop releases.
💻 Desktop releases #
The Desktop Linux world is something complex with tons of packages that are connected between them and is not easy planning specific upgrade without break the tree. For this reason we prefer keep a separated tree for Desktop respect the Container/Server and like describe before, it keeps a simple life for the solver with less packages.
Having multiple releases take more effort but we think that could be a choice right that permits to experiment in different way the upgrades.
For now, the only shared branch between the Desktop world and the Container/Server world
is mark-unstable
that share a common place where define the autogen specifications and
later choice with mark-devkit kit merge
of the upper branches what packages go where.
It’s not excluded that in the future will not change.
The logic describes in the previous chapter are pretty equal for the Desktop world,
the difference is only that the testing branch of Desktop is mark-iii
and the stable
tree of the Desktop is mark-i
.

🔬 Embedded releases #
Not ready yet for end users we have started in August 2025 the branch
mark-31
with the target to support ARM/ARM64 arches. We consider it
experimental for now but when will be ready we will add testing and stable
branches too.

So, the mark-31
branch could be considered like an unstable branch for embedded
that receive incoming PRs from mark-unstable
too.
Our target is to supply in the near future SD images for these devices as starting point:
- Raspberry PI4
- Banana PI
- Orange Pi
- Pine64
Stay tuned!
📦 Portage #
At the moment, Macaroni OS uses a forked version of Portage with patches from Funtoo as main package
manager system but with an eye for improve integration with anise
and the Macaroni binary
layer.
The Macaroni Portage fork follow the Funtoo/Gentoo paradigm where is used the ebuild to describe the steps to compile and install a package and different repositories (the kits) where aggregate specific packages for example about server services, networking, etc. Like described in The Story we love the core concepts used in FreeBSD, Gentoo and Funtoo about knobs/USE in order to customize easily a source-based distribution. These concepts will be always core elements also in the future when w will replace Portage itself.
Using different branches ensure different levels of stability already and so the behaviour of the
KEYWORDS variable used in Gentoo is less important, indeed, normally we use the value
*
and in the future could be probably removed.
In a different way respect Gentoo and Funtoo, MARK doesn’t generate the overlay metadata cache directly in the exposed repository. The main reason is that is more simple to manage in an upgrade workflow based on Github PR that could be merged, reverted, etc. without introduce jobs to update costantly the same repository that receive the update of the package, etc. Without the metadata the emerge solver could be slow, but this could be solved with the execution of the command:
$> # As root user
$> for i in $(ls -1 /var/git/meta-repo/kits/) ; do egencache --update --repo=$i ; done
This step is temporary and managed automatically in the near future from the replacer of
the ego
tool.