Software quality has been a topic and an area of interest since the dawn of software itself. And as software evolved so did the techniques and approaches to assuring its high quality. Better computers providing more computing power, bigger storage and faster communication have allowed software developers to detect issues in their code sooner and faster. And so we got from getting a syntax error after two days of waiting for the box of punch cards to go through the queue of boxes and get loaded into a computer running a compiler to getting such errors from a compiler in seconds or even in real-time from the code editor. And we got from bugs being detected by actually seeing real bugs on punch cards with machine instructions to operating systems providing bug reports with coredumps, tracebacks and lots of information helping the developers to identify the problem, tests detecting problems before the code gets into production, or compilers and tooling detecting them before the code is even executed the first time. We can afford doing things like fuzz testing, we have enough computational power for compilers and special tools to analyze the code and check all possible paths through it and much more. At the same time, software has become a part of almost everything we use or interact with every day and so with the incomparably greater amount of software potentially affecting our lives there is an incomparably greater amount of bugs that need to be detected and fixed or at least handled gracefully. With some software being more critical than other and with bugs ranging from minor annoyances to losses of human lives. Many things have changed in this evolution, but one rule has always been key:
Earlier this year, we hinted at what we were working on - a place for users to find and share reusable modules for CFEngine. Today, the CFEngine team is pleased to announce the launch of CFEngine Build:
The new website, build.cfengine.com, allows you to browse for modules, and gives you information about how to use each one of them. When you’ve found the module you were looking for, it can be downloaded and built using the command line tooling.
Still interested in running CFEngine on IoT?
Craig (Digger) shows building CFEngine Enterprise for Yacto and deploys a Raspberry Pi Zero with a sensor to measure the height of Nick’s (Doer of Things) desk.
Video The video recording is available on YouTube:
At the end of every webinar, we stop the recording for a nice and relaxed, off-the-record chat with attendees. Join the next webinar to not miss this discussion.
CFEngine is well suited for use in IoT environments due to it’s portability, size, and performance. There already exists a meta layer for including the CFEngine community client and Masterfiles Policy Framework in Yocto Project builds. This enables developing policy to:
ensure a service stays running track changes to important files monitor a value over time for normalcy Let’s walk through bringing up a qemu environment with CFEngine and ensure that a few basic things work: ensure the udev service stays running, tracking changes to important files like /etc/group and a look at monitoring capabilities.
Interested in running CFEngine for IoT?
Craig (Digger) shows building CFEngine for Yocto.
Video The video recording is available on YouTube:
At the end of every webinar, we stop the recording for a nice and relaxed, off-the-record chat with attendees. Join the next webinar to not miss this discussion.
I recently had a minor task involving changing an option - on one of our command line tools - from taking a required argument, to taking an optional argument. This should be easy they said; just change the respective option struct to take an optional argument, add a colon to the optstring, and get on with your life.
Well, it proved to be easier said than done. My initial expectation was that a solution similar to the one below should just work. And it does work, just not in the way I expected.
Interested writing CFEngine policy faster?
Jeff (CFEngine Community user) demonstrates his YASnippet library for CFEngine to make writing CFEngine policy significantly faster.
Video The video recording is available on YouTube:
At the end of every webinar, we stop the recording for a nice and relaxed, off-the-record chat with attendees. Join the next webinar to not miss this discussion.
This blog post will focus on the bash programming part of implementing a promise type. To understand what custom promise types are, and how to use them, you should read the introduction first.
To implement a custom promise type in CFEngine, you need a promise module. The module is an executable, and can be written in any language. It’s possible to write one from scratch, but to make it as easy as possible, we decided to provide libraries for common programming languages. In our previous blog post, we showed how to implement modules in Python. That’s great, it’s a powerful, expressive and readable programming language, however there is one drawback; installing python. Many systems don’t have python already, or have a version which is too old. So you will need to add policy to install / update Python, to make sure modules work correctly everywhere.
This tutorial focuses on how to write a promise module, implementing a new CFEngine promise type. It assumes you already know how to install promise modules and use custom promise types, as shown in the previous blog post.
Why Python? Promise modules can be written in any programming language, but there are some advantages of using python:
Readable and beginner friendly language / syntax Popular and familiar to a lot of people, also used in some CFEngine package modules Big standard library, allowing you to reuse data structures, parsers, etc. without reinventing the wheel or adding dependencies Official CFEngine promise module library Most of the code needed is already done (protocol, parsing, etc.) You can focus on only the business logic, what is unique to your new promise type With that said, there are some reasons why you might not always want to use python:
Introduction In the CFEngine Core team, we have recently been working on a fix for our WaitForCriticalSection() function. In short, the function checks a timestamp in a chunk of (lock) data stored in a local LMDB database and if the timestamp is too old, it writes a new chunk of (lock) data with the new timestamp. However, this used to be done in separate steps - read the data from the DB and close DB, check the data and potentially write the new data into the DB. So, there was a race condition because if multiple processes did the same steps at the same time, they could have read and checked the same timestamp value and then write their own data with their new timestamps one after another. On the high-level perspective that meant multiple processes could have entered the critical section at the same time.