Arch Linux installer written in OCaml

Hello everyone,

I’m sharing the WIP project on the off chance it’s interesting/useful to someone.

What

This installer written in OCaml allows installing Arch Linux with optional disk encryption (where all key files placements, boot parameters adjustment etc are adjusted for you). The installer aims to be somewhat smart and hassle free to use.

Right now

  • It recognises whehter your Arch Linux live CD is running in BIOS or EFI mode, and adjusts prompts/partitioning accordingly (not technically difficult at all, but just so you know it does that)
  • Handles optional disk encryption, with encrypted boot (haven’t added code for toggling boot partition encryption yet)
  • Allows two disk layout schemes atm
      1. use a single disk, installer does partitioning for you
      1. you tell installer partitions for /, /boot and /efi if in EFO mode, and installer use those info instead

WIP

  • Installation of SaltStack files (for package management) and other helper scripts
    • Section below gives more context on these things

TODO

  • Resumable installation (add logging etc)
  • Static config file support (so installation is fully automated)
  • Add disk layout scheme where it’s system partition + USB key
  • Whatever is missing from the original script
  • Travis CI (or other CI) builds for static binary to published on GitHub release
    • So one can download the installer directly instead of building it locally first

Context

This installer is essentially a rewrite of the install script I’ve been using for a while.

I especially needed an semi-automated solution to installing Arch Linux as I was using a encrypted USB key + encrypted system partition setup, where manual installation is error prone and time consuming.

The install script was thus born, written in bash, accompanied by salt files for package management, and various helper scripts for easier handling of the USB key in day-to-day operations.

This is all fine and dandy until I wanted to have different disk layout, and pick whether I want encryption or not. Bash script is not terribly good for these somewhat decision/logic heavy tasks for obvious reasons.

And so rewrite in OCaml began, and stuck with OCaml even after considering various other choices (e.g. elvish, xonsh, fish, python, racket).

Intention

The code aims to facilitate customisation (make a copy and adjust things your way) by providing a sane starting point, but does not aim to provide a proper “library” type of code base due to the somewhat volatile nature of Arch, and assumptions made may not be directly portable to other distros.

Navigation

  • scripts/
    • setup.sh is the original bash installer script, which this installer is based on
    • remaining files are helpers, and misc scripts
  • saltstack/
    • SaltStack files for package management
  • installer_ml/ contains the OCaml installer code
    • src/
      • installer.ml somewhat show cases the intended high level use, the install workflow is specified here
      • disk_layout.ml handles formatting, LUKS setup, mounting, unmounting of partitions etc
      • task_book.ml facilitates high level task registration, used in installer.ml
      • remainders are helper code largely

TL;DR

I wrote a Arch installer in OCaml, thought it’s pretty neat.

EDIT: Added missing Travis CI item in TODO

9 Likes

Sounds very cool! Do you think there is potential for adoption within the Arch community? What are other people using, and could you convince them to migrate to your installer (and help maintain it)?

You might want to check also the 0install which is also was ported to OCaml from Python, see their GitHub repository. Though judging by their repositories activity, they seem abandoned OCaml version and thrown all resources to the C#/.NET version in 0install-dotnet.

1 Like

Sounds very cool!

Thanks!

Do you think there is potential for adoption within the Arch community?

Yes, but definitely not widespread, there are two main reasons.

For people who like to build their system programmatically

The language choice is very niche to begin with - OCaml is definitely not a popular choice (if is one to begin with) for system administration.

For initial bootstrapping, most other langs are better choices: rich stdlib is desirable for the initial phase, good handling of interprocess communication, easy access to regex (maybe not as efficient efficient), easy text file manipulation (a lot of formats supported in stdlib or ecosystem etc).

So overall Python, Ruby, Racket are better for this phase. Especially since there are system administration frameworks in Python (e.g. Fabric) and in Ruby (the name escaped me). I stuck with OCaml since my brain can’t process more than a hundred lines of code in dynamically typed languages.

So the targeted audience is quite limited - one that knows OCaml, the distro’s native installer doesn’t work well enough and thus interested in building their own installer, and does not already have their favourite installer.

Arch overall promotes customisation

So most people have their own installers. This is especially true when Arch deprecated the official installer some years ago.

So sticking to mine as is probably doesn’t make too much sense to most people. The intention was definitely allowing other people to use it as a template for making their own OCaml installer to begin with anyway.

What are other people using, and could you convince them to migrate to your installer (and help maintain it)?

Some of the reasons mentioned in above section carry over.

Due to Arch’s philosophy on customisation, actively convincing others to use my installer would be close to convincing someone to use your favourite editor and abandon theirs.

In any case, I am the primary beneficiary I had in mind, so lack of adoption would not prevent me from maintaining it. Being able to reinstall your Linux willy-nilly with full disk encryption, and giving you a fresh but essentially identical copy of your current install (via package management + dotfiles management), that’s gold.

EDIT: One extra reason is maybe just to demonstrate writing one in OCaml is feasible, as it wasn’t quite obvious what the scope of work was when I first started writing.

1 Like

Thanks for the pointers! I definitely did not think about 0install when I was writing this.

I’m gonna say 0install is solving a different (and vastly more complex) problem. The installer I presented here is at best equivalent to a glorified shell script, and maybe a case study to some people with similar thoughts. So I don’t spot any immediate ideas I can learn from 0install as it stands.

EDIT: I wasn’t aware of 0install-dotnet, so this is definitely interesting.

Though judging by their repositories activity, they seem abandoned OCaml version and thrown all resources to the C#/.NET version

Well, this is the problem with OCaml. When 0install was written in Python, I did frequent bug-fix releases. Now it’s in OCaml, there’s no need to do that. e.g. there were 8 Python releases in 2012 vs 1 OCaml release last year. I prefer it that way, but it’s bad for the project’s metrics.

There is no directing of resources. Bastian Eicher did the C# version before and is still doing it now (though more of it is now hosted in the main github org and we just merged the two sets of documentation to make http://docs.0install.net/).

2 Likes

Lovely project. Hijacking the thread a bit, as I am also using arch… Do you know how much work it would be to implement a yaourt-like (a friendly frontend to Arch package manager, now abandoned) tool in OCaml?
Asking out of curiosity :slight_smile:

I swapped to yay after yaourt was gone. Yay is written in Go, so I thought it’s pretty good for me already.

Judging by the code size via tokei, yay is ~8.3k LOC in Go. So I’m gonna guess wildly and say 6 months if designing from scratch and 1.5 months if porting from yay’s source code directly, for a MVP, excluding testing.

EDIT: Wild guess was quite literal, cause I have no experience in porting Go code of this size/nature to anything. But a few months seems doable from my limited experience in user facing cli tools, when design choices are made and battle tested already (inb4 this becomes my famous last words). In any case most people here know much better than I would.

2 Likes

I also use yay and it’s working great. Go tools, despite my distaste of the language’s design choices, are generally quite reliable.

1 Like

This is exciting to hear - great work, Darren!

1 Like

Static binary builds are now available here (renamed repo as well).

They are built via Travis CI using the ocaml/opam2:alpine docker image, so the binary should be fully static and run fine on the live CD.

Added other stuff

  • Added disk layout for system partition + USB key
  • Code for installing hardened kernel

Note that it’s not well tested at all, so don’t use it for anything too serious yet.