+++
title = "BaguetteOS: technical choices"
paginate_by = 5
+++
- [Base system](#base)
- [Developers tools](#development)
- [Supported languages for the base system](#languages)
- [Conventions](#conventions)
# Base system
**Linux kernel**, but we are lurking on the OpenBSD one.
Linux is compatible with most hardware and software, it is fast and we can easily compile a custom version to remove most of the bloat for server usage.
Still, we don't want to rely on Linux-specific components.
At some point, our system will be kernel-agnostic and will be able to run on any BSD as well.
OpenBSD has `pledge` and `unveil` syscalls, which is an elegant way to provide a guarantee on the software behavior.
**Musl.** *reasonable libc for Linux*
It has a reasonable amount of features, it is efficient, provides reasonable binary sizes and static compilation.
Musl is simple, reliable and remove all glibc-specific functions.
Others can be added easily, which is useful for compatibility and comparisons, through [slotting](#slotting).
**Bootable system and rootfs available.**
A bootable system to install in virtual machines or bare metal, a rootfs to use BaguetteOS from any other OS, including non-Linux ones.
**SysV-style init + [CRUX-like /etc/{rc,mdev.conf,...}][baguette-rc]**. *easy to read, easy to adapt*
The init could come from toybox or another minimalist project.
The [rc script from CRUX][cruxinit] is simple to understand and to adapt to any requirements, so we use it.
We also provide some other scripts, like for [profile][baguette-profile] so we can easily manage slotting.
No systemd BS.
**Toybox.** *the megabyte coreutils*
[Toybox][toybox] combines common unix command line utilities together into a single BSD-licensed executable.
It is designed to be simple even to read, and is standards-compliant.
For the base system, that's all we need.
**ksh and zsh**. *the first for scripts and root, the other for users*
[Ksh][ksh] is a very stable and reliable shell from AT&T, trusted by the paranoid people of OpenBSD.
That's a safe choice for a base system and the root account.
On the other hand, we do use [zsh][zsh] daily, as for many users, so we may use it for development or build scripts but not in the base system.
**[Service][service] for service management** *tokenized service description, templating and dumb cli tools for the win*
[See custom tools.](#custom-tools)
**[Package][package] for package management** *simple-to-use, efficient, dead simple code*
[See custom tools.](#custom-tools)
**OpenSSH.** *as we all know and love*
This is required for almost all usages, and for debug.
Let's try not to shoot ourselves in the foot.
That's all you need for starters. Web administrative interface will be added to the base when ready.
# Development, build tools
**Default building tools** *every tool needed to bootstrap*
Clang (+ LLVM) is the default C (and C++) compiler.
[Libarchive][libarchive] is required for tarballs, packages, webhooks from `packaging`, and both [bsdcpio][bsdcpio] and [bsdtar][bsdtar] (sane implementations of `cpio` and `tar`).
[Auto-tools][autotools] are also required (for SysV init and libarchive).
[m4][m4] and [gnu-make][gmake] are required for compatibility reasons.
**Documentation.**
A full hand-book like the OpenBSD FAQ.
Our software man-pages are written with `scdoc` so anyone can contribute.
**[Packaging][packaging] for packaging software and libraries.** *dead simple, intuitive*
[See custom tools.](#custom-tools)
**Slotting.** *custom file system hierarchy*
Our FS is not FHS-compliant, partially because of the origin-based slotting.
There is a strict separation between core system and third party software.
[See slotting.](#slotting)
- `/usr/baguette` for core system programs
- `/usr/bad` for non slot-able software
- `/usr/` for other software
# Languages
We are reluctant to add new languages to the base system.
We will limit the number of languages required for a system bootstrap.
For now, bootstrapping requires: `C`, `perl`, `m4`, `python` (for stupid reasons) and `crystal` (used for our software).
However, we think that we can overcome C limitations, explore new possibilities.
Now, more than ever, we have better alternatives for all non kernel-related tooling.
That being said: we do not want dynamic languages.
We need:
- simple, small and efficient binaries
- the fewest dependencies possible (not to download half `cpan` or `pypi` for any freaking software)
**Crystal language for system tools.** *syntax and productivity of Ruby, the speed of C*
It is as simple to learn as a dynamic (oriented object) language, while at the same time being almost as fast as C.
Technically, Crystal is strongly typed so it catches errors at compilation-time, but with type inference so it is not cumbersome to use.
Applications are compiled in a simple binary, easy to deploy.
There is a good documentation, we have used it for long enough to tell.
Technical choices are reasonable and documented.
Finally, Crystal has a large library with all we need for our system components.
There is not much of a drawback here.
Yes, this is a language you have to learn to work with us on a couple of projects, but you can learn it in about a few days to a week and it increases our productivity like crazy.
We heard about `nim` and a ton of other languages, lots of them are great candidates, but **choices needed to be made**.
This is the one reaching the sweet spot between these parameters:
- productivity (the package manager was mostly done in a few days, [and is just a few hundred lines long][package])
- easy learning (a developer with basic notions of oriented-object can read our code, no black magic here)
- good documentation
- reasonably deployable (no host dependencies)
- execution speed
We are also looking at [Zig][zig] for low-level stuff. Wait & see.
# BaguetteOS conventions
### Documentation
Manual pages have to be provided for each software.
`BaguetteOS` tools have man-pages generated with [scdoc][scdoc], letting developers use the markdown format to create man-pages.
Scdoc isn't perfect, it ignores meta-data of man-pages (dates, authors name, etc.) and only provides a way to create man-pages with titles and style.
Scdoc should be seen as a way to encourage developers writing documentation, without the complexity of the `roff` format.
Meta-data are ignored in most usage anyway, we should not let them be an obstacle to documentation.
Additional documentation will be provided on this website, for a more educational approach and informal details.
### Service name, user and group names
Default name for a service instance is the name of the project: `nginx`, `wordpress`, etc.
Arbitrary names may be given to service instances.
Example:
```sh
# service add blog.example.com type=wordpress domain=blog.example.com
```
Default environment is `root`.
When a service is configured, we create a user (and a group) under which the service will run, providing a clean separation between all running services.
User and group names for these services are:
```sh
user = $environment.$service
group = $environment.$service
```
Example:
```sh
service = nginx
environment = root (the default environment)
user = root.nginx
group = root.nginx
```
### Package names
```sh
name = application name
version = application version
release = recipe version
$name-$version-r$release.pkg
```
Example:
```sh
firefox-79.0-r8.pkg
```
###
# Next
[See our tooling](/baguette/our-tooling/)
[service]: https://git.baguette.netlib.re/Baguette/service
[package]: https://git.baguette.netlib.re/Baguette/package
[packaging]: https://git.baguette.netlib.re/Baguette/packaging
[build.zsh]: https://git.baguette.netlib.re/Baguette/build.zsh
[libipc]: https://git.baguette.netlib.re/Baguette/libipc
[todod]: https://git.baguette.netlib.re/Baguette/todod
[webhooksd]: https://git.baguette.netlib.re/Baguette/
[tap-aggregator]: https://git.baguette.netlib.re/Baguette/tap-aggregator
[baguette-gitea]: https://git.baguette.netlib.re/
[baguette-rc]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/rc
[baguette-profile]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/rc/profile
[recipes]: https://git.baguette.netlib.re/Baguette/recipes/
[recipe-hello]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/hello/recipe.spec
[recipe-dhcpcd]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/dhcpcd/recipe.spec
[recipe-alsautils]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/alsa-utils/recipe.spec
[autotools]: https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html
[toybox]: http://www.landley.net/toybox/
[cruxinit]: https://crux.nu/gitweb/?p=ports/core.git;a=blob;f=rc/rc;h=26b8ca08d67208ceda4d4004c8333d362bcdc689;hb=HEAD
[ksh]: https://github.com/att/ast
[zsh]: https://www.zsh.org/
[libarchive]: https://libarchive.org/
[bsdcpio]: https://libarchive.org/
[bsdtar]: https://libarchive.org/
[m4]: https://www.gnu.org/software/m4/m4.html
[gmake]: https://www.gnu.org/software/make/
[proot]: https://man.openbsd.org/proot
[crinja]: https://github.com/straight-shoota/crinja
[zig]: https://ziglang.org/
[openbsd]: https://openbsd.org/
[pfsense]: https://www.pfsense.org/
[alpine]: https://alpinelinux.org/
[crux]: https://crux.nu/
[inferno]: http://www.vitanuova.com/inferno/index.html
[plan9]: https://9p.io/plan9/index.html
[morpheus]: https://morpheus.2f30.org/
[suckless]: https://suckless.org/
[cat-v]: http://cat-v.org/
[working-service-asciinema]: https://asciinema.org/a/0p2vGNA1TUmvq0s61Lu0r4TN6
[ruby-memory-bp]: https://web.archive.org/web/20160329122617/http://blog.rubybestpractices.com/posts/ewong/005-Avoiding-system-calls.html
[scdoc]: https://git.sr.ht/~sircmpwn/scdoc
[pledge]: https://man.openbsd.org/pledge.2
[unveil]: https://man.openbsd.org/unveil.2
[retguard]: https://undeadly.org/cgi?action=article&sid=20170819230157
[cveqemu]: https://www.cvedetails.com/vulnerability-list.php?vendor_id=7506&product_id=0&version_id=0&page=1&hasexp=0&opdos=0&opec=0&opov=0&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0&cvssscoremax=0&year=0&cweid=0&order=1&trc=276&sha=6055b0330a499f6aed7620adb79dc0cc143e50bc