Skip to content

cme: some read-write backend features are being deprecated

Hello

Config::Model and cme read and write configuration data with a set of “backend” classes, like Config::Model::Backend::IniFile. These classes are managed by Config::Model::BackendMgr.

Well, that’s the simplified view. Actually, the backend manager can handle several different backends to read and write data: read backends are tried until one of them succeeds to read configuration data. And write backend cen be different from the read backend, thus offering the possibility to migrare from one format to another. This feature came at the beginning of the project, back in 2005. This felt like a good idea to let user migrate from one data format to another.

More than 10 years later, this feature has never been used and is handled by a bunch of messy code that hampers further evolution of the backend classes.

So, without further ado, I’m going to deprecate the following features in order to simplify the backend manager:

  • The “custom” backend that can be easily replaced with more standard backend based on Config::Model::Backend::Any. This feature has been deprecated with Config::Model 2.107
  • The possibility to specify more that one backend. Soon, only the first read backend will be taken into account. This will simplify the declaration of backend. The “read_config” parameter, which is currently a list of backend specification, will become a single backend specification. The command cme meta edit will handle the migration of existing model to the new scheme.
  • the “write_config” parameter will be removed.

Unless someone objects, actual removal of these feature will be done in the next few months, after a quite short deprecation period.

All the best

Advertisements

New with cme: a GUI to configure Systemd services

Hello

Systemd is powerful, but creating a new service is a task that require creating several files in non obvious location (like /etc/systemd/system or ~/.local/share/systemd/user/). Each file features 2 or more sections (e.g. [Unit], [Service]). And each section supports a lot of parameters.

Creating such Systemd configuration files can be seen as a daunting task for beginners.

cme project aims to make this task easier by providing a GUI that:

  • shows all existing services in a single screen
  • shows all possible sections and parameters with their documentation
  • validates the content of each parameter (if possible)

For instance, on my laptop, the command cme edit systemd-user shows 2 custom services (“free-imap-tunnel@” and “gmail-imap-tunnel@”) with:

cme_edit_systemd_001

The GUI above shows the units for my custom systemd files:

$ ls ~/.config/systemd/user/
free-imap-tunnel@.service
free-imap-tunnel.socket
gmail-imap-tunnel@.service
gmail-imap-tunnel.socket
sockets.target.wants

and the units installed by Debian packages:

$ find /usr/lib/systemd/user/ -maxdepth 1 \
  '(' -name '*.service' -o -name '*.socket' ')' \
  -printf '%f\n' |sort |head -15
at-spi-dbus-bus.service
colord-session.service
dbus.service
dbus.socket
dirmngr.service
dirmngr.socket
glib-pacrunner.service
gpg-agent-browser.socket
gpg-agent-extra.socket
gpg-agent.service
gpg-agent.socket
gpg-agent-ssh.socket
obex.service
pulseaudio.service
pulseaudio.socket

The screenshot above shows the content of the service defined by the following file:

$ cat ~/.config/systemd/user/free-imap-tunnel@.service
[Unit]
Description=Tunnel IMAPS connections to Free with Systemd

[Service]
StandardInput=socket
# no need to install corkscrew
ExecStart=-/usr/bin/socat - PROXY:127.0.0.1:imap.free.fr:993,proxyport=8888

Note that empty parameters are not shown because the “hide empty value” checkbox on top right is enabled.

Likewise, cme is able to edit system files like user files with sudo cme edit systemd:

cme_edit_systemd_001

For more details on how to use the GUI to edit systemd files, please see:

Using a GUI may not be your cup of tea. cme can also be used as a validation tool. Let’s add a parameter with an excessive value to my service:

$ echo "CPUShares = 1000000" >> ~/.local/share/systemd/user/free-imap-tunnel@.service

And check the file with cme:

$ cme check systemd-user 
cme: using Systemd model
loading data
Configuration item 'service:"free-imap-tunnel@" Service CPUShares' has a wrong value:
        value 1000000 > max limit 262144

ok, let’s fix this with cme. The wrong value can either be deleted:

$ cme modify systemd-user 'service:"free-imap-tunnel@" Service CPUShares~'
cme: using Systemd model

Changes applied to systemd-user configuration:
- service:"free-imap-tunnel@" Service CPUShares: '1000000' -> ''

Or modified:

$ cme modify systemd-user 'service:"free-imap-tunnel@" Service CPUShares=2048'
cme: using Systemd model

Changes applied to systemd-user configuration:
- service:"free-imap-tunnel@" Service CPUShares: '1000000' -> '2048'

You can also view the specification of a service using cme:

$ cme dump systemd-user 'service:"free-imap-tunnel@"'---
Service:
  CPUShares: 2048
  ExecStart:
    - '-/usr/bin/socat -  PROXY:127.0.0.1:imap.free.fr:993,proxyport=8888'
  StandardInput: socket
Unit:
  Description: Tunnel IMAPS connections to Free with Systemd

The output above matches the content of the service configuration file:

$ cat ~/.local/share/systemd/user/free-imap-tunnel@.service
## This file was written by cme command.
## You can run 'cme edit systemd-user' to modify this file.
## You may also modify the content of this file with your favorite editor.

[Unit]
Description=Tunnel IMAPS connections to Free with Systemd

[Service]
StartupCPUWeight=100
CPUShares=2048
StartupCPUShares=1024
StandardInput=socket
# no need to install corkscrew now
ExecStart=-/usr/bin/socat -  PROXY:127.0.0.1:imap.free.fr:993,proxyport=8888

Last but not least, you can use cme shell if you want an interactive ui but cannot use a graphical interface:

$ cme shell systemd-user 
cme: using Systemd model
 >:$ cd service:"free-imap-tunnel@"  Service  
 >: service:"free-imap-tunnel@" Service $ ll -nz Exec*
name      │ type │ value                                                             
──────────┼──────┼───────────────────────────────────────────────────────────────────
ExecStart │ list │ -/usr/bin/socat -  PROXY:127.0.0.1:imap.free.fr:993,proxyport=8888

 >: service:"free-imap-tunnel@" Service $ ll -nz
name             │ type    │ value                                                             
─────────────────┼─────────┼───────────────────────────────────────────────────────────────────
StartupCPUWeight │ integer │ 100                                                               
CPUShares        │ integer │ 2048                                                              
StartupCPUShares │ integer │ 1024                                                              
StandardInput    │ enum    │ socket                                                            
ExecStart        │ list    │ -/usr/bin/socat -  PROXY:127.0.0.1:imap.free.fr:993,proxyport=8888

 >: service:"free-imap-tunnel@" Service $ set CPUShares=1024
 >: service:"free-imap-tunnel@" Service $ ll -nz CPUShares 
name      │ type    │ value
──────────┼─────────┼──────
CPUShares │ integer │ 1024 

 >: service:"free-imap-tunnel@" Service $ quit


Changes applied to systemd-user configuration:
- service:"free-imap-tunnel@" Service CPUShares: '2048' -> '1024'

write back data before exit ? (Y/n)

Currently, only service, socket and timer units are supported. Please create a bug report on github if you need more.

Installation instructions are detailed at the beginning of Managing Systemd configuration with cme wiki page.

As all softwares, cme probably has bugs. Please report any issue you might have with it.

For more information:

All in all, systemd is quite complex to setup. I hope I made a little bit easier to deal with.

All the best

New dzil command to install author dependencies as Debian packages

Hello

Dist::Zilla is a great tool to limit tedious tasks while working on Perl modules. For instance, dzil provides tools like dzil authordeps or dzil listdeps to list dependencies.
This list of Perl modules can then be installed with cpanm:

dzil authordeps --missing | cpanm
dzil listdeps --missing | cpanm

On a Debian system, one may prefer to install Perl modules using Debian packages. Installing build dependencies can be done with apt build-dep, but apt does not handle Dist::Zilla author dependencies.

The new authordebs Dist::Zilla sub-command was wriiten to fill this gap. When run in a directory containing the source of a Perl module that uses Dist::Zilla, you can run dzil installdebs to list the Debian packages required to run the dzil command. You can also run dzil installdebs -install to install author dependencies (using sudo under the hood).

See:

On Debian, authordebs is provided by libdist-zilla-app-command-authordebs-perl

All the best

A survey for developers about application configuration

Hello

Markus Raab, the author of Elektra project, has created a survey to get FLOSS developer’s point of view on the configuration of application.

If you are a developer, please fill this survey to help Markus’ work on improving application configuration management. Feeling this survey should take about 15 mns.

Note that the survey will close on July 18th.

The fact that this blog comes 1 month after the beginning of the survey is entirely my fault. Sorry about that…

All the best

An improved Perl API for cme and Config::Model

Hello

While hacking on a script to update build dependencies on a Debian package, it occured to me that using Config::Model in a Perl program should be no more complicated than using cme from a shell script. That was an itch that I scratched immediately.

Fast forward a few days, Config::Model now features new cme() and modify() functions that have a behavior similar to cme modify command.

For instance, the following program is enough to update popcon’s configuration file:

use strict; # let's not forget best practices ;-)
use warnings;
use Config::Model qw(cme); # cme function must be imported
cme('popcon')->modify("PARTICIPATE=yes");

The object returned by cme() is a Config;:Model::Instance. All its methods are available for a finer control. For instance:

my $instance = cme('popcon');
$instance->load("PARTICIPATE=yes");
$instance->apply_fixes;
$instance->say_changes; 
$instance->save;

When run as root, the script above shows:

Changes applied to popcon configuration:
- PARTICIPATE: 'no' -> 'yes'

If need be, you can also retrieve the root node of the configuration tree to use Config;:Model::Node methods:

my $root_node = cme('popcon')->config_root;
say "is popcon active ? ",$root_node->fetch_element_value('PARTICIPATE');

In summary, using cme in a Perl program is now as easy as using cme from a shell script.

To provide feedback, comments, ideas, patches or to report problems, please follow the instructions from CONTRIBUTING page on github.

All the best

Automount usb devices with systemd

Hello

Ever since udisk-glue was obsoleted with udisk (the first generation), I’ve been struggling to find a solution to automatically mount a usb drive when such a device is connected to a kodi based home cinema PC. I wanted to avoid writing dedicated scripts or udev rules. Systemd is quite powerful and I thought that a simple solution should be possible using systemd configuration.

Actually, auto-mount notion covers 2 scenario :

  1. A device is mounted after being plugged in
  2. An already available device is mounted when a process accesses its mount point

The first case is the one that is needed with Kodi. The second may be usefull so is  also documented in this post.

For the first case, add a line like the following in /etc/fstab:

/dev/sr0 /mnt/br auto defaults,noatime,auto,nofail 0 2

and reload systemd configuration:

sudo systemctl daemon-reload

The important parameters are “auto” and “nofail”: with “auto”, systemd mounts the filesystem as soon as the device is available. This behavior is different from sysvinit where “auto” is taken into account only when “mount -a” is run by init scripts. “nofail” ensures that boot does not fail when the device is not available.

The second case is handled by a line like the following one (even if the line is split here to improve readability):

/dev/sr0 /mnt/br auto defaults,x-systemd.automount,\
   x-systemd.device-timeout=5,noatime,noauto 0 2

With the line above in /etc/fstab, the file system is mounted when user does (for instance) “ls /mnt/br” (actually, the first “ls” fails and triggers the mount. A second “ls” gives the expected result. There’s probably a way to improve this behavior, but I’ve not found it…)

“x-systemd.*” parameters are documented in systemd.mount(5).

Last but not least, using a plain device file (like /dev/sr0) works fine to automount optical devices. But it is difficult to predict the name of a device file created for a usb drive, so a LABEL or a UUID should be used in /etc/fstab instead of a plain device file. I.e. something like:

LABEL=my_usb_drive /mnt/my-drive auto defaults,auto,nofail 0 2

All the best

 

Perl6 is now up to date on Debian sid

Hello

Thanks to the help of Daniel Dehennin and Paul Cochrane, The rakudo implementation of Perl 6  is now up to date on Debian/sid.

Unlike previous version, Perl 6 on Debian uses moarvm backend. No other backend is provided.

Please use the following command to install Perl6 on Debian:

sudo apt-get install rakudo

All the best