Browse Source
__debconf set selections: Add state explorer See merge request ungleich-public/cdist!999ander/__rsync
7 changed files with 230 additions and 27 deletions
@ -0,0 +1,142 @@
|
||||
#!/bin/sh -e |
||||
# |
||||
# 2021 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) |
||||
# |
||||
# This file is part of cdist. |
||||
# |
||||
# cdist is free software: you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation, either version 3 of the License, or |
||||
# (at your option) any later version. |
||||
# |
||||
# cdist is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>. |
||||
# |
||||
# Determine current debconf selections' state. |
||||
# Prints one of: |
||||
# present: all selections are already set as they should. |
||||
# different: one or more of the selections have a different value. |
||||
# absent: one or more of the selections are not (currently) defined. |
||||
# |
||||
|
||||
test -x /usr/bin/perl || { |
||||
# cannot find perl (no perl ~ no debconf) |
||||
echo 'absent' |
||||
exit 0 |
||||
} |
||||
|
||||
linesfile="${__object:?}/parameter/line" |
||||
test -s "${linesfile}" || { |
||||
if test -s "${__object:?}/parameter/file" |
||||
then |
||||
echo absent |
||||
else |
||||
echo present |
||||
fi |
||||
exit 0 |
||||
} |
||||
|
||||
# assert __type_explorer is set (because it is used by the Perl script) |
||||
: "${__type_explorer:?}" |
||||
|
||||
/usr/bin/perl -- - "${linesfile}" <<'EOF' |
||||
use strict; |
||||
use warnings "all"; |
||||
|
||||
use Fcntl qw(:DEFAULT :flock); |
||||
|
||||
use Debconf::Db; |
||||
use Debconf::Question; |
||||
|
||||
# Extract @known... arrays from debconf-set-selections |
||||
# These values are required to distinguish flags and values in the given lines. |
||||
# DC: I couldn't think of a more ugly solution to the problem… |
||||
my @knownflags; |
||||
my @knowntypes; |
||||
my $debconf_set_selections = '/usr/bin/debconf-set-selections'; |
||||
if (-e $debconf_set_selections) { |
||||
my $sed_known = 's/^my \(@known\(flags\|types\) = qw([a-z ]*);\).*$/\1/p'; |
||||
eval `sed -n '$sed_known' '$debconf_set_selections'`; |
||||
} |
||||
|
||||
sub mungeline ($) { |
||||
my $line = shift; |
||||
chomp $line; |
||||
$line =~ s/\r$//; |
||||
return $line; |
||||
} |
||||
|
||||
sub fatal { printf STDERR @_; exit 1; } |
||||
|
||||
my $state = 'present'; |
||||
|
||||
sub state { |
||||
my $new = shift; |
||||
if ($state eq 'present' |
||||
or ($state eq 'different' and $new eq 'absent')) { |
||||
$state = $new; |
||||
} |
||||
} |
||||
|
||||
|
||||
# Load Debconf DB but manually lock on the state explorer script, |
||||
# because Debconf aborts immediately if executed concurrently. |
||||
# This is not really an ideal solution because the Debconf DB could be locked by |
||||
# another process (e.g. apt-get), but no way to achieve this could be found. |
||||
# If you know how to, please provide a patch. |
||||
my $lockfile = "%ENV{'__type_explorer'}/state"; |
||||
if (open my $lock_fh, '+<', $lockfile) { |
||||
flock $lock_fh, LOCK_EX or die "Cannot lock $lockfile"; |
||||
} |
||||
{ |
||||
Debconf::Db->load(readonly => 'true'); |
||||
} |
||||
|
||||
|
||||
while (<>) { |
||||
# Read and process lines (taken from debconf-set-selections) |
||||
$_ = mungeline($_); |
||||
while (/\\$/ && ! eof) { |
||||
s/\\$//; |
||||
$_ .= mungeline(<>); |
||||
} |
||||
next if /^\s*$/ || /^\s*\#/; |
||||
|
||||
my ($owner, $label, $type, $content) = /^\s*(\S+)\s+(\S+)\s+(\S+)(?:\s(.*))?/ |
||||
or fatal "invalid line: %s\n", $_; |
||||
$content = '' unless defined $content; |
||||
|
||||
|
||||
# Compare is and should state |
||||
my $q = Debconf::Question->get($label); |
||||
|
||||
unless (defined $q) { |
||||
# probably a preseed |
||||
state 'absent'; |
||||
next; |
||||
} |
||||
|
||||
if (grep { $_ eq $q->type } @knownflags) { |
||||
# This line wants to set a flag, presumably. |
||||
if ($q->flag($q->type) ne $content) { |
||||
state 'different'; |
||||
} |
||||
} else { |
||||
# Otherwise, it's probably a value… |
||||
if ($q->value ne $content) { |
||||
state 'different'; |
||||
} |
||||
|
||||
unless (grep { $_ eq $owner } (split /, /, $q->owners)) { |
||||
state 'different'; |
||||
} |
||||
} |
||||
} |
||||
|
||||
printf "%s\n", $state; |
||||
EOF |
@ -0,0 +1,21 @@
|
||||
#!/bin/sh -e |
||||
# |
||||
# 2021 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) |
||||
# |
||||
# This file is part of cdist. |
||||
# |
||||
# cdist is free software: you can redistribute it and/or modify |
||||
# it under the terms of the GNU General Public License as published by |
||||
# the Free Software Foundation, either version 3 of the License, or |
||||
# (at your option) any later version. |
||||
# |
||||
# cdist is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with cdist. If not, see <http://www.gnu.org/licenses/>. |
||||
# |
||||
|
||||
__package_apt debconf |
Loading…
Reference in new issue