Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

rbuild

Build, run & test packages on a matrix of VPS easily

Usage

Architecture

Usage

See exemple for reference code used in the demonstrations

Nix packaging

Check out the NixOS website Nix packaging

Ansible packaging

Check out the Ansible documentation Ansible packaging

CLI

rbuild {nix,ansible,test} [-h] [-f FOLDER] [-c CONFIG] [-v] [-V]

Subcommands

CommandDescription
testTest the SSH connection to the remotes
nixBuild the project on remotes, using Nix derivation
ansibleBuild the project on remotes, using Ansible playbook

Options

ShortLongDescription
-h–helpShow the help message
-f–folder FOLDERPath to the folder containing the project to build/test
-c–config CONFIGPath to the configuration file
-v–verboseEnable verbose output
-V–versionShow the version number and exit

Exemples

# Test the connection on the remotes
./rbuild test 

# Build the project remotely using Nix
./rbuild.py nix --folder test-project/

# Build the project remotely using Nix
./rbuild.py ansible --folder test-project/ --verbose 

Config

config.json

{
    "version": "v1",
    "vps" : [
        {
            "name" : "my_x86-64_vps",
            "ip" : "0.0.0.0",
            "user" : "admin"
        },
        {
            "name" : "my_aarch64_vps",
            "ip" : "0.0.0.0",
            "user" : "cooluser"
        }
    ]
}

Exemple project

Only one of default.nix or build.yml is required

main.c

#include <stdio.h>
#include <stdlib.h>

int main() {

  #if defined __x86_64__
    int result = system("cowsay 'Hello world from x86-64'");
  #elif defined __aarch64__
    int result = system("cowsay 'Hello world from aarch64'");
  #else
    int result = system("cowsay 'Hello world from a weird architecture'");
  #endif

  if (result == -1) {
    fprintf(stderr, "Error: Failed to execute cowsay\n");
    return 1;
  }
}

default.nix

{ pkgs ? import <nixpkgs> {} }:

pkgs.stdenv.mkDerivation {
  pname = "exemple-c";
  version = "0.0.1";

  src = ./.;
  nativeBuildInputs = [ pkgs.makeWrapper ];
  buildInputs = [ pkgs.cowsay ];


  buildPhase = ''
    gcc -o exemple-c main.c
  '';

  postFixup = ''
    wrapProgram "$out/bin/exemple-c" \
      --prefix PATH : ${ pkgs.lib.makeBinPath [ pkgs.cowsay ] }
  '';

  doCheck = true;
  checkPhase = ''
    ./exemple-c 
  '';

  installPhase = ''
    mkdir -p $out/bin/
    cp exemple-c $out/bin/
  '';

}

build.yml

---
- name: Ensure GCC is installed
  ansible.builtin.package:
    name: gcc
    state: present
  become: true

- name: Ensure cowsay is installed
  ansible.builtin.package:
    name: cowsay
    state: present
  become: true

- name: Compile the C program (gcc -o exemple-c main.c)
  ansible.builtin.command:
    cmd: gcc -o exemple-c main.c
    chdir: /tmp/rbuild/test-project/
  register: compile_result

- name: Run compiled program (./exemple-c)
  ansible.builtin.command:
    cmd: ./exemple-c
    chdir: /tmp/rbuild/test-project/
  register: check_result
  
- name: Display check result
  ansible.builtin.debug:
    msg: "Test output (checkPhase): {{ check_result.stdout }}"

- name: Clean up temporary build directory
  ansible.builtin.file:
    path: /tmp/rbuild/test-project
    state: absent

Architecture

Architecture

Ansible

Require a file build.yml at the root of the project
You must have ansible installed on your machine, check installation steps

Flow

rbuild will autogenerate two files:

  • rbuild_inventory.ini that contain the servers from your config.json
  • rbuild_playbook.yml that will import your build.yml and run a few setup tasks beforehand Both files will get removed automatically at the end of the script

rbuild handle the calling of ansible-playbook, make sure this command is available in your $PATH.

Afterwards, you will get a summary of which server was able to build the package, and for thoses that failed, the error message received. Check out the demo here

Nix

Require a file default.nix at the root of the project
You must have nix installed on all servers, check installation steps

Flow

rbuild will send your project to all remotes via scp in a temporary folder
It will initiate a SSH connection to all servers, and nix-build the package
For any failure, it will also run nix-store -l [DERIVATION]

Afterwards, you will get a summary of which server was able to build the package, and for thoses that failed, the error message received. Check out the demo here