Skip to content

Status and next step on lcdproc automatic configuration upgrade with Perl and Config::Model

Back in March, I uploaded a Debian’s version of lcdproc with a unique feature: user and maintainer configurations are merged during package upgrade: user customizations and developers enhancements are both preserved in the new configuration file. (See this blog for more details). This avoids tedious edition of the configuration LCDd.conf file after every upgrade of lcdproc package.

At the beginning of June, a new version of lcdproc (0.5.7-1) was uploaded. This triggered another round of automatic upgrades on user’s systems.

According to the popcon rise of libconfig-model-lcdproc-perl, about 100 people have upgraded lcdproc on their system. Since automatic upgrade has an opt-out feature, one cannot say for sure that 100 people are actually using automatic upgrade, but I bet a fair portion are them are.

So far, only one people has complained: a bug report was filed about the many dependencies brought by libconfig-model-lcdproc-perl.

The next challenge for lcdproc configuration upgrade is brought by a bug reported on Ubuntu: the device file provided by imon kernel module is a moving target: The device file created by the kernel can be /dev/lcd0 or /dev/lcd1 or even /dev/lcd2. Static configuration files and moving target don’t mix well.

The obvious solution is to provide a udev rule so that a symbolic link is created from a fixed location (/dev/lcd-imon) to the moving target. Once the udev rule is installed, the user only has to update LCDd.conf file to use the symlink as imon device file and we’re done.

But, wait… The whole point of automatic configuration upgrade is to spare the user this kind of trouble: the upgrade must be completely automatic.

Moreover, the upgrade must work in all cases: whether udev is available (Linux) or not. If udev is not available, the value present in the configuration file must be preserved.

To know whether udev is available, the upgrade tool (aka cme) will check whether the file provided by udev (/dev/lcd-imon) is present or not. This will be done by lcdproc postinst script (which is run automatically at the end of lcdproc upgrade). Which means that the new udev rule must also be
activated in the postinst script before the upgrade is done.

In other words, the next version of lcdproc (0.5.7-2) will:

  • Install a new udev rule to provide lcd-imon symbolic link
  • Activate this rule in lcdproc postinst script before upgrading the configuration (note to udev experts: yes, the udev rule is activated with “--action=change” option)
  • Upgrade the configuration by running “cme migrate” in lcdproc postinst script.

In the lcdproc configuration model installed by libconfig-model-lcdproc-perl, the “imon device” parameter is enhanced so that running cme check lcdproc or cme migrate lcdproc issues a warning if /dev/lcd-imon exists and if imon driver is not configured to use it.

This way, the next installation of lcdproc will deliver a fix for imon and cme will fix user’s configuration file without requiring user input.

The last point is admittedly bad marketing as users will not be aware of the magic performed by Config::Model… Oh well…

In the previous section, I’ve briefly mentioned that “imon_device” parameter is “enhanced” in lcdproc configuration model. If you’re not already bored, let’s lift the hood and see what kind of enhancements was added.

Let’s peek in lcdproc configuration file, LCDd.conf file which is used to generate lcdproc configuration model. You may remember that the formal description of all LCDd.conf parameters and their properties is generated from LCDd.conf to provide lcdproc configuration model. The comments in LCDd.conf follow a convention so that most properties of the parameters can be extracted from the comments. In the example below, the comments show that NewFirmware is a boolean value expressed as yes or no, the latter being the default :

# Set the firmware version (New means >= 2.0) [default: no; legal: yes, no]

Back to the moving target. In LCDd.conf, imon device file parameter is declared this way:

# Select the output device to use

This means that device is a string where the default value is /dev/lcd0.

Which is wrong once the special udev rule provided with Debian packages is activated. With this rule, the default value must be /dev/lcd-imon.

To fix this problem, a special comment is added in the Debian version of LCDd.conf to tune further the properties of the device parameter:

# select the device to use
# {%
#   default~
#   compute
#     use_eval=1
#     formula="my $l = '/dev/lcd-imon'; -e $l ? $l : '/dev/lcd0';"
#     allow_override=1 -
#   warn_if:not_lcd_imon
#     code="my $l = '/dev/lcd-imon';defined $_ and -e $l and $_ ne $l ;"
#     msg="imon device does not use /dev/lcd-imon link."
#     fix="$_ = undef;"
#   warn_unless:found_device_file
#     code="defined $_ ? -e : 1"
#     msg="missing imon device file"
#     fix="$_ = undef;"
#   - %}

This special comment between “{%” and “%}” follows the syntax of Config::Model::Loader. A small configuration model is declared there to enhance the model generated from LCDd.conf file.

Here are the main parts:

  • default~ suppress the default value of the “device” parameter declared in the original LCDd.conf (i.e. “/dev/ldcd0“)
  • compute and the 3 lines below computes a default value for the device file. Since “use_eval” is true, the formula is evaluated as Perl code. This code will return /dev/lcd-imon if this file is found. Otherwise, /dev/lcd0 is returned. Hence, either /dev/lcd-imon or /dev/lcd0 will be used a as default value. allow_override=1 lets the user override this computed value
  • warn_if and the 3 lines below test the configured device file with the Perl instructions provided by the code parameter. There, the device value is available in the $_ variable. This code will return true if /dev/lcd-imon exists and if the configured device does not use it. This will trigger a warning that will show the specified message.
  • Similarly warn_unless and the 3 lines below warns the user if the configured device file is not found.

In both warn_unless and warn_if parts, the fix code snippet is run when by the command cme fix lcdproc and is used to “repair” the warning condition. In this case, the fix consists in resetting the device configuration value so the computed value above can be used.

cme fix lcdproc is triggered during package post install script installed by dh_cme_upgrade.

Come to think of it, generating a configuration model from a configuration file can probably be applied to other projects: for instance, php.ini and kdmrc are also shipped with detailed comments. May be I should make a more generic model generator from the example used to generate lcdproc model…

Well, I will do it if people show interest. Not in the form “yeah, that would be cool”, but in the form, “yes, I will use your work to generate a configuration model for project […]”. I’ll let you fill the blank 😉

Edit your debian patch header for DEP-3 compliance with cme

While not required by Debian policy, the  patch tagging guidelines (aka DEP-3) recommends to add a structured header to source package patches.

Long story short, patches should begin with something like :

Description: tweak lcdproc config for debian
patch LCDd.conf to:
* use syslog instead of stderr to show message
* run LCDd as root (to read /dev/lcd* file)
The latter could be done better by tweaking udev rule
Author: dod
Applied-Upstream: NA

Making sure that the DEP-3 recommendation is respected may not be fun. Do not despair: once libconfig-model-dpkg-perl is installed on your system, you can check whether your patches respect the DEP3 recommendation with the following command:

$ cme check dpkg-patches
loading data
checking data
check done

You can also check individual patches with:

cme check dpkg-patch tweak-conf

Note that bash auto-completion is provided only from version 2.049 of libconfig-model-dpkg-perl package.

If editing the header of your patches with your favorite editor does not strike you as fun, you can also use cme graphical editor provided by libconfig-model-tkui-perl. Once this package is installed, you can run:

cme edit dpkg-patches

You will get this editor to update your patches:

-usr-bin-cme Dpkg::Patches_001

This editor will show you the available parameters and the associated documentation to let you provide relevant information.

Last but not least, patch header check is also performed when you check your whole package with cme check dpkg

All the best

Deprecating experience level and preset value in Config::Model


The next releases of Config::Model will deprecate 2 (mis)features:

  • Experience level: trying to filter out configuration parameter based on arbitrary experience is a bad idea. This may confuse user by hiding parameter without obvious way to show them back. (actually with the options menu on the graphical interface, but that’s too easy to miss)
  • Preset value: this feature provides a way to specify a default value at runtime. This is now provided with the configuration layer.

The behavior of ‘cme check’ will not change. People using ‘cme edit’ with the GUI will see many more configuration parameters.

All the best

Another package configuration upgrade project …


I’ve recently learned that Debian Google Summer of Code 2014 features a project to improve package configuration upgrade based on Elektra library

Despite the fact that this project competes directly with the work done for lcdproc upgrades, I’m very glad that the idea of improving configuration upgrade is getting more attention and I welcome this new project.

All the best

Easier Lcdproc package upgrade with automatic configuration merge


This blog explains how next lcdproc package provide easier upgrader with automatic configuration merge.

Here’s the current situation: lcdproc is shipped with several configuration files, including /etc/LCDd.conf. This file is modified upstream at every lcdproc release to bring configuration for new lcdproc drivers. On the other hand, this file is always customized to suit the specific hardware of the user’s system. So upgrading a package will always lead to a conflict during upgrade. User will always be required to choose whether to use current version or upstream version.

Next version of libconfig-model-lcdproc-perl will propose user whether to perform automatic merge of the configuration: upstream change are taken into account while preserving user change.

The configuration upgrade shown is based on Config::Model can be applied to other package.

Current lcdproc situation

To function properly, lcdproc configuration must always be adapted to suit the user’s hardware. On the following upgrade, upstream configuration is often updated so user will often be shown this question:

Configuration file '/etc/LCDd.conf'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** LCDd.conf (Y/I/N/O/D/Z) [default=N] ?

This question is asked in the middle of an upgrade and can be puzzling for an average user.

Next package with automatic merge

Starting from lcdproc 0.5.6, the configuration merge is handled automatically by the packaging script with the help of Config::Model::Lcdproc.

When lcdproc is upgraded to 0.5.6, the following changes are visible:
* lcdproc depends on libconfig-model-lcdproc-perl
* user is asked once by debconf whether to use automatic configuration upgrades or not.
* no further question are asked (no ucf style questions).

For instance, here’s an upgrade from lcdproc_0.5.5 to lcdproc_0.5.6:

$ sudo dpkg -i lcdproc_0.5.6-1_amd64.deb 
(Reading database ... 322757 files and directories currently installed.)
Preparing to unpack lcdproc_0.5.6-1_amd64.deb ...
Stopping LCDd: LCDd.
Unpacking lcdproc (0.5.6-1) over (0.5.5-3) ...
Setting up lcdproc (0.5.6-1) ...

Changes applied to lcdproc configuration:
- server ReportToSyslog: '' -> '1' # use standard value
update-rc.d: warning: start and stop actions are no longer supported; falling back to defaults
Starting LCDd: LCDd.
Processing triggers for man-db (2.6.6-1) ...

Note: the automatic upgrade currently applies only to LCDd.conf. The other configuration files of lcdproc are handled the usual way.

Other benefits

User will also be able to:
* check lcdproc configuration with sudo cme check lcdproc
* edit the configuration with a GUI (see Managing Lcdproc configuration with cme for more details)

Here’s a screenshot of the GUI:

GUI to edit lcdproc configuration

More information

* libconfig-model-lcdproc-perl package page. This package provides a configuration model for lcdproc.
* This blog explains how this model is generated from upstream LCDd.conf.
* How to adapt a package to perform configuration upgrade with Config::Model

Next steps

Automatic configuration merge can be applied to other packages. But my free time is already taken by the maintenance of Config::Model and the existing models, there’s no room for me to take over another package.

On the other hand, I will definitely help people who want to provide automatic configuration merge on their packages. Feel free to contact me on:
* config-model-user mailing list
* debian-perl mailing list (where Config::Model is often used to maintain debian package file with cme)
* #debian-perl IRC channel

All the best

Config::Model::OpenSsh now supports OpenSSH 6.4 configuration


This was long overdue.

I’ve released Config::Model::OpenSsh 1.232. This new release
supports a lot of new parameters that were added to OpenSSH 6.0 and later versions, like AllowAgentForwarding, AuthenticationMethods or AuthorizedKeysCommand.

This new version is also available in Debian.

Happy new year !

LWP::UserAgent https proxy now fixed in Debian


For more 10 years, opening a https connection throught a proxy was not possible
with LWP::UserAgent.

Thanks to Steffen Ullrich, this bug is now fixed in LWP::UserAgent and LWP::Protocol::https repositories.

In Debian, I’ve updated libwww-perl 6.05-2 and liblwp-protocol-https-perl 6.04-2 to include the same patches. This fix is now available in Debian unstable.

See my previous blog for more details on this story.

All the best