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]
NewFirmware=no
Back to the moving target. In
LCDd.conf,
imon device file parameter is declared this way:
# Select the output device to use
Device=/dev/lcd0
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;"
# - %
Device=/dev/lcd0
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
;-) Tagged:
Config::Model,
configuration,
debian,
lcdproc,
Perl,
upgrade