Index: Debconf/Config.pm =================================================================== --- Debconf/Config.pm (revision 1851) +++ Debconf/Config.pm (working copy) @@ -181,6 +181,25 @@ ); $config->{config} = "_ENV_stack"; } + + # If the templates database is readonly, stack a writable in-memory + # one on top so that at least we can act as a passthrough UI agent. + my $templates=Debconf::DbDriver->driver($config->{templates}); + if (ref $templates and $templates->{readonly}) { + Debconf::Db->makedriver( + driver => "Pipe", + name => "_mem_templates_cache", + infd => "none", + outfd => "none", + format => "822", + ); + Debconf::Db->makedriver( + driver => "Stack", + name => "_mem_templates_stack", + stack => "_mem_templates_cache, $config->{templates}", + ); + $config->{templates} = "_mem_templates_stack"; + } } =item getopt Index: Debconf/DbDriver/Stack.pm =================================================================== --- Debconf/DbDriver/Stack.pm (revision 1851) +++ Debconf/DbDriver/Stack.pm (working copy) @@ -18,7 +18,7 @@ shadow items lower in the stack, so requests for items will be passed on to the first driver in the stack that contains the item. -Writing to the stack is more complex, because we meed to worry about +Writing to the stack is more complex, because we need to worry about readonly drivers. Instead of trying to write to a readonly driver and having it fail, this module will copy the item from the readonly driver to the writable driver closest to the top of the stack that accepts the @@ -73,6 +73,15 @@ $this->error("stack is empty") if ! @{$this->{stack}}; #$this->error("topmost driver not writable") # if $this->{stack}->[0]->{readonly} && ! $this->{readonly}; + + if (! $this->{readonly}) { + # If all drivers are readonly, then the whole stack is. + my $readonly=1; + foreach my $driver (@{$this->{stack}}) { + $readonly=0 if ! $driver->{readonly}; + } + $this->{readonly}=1 if $readonly; + } } =head2 iterator Index: Debconf/DbDriver/Pipe.pm =================================================================== --- Debconf/DbDriver/Pipe.pm (revision 1851) +++ Debconf/DbDriver/Pipe.pm (working copy) @@ -29,7 +29,9 @@ =item outfd -File descriptor number to write to. Defaults to writing to stdout. +File descriptor number to write to. Defaults to writing to stdout. If +it's set to "none", the db will be thrown away rather than saved. Setting +both infd and outfd to none gets you a writable temporary db in memory. =item format @@ -95,7 +97,7 @@ =sub shutdown Save the entire cache out to the fd. Always writes the cache, even if it's -not dirty, for consitency's sake. +not dirty, for consistency's sake. =cut @@ -106,20 +108,24 @@ my $fh; if (defined $this->{outfd}) { - open ($fh, ">&=$this->{outfd}") or - $this->error("could not open file descriptor #$this->{outfd}: $!"); + if ($this->{outfd} ne 'none') { + open ($fh, ">&=$this->{outfd}") or + $this->error("could not open file descriptor #$this->{outfd}: $!"); + } } else { open ($fh, '>-'); } - $this->{format}->beginfile; - foreach my $item (sort keys %{$this->{cache}}) { - next unless defined $this->{cache}->{$item}; # skip deleted - $this->{format}->write($fh, $this->{cache}->{$item}, $item); + if (defined $fh) { + $this->{format}->beginfile; + foreach my $item (sort keys %{$this->{cache}}) { + next unless defined $this->{cache}->{$item}; # skip deleted + $this->{format}->write($fh, $this->{cache}->{$item}, $item); + } + $this->{format}->endfile; + close $fh; } - $this->{format}->endfile; - close $fh; return 1; }