kevans91 / bricoler

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

-- What? --

bricoler (French for "to tinker") is a small lua-based framework which aims to
make it easier to compose certain common FreeBSD development workflows.

It only runs on FreeBSD, at least for now.  It requires lua54 and some packages:
- lua54-argparse
- lua54-Penlight
- lua54-posix
- lua54-luafilesystem

Before using it, run "make" to build a couple of small C modules.

Depending on how you use it, you'll probably have to install other packages.

-- Why? --

Today, if I want to build a src tree and run the regression test suite on the
result in a VM, I have to:

1. Build world and the kernel I want.
2. Install the result to a staging directory.
3. Run makefs(8) to build a filesystem image from the staging directory and
   mtree manifest.
4. Run mkimg(1) to build a disk image from the filesystem image, possibly also
   creating an ESP.
5. Boot the disk image in QEMU, run the test suite, and somehow extract the
   results.

As a project, we don't have any good tooling around this workflow.
Furthermore, this workflow has quite a few different parameters, e.g., target
architecture, disk image size, filesystem type, etc..

If I want to instead take a FreeBSD src revision and fuzz the kernel with
syzkaller, then I need to perform most of the above steps (with a bunch of
customization, e.g., root ssh access, a special kernel with kcov(4) enabled),
plus some others.  This is all tedious to do manually, so of course one writes
scripts to automate it.  But such scripts are always purpose-driven and so
miss lots of useful functionality or make assumptions that might not be
appropriate in general.

Some other workflow examples that are useful to me (but not necessarily
integrated yet):
- Build a FreeBSD cloud image and upload it to one of several cloud providers,
  then try to boot the image.
- Run tests which require the ability to start and stop VMs (e.g., to test
  kernel dumps).

Rather than writing ad-hoc scripts for all of my workflows, I wanted a
framework that would let me reuse code and provide extensive parameterization.
I wanted it to be useful in CI environments (e.g., you can run it from
Jenkins) but also useful for interactive developement, in the sense that it's
part of my compile-build-test-debug loop.

bricoler is an experiment in this direction.  It's somewhat stalled.  I think
some of the ideas behind it are solid but it needs a stronger vision.  It's
inspired somewhat by Nix and cheribuild, but it's very primitive.

-- How? --

bricoler is a script which makes use of code under lib/ and some third-party
libraries (argparse, luaposix, lfs, Penlight).  The tasks/ directory contains
"tasks", which are composeable building blocks for workflows.  Running
"bricoler runtask" lists the available tasks.  (Note, at the time of writing,
some of them are not functional or fully implemented.)

Tasks are lua scripts that contain several tables declaring their properties,
and a function, Run(), that's executed by the framework.  The tables define a
task's parameters, inputs and outputs.

A task's inputs define the tasks which must run before that task can run.  For
instance, if one has a task which builds a FreeBSD VM image, it depends on the
output of a task which builds world and the kernel.  Tasks which have no
inputs are leaf tasks and thus run before anything else.

A task's outputs define the result of the task.  This is usually in the form
of a file tree, but this isn't required.  All tasks are run in the same
process so it's possible for a task to output arbitrary lua objects which can
be handed over to subsequent tasks as inputs.

A task's parameters define the "tweakable" properties of the task's execution.
All parameters can be overridden on the command line.  Furthermore, a
dependent task can specify the parameters of its input tasks.  Command-line
parameters have the highest precedence.  Parameters can be typed to an extent,
can have default values and can specify validators.

When running bricoler, one specifies a task to run.  The framework then
figures out the dependency tree and creates a "schedule".  The schedule can be
dumped by adding the "-s" parameter.  Inputs and outputs are placed in the
work directory, which is ~/bricoler by default.

-- Examples --

Add "-C" to all of these to clean the work directory first.

List all defined tasks:
  $ bricoler runtask

List the parameters for the regression suite task:
  $ bricoler runtask freebsd/test/regression-suite -s

Build kgdb using jhb's kdbg scripts:
  $ bricoler runtask kgdb/build

Build pkg with ASAN enabled and run the test suite:
  $ bricoler runtask pkg/build -p configure_args=--with-asan
It would be within the spirit of the framework to define a parameter which
enables ASAN (and one for UBSAN, etc.) rather than having to know the
configure syntax.

Boot a FreeBSD VM image built from a development branch and containing several
packages:
  $ bricoler runtask --workdir ../bricoler freebsd/vm-boot -p memory=4g -p numcpus=4 \
        -p image.build.src:repo="file:///home/markj/sb/so_reuseport_lb/src" \
	-p image.build.src:branch=stable/13-reuseport_lb-backport \
	-p image:image_size=20g -p image:pkgabi=FreeBSD:13:amd64 \
	-p image:pkgs=py39-scapy -p image:ssh_users=root

Please read the task definitions for more information.  Note the many XXX
comments.

-- TODO --

So many things.  An incomplete list:
- Have some way for tasks to declare their system dependencies, so that they
  can fail immediately if one is not installed.  The dependencies might need
  to be derived from a task's parameters.  For instance, vm-boot might need
  QEMU installed, but not if the user specified bhyve.
- Have some way to define site-local defaults for parameters.  For instance,
  a configuration file which specifies parameter values.
- The workdir layout is kind of confusing.
- When specifying parameters on the command line, sometimes I want to append
  to the existing value, but there's no way to do that other than to copy and
  paste the output from "runtask -s" and include that on the command line.  It
  would be nice to have a += operator.  Also would be nice to have a @=
  operator to slurp the value from a file.
- Documentation.

About


Languages

Language:Lua 91.2%Language:C 7.8%Language:Makefile 0.5%Language:Shell 0.5%