On Sunday 12 August 2007, Frans Pop wrote: > Attached is a proof-of-concept patch that implements config file handling > in three levels:
Even though there was only one real conflict caused by Debian-specific changes, I've rebased the two patches against pure upstream 3.1.0beta0. So they should now apply cleanly for you. > So, you'd end up with: > - /usr/share/backuppc/config.pl # default config file > - /etc/backuppc/config.pl # local main config overrides > - /etc/backuppc/$host.pl # per-PC config overrides The last should of course be /etc/backuppc/pc/$host.pl. Thanks for clarifying that for me. I've suggested to the Debian maintainer that per-PC config files be kept in the pc subdir for Debian as well. Cheers, FJP
commit aa7d9a1d07f81ca9b05547f3c905e0f7b1b30264 Author: Frans Pop <[EMAIL PROTECTED]> Date: Tue Sep 4 22:20:00 2007 +0200 Support local overrides against main default configuration file Initial 'proof of concept support' for having a fixed default main configuration file and allowing admins to define local overrides against that default file. This will make local changes more visible and also prepares the way for beter management of changes in the default configuration file on upgrades. diff --git a/lib/BackupPC/CGI/EditConfig.pm b/lib/BackupPC/CGI/EditConfig.pm index aa48bf9..1062ce8 100644 --- a/lib/BackupPC/CGI/EditConfig.pm +++ b/lib/BackupPC/CGI/EditConfig.pm @@ -349,15 +349,11 @@ our %ConfigMenu = ( sub action { - my $pc_dir = "$TopDir/pc"; - my($content, $contentHidden, $newConf, $override, $mainConf, $hostConf); + my($content, $contentHidden, $newConf, $override, $baseConf, $localConf, $hostConf); my $errors = {}; my $host = $In{host}; my $menu = $In{menu} || "server"; - my $hosts_path = $Hosts; - my $config_path = $host eq "" ? "$TopDir/conf/config.pl" - : "$TopDir/pc/$host/config.pl"; my $Privileged = CheckPermission($host) && ($PrivAdmin || $Conf{CgiUserConfigEditEnable}); @@ -391,25 +387,32 @@ sub action } ($newConf, $override) = inputParse($bpc, $userHost); - $override = undef if ( $host eq "" ); } else { # # First time: pick up the current config settings # - $mainConf = $bpc->ConfigDataRead(); + $baseConf = $bpc->ConfigDataRead(); + $localConf = $bpc->ConfigDataRead("config_local"); + $baseConf = { %$baseConf, %$localConf } if ( $host ne "" ); + $hostConf = {}; + $override = {}; + if ( $host ne "" ) { $hostConf = $bpc->ConfigDataRead($host); - $override = {}; foreach my $param ( keys(%$hostConf) ) { $override->{$param} = 1; } + $newConf = { %$baseConf, %$hostConf }; } else { - my $hostInfo = $bpc->HostInfoRead(); - $hostConf = {}; - $mainConf->{Hosts} = [map($hostInfo->{$_}, sort(keys(%$hostInfo)))]; + my $hostInfo = $bpc->HostInfoRead(); + $baseConf->{Hosts} = [map($hostInfo->{$_}, sort(keys(%$hostInfo)))]; + + foreach my $param ( keys(%$localConf) ) { + $override->{$param} = 1; + } + $newConf = { %$baseConf, %$localConf }; } - $newConf = { %$mainConf, %$hostConf }; } if ( $In{saveAction} ne "Save" && $In{newMenu} ne "" @@ -684,8 +687,20 @@ EOF if ( !$isError && $In{saveAction} eq "Save" ) { my($mesg, $err); + + # FJP: Are these really needed? + # FJP: If they are, shouldn't $baseConf->{hosts} be initialized as well? + # FJP: OTOH, it looks as if {hosts} may only be needed in $newConf anyway + $localConf = $bpc->ConfigDataRead("config_local") if ( !defined($localConf) ); + if ( !defined($baseConf) ) { + $baseConf = $bpc->ConfigDataRead(); + $baseConf = { %$baseConf, %$localConf } if ( $host ne "" ); + } + if ( $host ne "" ) { + # FJP: Again, is this really needed? $hostConf = $bpc->ConfigDataRead($host) if ( !defined($hostConf) ); + my %hostConf2 = %$hostConf; foreach my $param ( keys(%$newConf) ) { if ( $override->{$param} ) { @@ -694,11 +709,9 @@ EOF delete($hostConf->{$param}); } } - $mesg = configDiffMesg($host, \%hostConf2, $hostConf); - $err .= $bpc->ConfigDataWrite($host, $hostConf); + $mesg .= configDiffMesg($host, \%hostConf2, $hostConf); + $err .= $bpc->ConfigDataWrite($host, $hostConf); } else { - $mainConf = $bpc->ConfigDataRead() if ( !defined($mainConf) ); - my $hostsSave = []; my($hostsNew, $allHosts, $copyConf); foreach my $entry ( @{$newConf->{Hosts}} ) { @@ -727,15 +740,24 @@ EOF foreach my $host ( keys(%$copyConf) ) { my $confData = $bpc->ConfigDataRead($copyConf->{$host}); my $fromHost = $copyConf->{$host}; - $err .= $bpc->ConfigDataWrite($host, $confData); $mesg .= eval("qq($Lang->{CfgEdit_Log_Copy_host_config})"); + $err .= $bpc->ConfigDataWrite($host, $confData); } delete($newConf->{Hosts}); - $mesg .= configDiffMesg(undef, $mainConf, $newConf); - $mainConf = { %$mainConf, %$newConf }; - $err .= $bpc->ConfigDataWrite(undef, $mainConf); - $newConf->{Hosts} = $hostsSave; + + my %localConf2 = %$localConf; + foreach my $param ( keys(%$newConf) ) { + if ( $override->{$param} ) { + $localConf->{$param} = $newConf->{$param} + } else { + delete($localConf->{$param}); + } + } + $mesg .= configDiffMesg(undef, \%localConf2, $localConf); + $err .= $bpc->ConfigDataWrite("config_local", $localConf); + + $newConf->{Hosts} = $hostsSave; } if ( defined($err) ) { $tblContent .= <<EOF; @@ -791,6 +813,8 @@ EOF $doneParam->{$param} = 1; + # FJP: The exception for 'Hosts' can probably be done cleaner; + # maybe by setting a flag in its metadata $tblContent .= fieldEditBuild($ConfigMeta{$param}, $param, $newConf->{$param}, @@ -799,8 +823,8 @@ EOF $comment, $isError, $paramInfo->{onchangeSubmit}, - defined($override) ? $param : undef, - defined($override) ? $override->{$param} : undef + $param ne "Hosts" ? $param : undef, + $param ne "Hosts" ? $override->{$param} : undef, ); if ( defined($paramInfo->{comment}) ) { my $topDir = $bpc->TopDir; @@ -857,36 +881,16 @@ EOF } if ( defined($In{menu}) || $In{saveAction} eq "Save" ) { - if ( $In{saveAction} eq "Save" && !$userHost ) { - # - # Emit the new settings as orig_zZ_ parameters - # - $doneParam = {}; - foreach my $param ( keys(%ConfigMeta) ) { - next if ( $doneParam->{$param} ); - next if ( $userHost - && (!defined($bpc->{Conf}{CgiUserConfigEdit}{$param}) - || (!$PrivAdmin - && !$bpc->{Conf}{CgiUserConfigEdit}{$param})) ); - $contentHidden .= fieldHiddenBuild($ConfigMeta{$param}, - $param, - $newConf->{$param}, - "orig", - ); - $doneParam->{$param} = 1; - $In{modified} = 0; - } - } else { - # - # Just switching menus: copy all the orig_zZ_ input parameters - # - foreach my $var ( keys(%In) ) { - next if ( $var !~ /^orig_zZ_/ ); - my $val = decode_utf8($In{$var}); - $contentHidden .= <<EOF; + # FJP: Not completely sure if this always needs to be executed + # + # Just switching menus: copy all the orig_zZ_ input parameters + # + foreach my $var ( keys(%In) ) { + next if ( $var !~ /^orig_zZ_/ ); + my $val = decode_utf8($In{$var}); + $contentHidden .= <<EOF; <input type="hidden" name="$var" value="${EscHTML($val)}"> EOF - } } } else { # @@ -901,7 +905,7 @@ EOF && !$bpc->{Conf}{CgiUserConfigEdit}{$param})) ); $contentHidden .= fieldHiddenBuild($ConfigMeta{$param}, $param, - $mainConf->{$param}, + $baseConf->{$param}, "orig", ); $doneParam->{$param} = 1; @@ -1494,7 +1498,7 @@ sub configDiffMesg if ( $host ne "" ) { $conf = "host $host config"; } else { - $conf = "main config"; + $conf = "local config"; } foreach my $p ( keys(%ConfigMeta) ) { diff --git a/lib/BackupPC/Lib.pm b/lib/BackupPC/Lib.pm index 591ef57..629f1cb 100644 --- a/lib/BackupPC/Lib.pm +++ b/lib/BackupPC/Lib.pm @@ -353,7 +353,7 @@ sub ConfigRead my($ret); # - # Read main config file + # Read default config file # my($mesg, $config) = $bpc->{storage}->ConfigDataRead(); return $mesg if ( defined($mesg) ); @@ -361,6 +361,16 @@ sub ConfigRead $bpc->{Conf} = $config; # + # Read local config file + # For now: use '/etc/backuppc/config_local.pl' + # Eventually the default config file should be moved elsewhere and this + # should become '/etc/backuppc/config.pl' + # + my($mesg, $config) = $bpc->{storage}->ConfigDataRead("config_local"); + return $mesg if ( defined($mesg) ); + $bpc->{Conf} = { %{$bpc->{Conf}}, %$config }; + + # # Read host config file # if ( $host ne "" ) {
commit 3154f0af330ffeb863069d5acd281f9c22f06b10 Author: Frans Pop <[EMAIL PROTECTED]> Date: Tue Sep 4 22:20:55 2007 +0200 Do not include hosts in baseConf As far as I can tell there is no need to have hosts data in baseConf. The check for changes is done by comparing against the hosts file, not by checking against baseConf. Small regression is that now the hosts dropdown list does not get updated immediately after adding a new host. However, this already did not get done of a host was removed, so a cleaner solution for that was probably wanted anyway. diff --git a/lib/BackupPC/CGI/EditConfig.pm b/lib/BackupPC/CGI/EditConfig.pm index 1062ce8..53aeabf 100644 --- a/lib/BackupPC/CGI/EditConfig.pm +++ b/lib/BackupPC/CGI/EditConfig.pm @@ -405,13 +405,13 @@ sub action } $newConf = { %$baseConf, %$hostConf }; } else { - my $hostInfo = $bpc->HostInfoRead(); - $baseConf->{Hosts} = [map($hostInfo->{$_}, sort(keys(%$hostInfo)))]; - foreach my $param ( keys(%$localConf) ) { $override->{$param} = 1; } $newConf = { %$baseConf, %$localConf }; + + my $hostInfo = $bpc->HostInfoRead(); + $newConf->{Hosts} = [map($hostInfo->{$_}, sort(keys(%$hostInfo)))]; } } @@ -689,8 +689,6 @@ EOF my($mesg, $err); # FJP: Are these really needed? - # FJP: If they are, shouldn't $baseConf->{hosts} be initialized as well? - # FJP: OTOH, it looks as if {hosts} may only be needed in $newConf anyway $localConf = $bpc->ConfigDataRead("config_local") if ( !defined($localConf) ); if ( !defined($baseConf) ) { $baseConf = $bpc->ConfigDataRead();
signature.asc
Description: This is a digitally signed message part.
------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________ BackupPC-devel mailing list BackupPC-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/backuppc-devel http://backuppc.sourceforge.net/