This is my contribution to the Emacs Carnival 2025-07: Writing Experience.
For me the experience of writing in Emacs is a frequent, ever evolving, largely in org-mode, magical experience that has become critical for the way I operate.
I am a vim convert, but I never had to give up the lovely editing experience and familiar key bindings thanks to Spacemacs and evil-mode. I have been trying…
Org-mode is my exocortex, second brain, second mind, mind palace, pensive, personal knowledge management system, and apocrypha. It’s very flexible and the features I use as well as how I organize my files continues to change so I collected things here to document how I do things in 2024, I did this in 2023 as well1.
No, my Emacs org-mode configuration is not published. However, if you…
I’ve been pretty much living in org-mode for 6 or 7 years now1. It’s my exocortex, second brain, second mind, mind palace, pensive, and personal knowledge management system2. The features and tools I use as well as how I organize my files has changed quite a bit over this period of time and I thought it would be nice give myself (and anyone else who cares) a reference of what it was…
I think I started getting interested in org-mode in 20071. I definitely was making serious attempts to integrate it into my workflow by 2010. By 2016 it became my primary tool. By primary tool, I mean that most of my daily work is either done from within or at least I’ve probably written down something about what I’ve done in org-mode.
Early on, maybe 2009 I found Bernt Hansens…
Do you have any tips on reversing a json dictionary?
I have a map of IPv4 addresses to environments and I would like to have a map of environments to IPv4s.
1 2 3 4 5 6 7 { '192.0.2.131' : 'TEST-NET-1', '198.51.100.151' : 'TEST-NET-2', '198.51.100.146' : 'TEST-NET-2', '203.0.113.146' : 'TEST-NET-3', '203.0.113.21' : 'TEST-NET-3' } Would become:
1 2 3 4 5 6 7 8 9 10 11 12 13 {…
How can I use or with a classes type promise where an element is negated with not().
It's not currently possible to use not() directly within an or classes promise since it returns a string and not boolean.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 bundle agent main { vars: 'f' string => '/tmp/missing'; classes: 'missing' or => { not( fileexists( $(f) ) ) }; 'exists' or => {…
CFEngine provides the services promise type to manage the state of a given service. By default, bundle agent standard_services is used for the service_method. The standard_services bundle uses the status command and interprets the return codes according to the Linux Standard Base init script actions. Unfortunately some init scripts do not follow the standards. On sysvinit (non-systemd) hosts, if…
Can I access the current KEY when iterating in Mustache?
Yes, CFEngine's implementation of mustache includes an extension to be able to access the current key when iterating. @ expands the current key being iterated.
This example defines d as a simple json data structure with index-1 and index-2 being top level keys. The mustache template iterates over the entirety of the structure…
How can I execute a command that uses command substitution in CFEngine?
On the console I might execute something like this:
1 2 touch /tmp/file-$(date --iso-8601) ls /tmp/file-* /tmp/file-2019-03-08 Example command substitution I recommend not executing commands using substitution. Instead, prepare all that you need up front. Get the result of the data command and put it into a cfengine…
What is the -top- extension, and how do I use it in CFEngines Mustache templating method?
The -top- extension to the mustache template method, first introduced in CFEngine 3.9.0, is a special key representing the complete data given to the templating engine. This is useful for iterating over the top level of a container {{#-top-}} … {{/-top-}} and rendering json representation of data given…
CFEngine 3.12.0 introduced the augments key to the Augments file format. If you are not already familiar with Augments, check it out. It's a very easy way to define classes and variables very early during agent execution, before policy.
The new augments key allows you to merge additional data in the augments format on top of the base augments. I However, there is, I think, still a simple way…
How do you deal with config files that need different settings based on various services that are running on a host and cooperate with other teams? It's a common question, and it came up on in #cfengine on irc.freenode.net recently.
The issue is that team A might be working on package A, which requires some environment variables set. But team B might be working on a totally different thing –…
In CFEngine classes are used for decision making. Classes can be defined as the result of a promise by attaching a classes body to the promise via the classes attribute.
For example, here we run the command echo Hello World and define bundle scoped classes using the results classes body prefixed with Hello_World.
1 2 3 4 5 6 7 8 9 10 bundle agent main { commands: 'echo Hello World' contain…
This was asked on the CFEngine Help Mailing list on October 1st 2018.
How can I use classes in a mustache template while passing explicit data to template_data? When a mustache template is rendered without providing explicit data to the template_data attribute in a files promise datastate() is used. datastate() contains the JSON representation of the current cfengine state.
When providing…
How do I set the timeout with url_get()?
As shown in the documentation for url_get(), you set url.timeout in the data container passed for url_get() options.
This example policy shows how to configure the timeout and demonstrates it by making a request through www.delay.me.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 bundle agent main { vars: 'options' data => '{ 'url.timeout': '2', 'url.
Recently I noticed that my CPU was pretty busy with the desktop search indexing, it brought me to the question:
How can I disable the desktop search service trackerd?
After a brief investigation I found some XDG desktop needed to be edited to include the key Hidden=true.
This policy disables known trackerd related XDG files when they are found.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15…
How can I define custom access promises for cf-serverd without modifying vendored policy?
Commonly, when custom access promises are introduced, they are introduced by editing bundle server access_rules in controls/cf_serverd.cf where the default access rules are promised. Modifying policy maintained upstream can complicate future framework upgrades because care must be taken to ensure that…
> How can I automatically remediate the issue where corruption in LMDB causes the agent to crash?
In some cases lmdb corruption causes cf-agent to crash. The typical fix is to remove the corrupt lmdbs causing the problem. In some cases this can be remediated from policy. This policy (run early in the bundlesequence) uses lmdump to probe all lmdbs. If the probe fails the offending lmdb and it's…
> How do I know if vars or classes come first during cfengine evaluation?
Read the documentation on Normal Order There is a wealth of information on docs.cfengine.com. Find documentation about the order of agent promise evaluation (Normal Order) in the Language Concepts section of the Reference manual.
Run the agent with –verbose or -v and grep for pass 1. Write a test policy that has both…
> How can I ensure that a notice containing legal text is presented to windows users during login?
With the windows agent (Northern.tech builds Enterprise windows agents) you can accomplish this by managing the registry using the databases promise type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 bundle agent registered_owner #@ brief Make the…
This tip comes from my good friend Aleksey Tsalolikin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 bundle agent main { vars: # Creae a map of interface to MAC # Generate a classic array # Iterate over known interfaces, define interface as key and MAC as value 'iface2mac[$(sys.interfaces)]' string => '$(sys.hardware_mac[$(sys.interfaces)])', meta => { 'inventory',…
It looks like ifvarclass is one of few places in CFEngine that does not automatically canonify:
Is there a reason why ifvarclass – which takes a variable by design – does not automatically canonify that variable before checking if there’s a matching class?
Yes, it's true that ifvarclass, and it's aliases if and unless do not automatically canonify when checking a class.
Historically…
How can I purge a package using the apt_get package_module? policy => purge doesn't work.
present and absent are the package states, purge is an option for package manager. You should be able to use the options attribute since the apt_get package module supports it.
1 2 3 4 5 6 7 8 9 10 bundle agent main { packages: # Purging a package using the --purge option 'screen' policy => 'absent',…
How can I make cfengine do things during a specific time window?
You can find 'time based classes' in the cf-promises --show-classes output, they are easily identified because they are tagged with time_based. For example:
1 cf-promises --show-classes | grep time | Day2 time_based | cfengine_internal_time_based_autoremove | source=agent | hardclass | | GMT_Afternoon time_based |…
How do I format and convert time strings?
The strftime() function takes unix epoch format as input and can format the time using the standard strftime templates.
1 2 3 4 5 6 7 bundle agent main { reports: '$(with)' with => strftime( localtime, '%FT%R:%S%Z', now() ); } R: 2018-01-27T15:47:14CST Output current time in ISO 8601 format Unfortunately there is currently no native way to convert…
> Can we use uid/gid to set permissions instead of username and groupname?
Yes, you sure can.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 bundle agent main { files: # Here we use username and groupname '/tmp/example' create => 'true', perms => mog( '600', 'root', 'root' ); # Here we use uid and gid '/tmp/example' perms => mog( '600', 1000, 136 ); } body perms…
> Does CFEngine provide tool to render a mustache template?
No, CFEngine doesn't have a standalone tool to render mustache. This online demo is a good place to quickly prototype a simple template and data set.
Another option is to use a stand-alone policy file.
Name the file whatever you like. It looks for json in a file named the same suffixed with .json, it looks for a mustache…
Anyone interested in organizing Kansas Linux Fest in 2018?
In 2016 and 2017 KLF was hosted in Wichita KS at Wichita State University. The prior two years organizers are a bit burned out and are taking a break.
<ben_roose> Hi nickanderson, Sadly at the moment there is not a KLF 2018 planned. The few of us who created KLF 2017 are rather burned out and need a break this year :-( <ben_roose>…
Why doesn't body action if_elapsed work with vars type promises?
Let's start with the details of body action if_elapsed.
1 2 3 4 5 6 7 body action if_elapsed(x) # @brief Evaluate the promise every `x` minutes # @param x The time in minutes between promise evaluations { ifelapsed => '$(x)'; expireafter => '$(x)'; } body action if_elapsed from the standard library The ifelapsed action body…
Is there any way to do a multiline regex check for a file in CFEngine?
There is no function for searching a file for content. The grep() function operates on lists, not files. However using readfile() and regcmp() I was sill able to search for a multi-line string using only native functionaity
In the example below we first create a file with content that spans multiple lines. Then we read…
If I have a promise with a copy_from promise where the body specifies that permissions should be preserved and I also have a perms body on the same promise what is expected to happen?
The files type promises documentation describes the normal order of files promise attributes during promise actuation.
The documentation notes:
file presence ( create | copy | link ) permissions file…
> How can my hosts self organize into different groups?
In cfengine 3 select_class can be used for partitioning hosts into separate groups without central coordination. Given the same list of options in the same order each host will always choose the same option.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 bundle agent…
It's easy to export an org document to html and get a table of contents, but sometimes it's nice to have a table of contents inside of an org-mode file. The [[https://github.com/snosov1/toc-org][toc-org]] package makes this automatic.
Simply tag a headline with :TOC: and the headline will auto fill an index with all following headlines.
<img src='' alt='' width='100%'/>
What's the simplest, easiest, no-fuss way to wrap up standalone example?
I use ob-cfengine3 with org-mode inside of spacemacs for most of my self contained examples and when I start prototyping new policy.
When I have a cfengine3 SRC block and I execute it body file control is magically inserted to load the stdlib.
1 2 3 4 5 6 7 bundle agent main { reports: '$(this.promise_filename):'…
How can I use set_line_based to manage a space separated file like /etc/services but include more than one space to make the config a bit easier to read.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 bundle agent main { vars: 'map[hpss_d_mvr1]' string => '65501/tcp'; # Include padding in the value itself 'map[hpss_d_mvr2]' string => ' 65503/tcp'; files: '/tmp/services' create =>…
When I first tried using Emacs it was to play with Orgmode. I loved Orgmode but being a staunch vim user I really struggled with the key bindings. Ultimately my first attempt to use Orgmode fell by the wayside.
When I learned about evil mode I gave it another go. I stumbled my way through just enough to get evil-mode working and Orgmode became much more usable. I still primarily interacted…
> How can I make sure a package is always up to date?
1 2 3 4 5 6 7 8 9 10 11 12 bundle agent main { vars: 'latest_pkgs' slist => { 'singularity', 'singularity-devel' }; packages: '$(latest_pkgs)' policy => 'present', comment => 'Important to automatically track the latest and greatest because ....', version => 'latest'; } The packages promise implementation shown above has been available…
cf-agent -Kf ./example.cf error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data error: readjson: data error parsing JSON file '/tmp/mydata.json': No data…
When using the acl_method overwrite you must supply user, group, all ( aka other ), and mask for a complete ACL specification.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 bundle agent main { vars: 'acl' slist => { 'user:*:rwx', # System owner should have read write and execute access 'group:*:rw', # System group should have read and write access but not execute 'all:r', #…
This controls if and how files are backed up by cf-agent during file editing operations. If enabled previous versions of the file will be retained next to the file or in default_repository if it is defined in body agent control. Note as it relates to edited files it is only applicable when combined with edit_line. It has no effect when used with edit_template or copy_from.
A value of true (the…
Is there implicit 'canonify'-cation happening in in 'classes:' promise type?
Yes the agent will automatically canonify classes that you define for your convenience.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 bundle agent main # @brief show how classes are automatically canonified during definition { vars: 'invalid_class_string' string => 'my-invalid-class';…
Well, I no longer work at CFEngine Inc. But only because we re-named the company to Northern Tech in order to unify our multiple products under a single company. Both CFEngine and Mender will continue to have their own unique product branding.
This weekend Neil Watson asked if I could share how I use org-mode with Spacemacs.
@cmdln_ Care to share with an Emacs illiterate how you got Spacemacs and Org-mode to work together? – @neil_h_watson
First of all, I spend most of my time in a terminal, and vim is ingrained in my muscle memory any time I need to edit a file. While Vim is my goto editor I consider myself just a novice Vim…
I recently built a new file server and I based it on the well renowned FreeNAS by iXsystems. It’s been pretty solid over the past few weeks but today I ran into an issue. The web ui stopped responding. Actually it turned out that the django service had stopped. Well, that was the perfect opportunity to use CFEngine to make sure I never have the issue again.
I grabbed the cfengine community 3.
You never know when the Zombie or Cloud Apocalypse is coming. It’s good to be able to locate those buried bodies quickly and easily. OK, enough bad jokes, but haven’t you ever looked at some CFEngine policy and wondered to yourself, exactly what does “delete => tidy” or some other body or bundle do?
I have. I even wrote a crappy little perl script to locate the files that contained a specific…