Skip to content

Instantly share code, notes, and snippets.

@stormwatch
Last active December 28, 2020 23:27
Show Gist options
  • Save stormwatch/cf01d64403c483999458f02229b25245 to your computer and use it in GitHub Desktop.
Save stormwatch/cf01d64403c483999458f02229b25245 to your computer and use it in GitHub Desktop.
Learning verb.el and org mode

Goal

I am learning Vagrant and friends. I am currently writing a document in Org Mode where I intend to compare different providers and boxes. Ideally I’d like to automate and generate the comparision dynamically. Vagrant provides an API to query their box cloud registry. It is not very sofisticated in terms of searching but it sort of works.

My initial efforts with verb.el are geared towards getting simple results, then maybe I can manage to generalize the functions and code blocks in order for them to accept arguments.

A minimal test

template https://app.vagrantup.com/api/v1/box

Barge

For this test I chose arbitrarily a Vagrant Box called Barge which I am interested in testing and benchmarking.

I hardcoded the path. Ideally I’d like to be able to pass variables like :var account="ailispaw" box-name="barge" to this or a similar verb block.

I am insterested in the current_version object and some of its properties down the hierarchy like: update date, size of the image (if avialiable), list of providers, etc. So it seems reasonable to only query the API once for each box I am interested in.

(setq barge (verb-json-get (oref (verb-stored-response box) body) "current_version"))

Results are sent to barge.json because I don’t want them in the exported document. Maybe there is a better way?

Then I can for example call currentVersion like:

Random thoughts

Since tables are first-class citizens in Org Mode, I see many examples that ingest data from a source table, process them and finally output the desired result. I could start for example from a table like:

ailispawbarge
bentoamazonlinux-2
gbaileyamzn2
hajowielandamazonlinux2
hbsmithawslinux2
bb_sdetamzn2
nixweiamazon-linux-2

and use an emacs-lisp (or verb?) source block to map over each row in order to get the desired data and then format it accordingly into another table and/or interpolate the data into a text paragraph via inline calls.

A formatted result could look like:

Box nameprovidersLast updatetotal downloadsdescriptiontime of vagrant up (seconds)
ailispaw/bargeVirtualBox[2020-01-01]123456A minimal box capable of running Docker images45
etc…

Another example could be a table that tracks the results of vagrant up under different providers:

VirtualBoxlibvirt (qemu-kvm)VMware
ailispaw/bargesuccessN/AN/A
centos/8pendingsuccessN/A
freebsd/FreeBSD-12.2-STABLEpendingN/Apending
bento/freebsd-12.2pendingN/Apending
alpine-linux/alpine-x86_64pendingpendingN/A
fedora/33-cloud-basependingsuccessN/A

Right now, I am doing this by hand but I am quite sure this could be automated. I am not using a source data table but heading properties and a columnview block to collect and show the data. Example:

An overview of some suitable Vagrant boxes

Amazon Linux

Since our “production environment is in AWS” it seems sensible to use Amazon Linux 2 as the host OS. It features AWS integration, long term support, extras repository, on-premises use, systemd support, EC2 optimized kernel & toolchain, secure by default[fn:Amazon Linux 2 limits remote access by using SSH key pairs and by disabling remote root login. Additionally, Amazon Linux 2 reduces the number of non-critical packages which are installed on an instance, limiting exposure to potential security vulnerabilities. Security updates rated “critical” or “important” are automatically applied on the initial boot.], security updates[fn:Security alerts are published in the Amazon Linux AMI Security Center.], kernel live patching.

Amazon Linux 2 vagrant box construction, using an Amazon supplied VDI disk image as a base. This approach avoids actually booting the Amazon supplied VDI disk image by mounting it and applying vagrant related changes to it, and then calling vagrant to package the resulting image as a box file. Available updates are applied as part of this process. Features

These scripts also shrink the consumed disk space, such that these box files are significantly smaller than others I’ve seen posted online.

VirtualBox Guest Additions are included in this box.

Add below for fast boot
config.vm.provider :libvirt do |libvirt|
  # Pass through /dev/random from the host to the VM
  libvirt.random :model => 'random'
end
Amazon Linux 2 prepared for testing with update kernel
Comparison

This approach works fine when exporting by adding org-update-all-dblocks to org-export-before-parsing-hook.

Thoughts

Org Mode conflates data and its representation. Ideally I’d like to produce an executable document that hides verb’s specifics but keeps its functionalities. verb source blocks seem like a good fit for the task. The template syntax, altough useful may be undesirable for this kind of project; but maybe there is a way of hiding it, :no_export: tags? Prepending COMMENT before the Org headline title?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment