[freeside-devel] FS:Conf patches
ivan
ivan at 420.am
Mon May 8 14:38:59 PDT 2000
I'm a little hesitant to add something to the standard distribution which
makes implementing write-access to configuration values much more
difficult. This may be better implemented as a generator for the
current-style configuration files.
Incidentally, why IniConf? IIRC your original proposal was to use
App::Config. It looks like App::Config may have the same problem with
complicating write access, unfortunately.
[1] Question: why is write-access to configuration values important?
Answer: interactive configuration tools
On Fri, Apr 07, 2000 at 12:08:57PM -0500, David Morton wrote:
> Attached are two patches for UID.pm and Conf.pm files. These
> patches allow for configuration to be set in a more limited
> area. This seems to work for me so far... I'm sure it could use a
> little cleanup.
>
> Here's a brief description of what it does/expects:
>
> Upon the first use of FS:Conf, it loads system wide
> values from /usr/local/etc/freeside/freeside.conf.
>
> UID.pm looks in the mapsecrets file for the username/directory pair,
> and then loads the Conf module with that new directory, for example,
> /usr/local/etc/freeside/osprey/freeside.conf
> This file has the datasource names, and most of the configuration.
>
> (The only reason for having two files, is if this is supposed to support
> two different companies on the same setup. I wouldn't mind dropping
> this expectation for a while)
>
> IniConf needs to be installed from CPAN... I may change this part, but
> the
> configuration file format won't need to change.
>
>
> the freeside.conf file has the format:
>
>
> #comments start with '#'
> [default] #section names in []'s
> key=value
> array=<<EOT
> value1
> value2
> value3
> EOT
>
> bool=true
> anotherbool=1
> yetanother=something rediculous.
>
> #this next line doesn't work.
>
> badbool=
>
> badbool= #although this does; value is spaces. It's
> a bug.
> #the comment makes it read the spaces.
> [other]
> foo=bar
>
> ______________________
>
>
> For exists() to work, the value must have a value, although it doesn't
> matter what.
>
> exists("yetanother") is true
> exists("badbool=") is not true for the first entry, although the second
> entry would overwrite the first.
> --- /home/freeside/dist/freeside_current/FS/FS/UID.pm Thu Apr 6 11:57:00 2000
> +++ FS/UID.pm Thu Apr 6 11:19:21 2000
> @@ -215,15 +215,27 @@
> my($setuser) = shift;
> $user = $setuser if $setuser;
> die "No user!" unless $user;
> - my($conf) = new FS::Conf $conf_dir;
> - my($line) = grep /^\s*$user\s/, $conf->config('mapsecrets');
> - die "User not found in mapsecrets!" unless $line;
> - $line =~ /^\s*$user\s+(.*)$/;
> - $secrets = $1;
> +
> + open MAPSECRETS, $conf_dir . "/mapsecrets";
> +
> + while (<MAPSECRETS>) {
> + if (/^\s*$user\s+(.*)$/) {
> + $secrets = $1;
> + last;
> + }
> + }
> die "Illegal mapsecrets line for user?!" unless $secrets;
> - ($datasrc, $db_user, $db_pass) = $conf->config($secrets)
> +
> +
> + my($conf) = new FS::Conf "$conf_dir$secrets" ;
> + ($datasrc, $db_user, $db_pass) = $conf->config("datasource")
> or die "Can't get secrets: $!";
> - $FS::Conf::default_dir = $conf_dir. "/conf.$datasrc";
> ($datasrc, $db_user, $db_pass);
> }
>
> --- /home/freeside/dist/freeside_current/FS/FS/Conf.pm Thu Apr 6 11:57:00 2000
> +++ FS/Conf.pm Fri Apr 7 11:37:14 2000
> @@ -1,7 +1,9 @@
> package FS::Conf;
>
> -use vars qw($default_dir);
> +use vars qw(%configs $config_main);
> use IO::File;
> +use IniConf;
> +use Carp;
>
> =head1 NAME
>
> @@ -19,38 +21,83 @@
> $dir = $conf->dir;
>
> $value = $conf->config('key');
> + $value = $conf->config('key','section');
> @list = $conf->config('key');
> $bool = $conf->exists('key');
>
> =head1 DESCRIPTION
>
> -Read access to Freeside configuration values. Keys currently map to filenames,
> -but this may change in the future.
> +Read access to Freeside configuration values. Freeside looks for a file named
> +F<freeside.conf> in the directory named, or F</usr/local/etc/freeside> as default.
> +FS::Conf stores the configuration in a class variable %configs, so that it won't
> +have to be reloaded if new is called again. The freeside.conf file is formatted
> +like an .ini file; see the manpage for IniConf
>
> =head1 METHODS
>
> =over 4
>
> +=cut
> +
> +BEGIN {
> + $default_dir = "/usr/local/etc/freeside"; #if this could be set be a command
> + #line argument, that would be nifty
> +
> +
> + if ($config_main = IniConf->new( -file => $default_dir .
> + "/freeside.conf")) {
> + my $mainself={ 'dir' => $default_dir,
> + 'config' => $config_main} ;
> + bless $mainself, "FS::Conf";
> + $configs{$default_dir} = $mainself;
> + } else {
> + print STDERR "Could not open config file: $default_dir/freeside.conf\n"
> + . "There were problems on the following lines:\n" .
> + join "\n", @IniConf::errors;
> + print "\n";
> + exit();
> + }
> +}
> +
> +
> =item new [ DIRECTORY ]
>
> -Create a new configuration object. A directory arguement is required if
> -$FS::Conf::default_dir has not been set.
> +Create a new configuration object. Defaults to F</usr/local/etc/freeside/> if
> +no parameter is passed; otherwise it looks for the F<freeside.conf> file in the
> +directory indicated.
>
> =cut
>
> sub new {
> - my($proto,$dir) = @_;
> - my($class) = ref($proto) || $proto;
> - my($self) = { 'dir' => $dir || $default_dir } ;
> - bless ($self, $class);
> + my($proto,$dir) = @_;
> + my($class) = ref($proto) || $proto;
> +
> + $dir = $default_dir if !defined($dir);
> + $dir =~ s/(.*)\/$/$1/;
> +
> + if (exists $configs{$dir}) {
> + return $configs{$dir};
> + }
> +
> + #print "loading more config values from $dir/freeside.conf\n";
> +
> +
> + my $config = IniConf->new( -file => $dir . "/freeside.conf");
> + my($self) = { 'dir' => $dir,
> + 'config' => $config} ;
> +
> + bless $self, $class;
> + $configs{$dir} = $self;
> +
> }
>
> =item dir
>
> -Returns the directory.
> +Returns the directory. (Not sure if this is needed anymore - DGM)
>
> =cut
>
> +
> sub dir {
> my($self) = @_;
> my $dir = $self->{dir};
> @@ -64,49 +111,56 @@
> =item config
>
> Returns the configuration value or values (depending on context) for key.
> +Optional section parameter specifies which section to look in for the key;
> +defaults to "default". A temporary hack allows for the key to include
> +a directory path - this will be interpreted as a section, ie.
> +C<config("/foo/bar/file")> translates to C<config("file", "/foo/bar")>
>
> =cut
>
> sub config {
> - my($self,$file)=@_;
> - my($dir)=$self->dir;
> - my $fh = new IO::File "<$dir/$file" or return;
> - if ( wantarray ) {
> - map {
> - /^(.*)$/
> - or die "Illegal line (array context) in $dir/$file:\n$_\n";
> - $1;
> - } <$fh>;
> - } else {
> - <$fh> =~ /^(.*)$/
> - or die "Illegal line (scalar context) in $dir/$file:\n$_\n";
> - $1;
> - }
> + my($self,$file, $section)=@_;
> + my($dir)=$self->{dir};
> +
> + $section = "default" if !defined $section;
> +
> + if ($file =~ /(.*)\/(.*)/) { #subdirectories translate to sections?
> + $section = $1; #backwards compatability hack
> + $file = $2;
> + }
> +
> + my $result = eval '$configs{$dir}->{config}->val($section, $file)';
> +
> +
> +
> }
>
> =item exists
>
> -Returns true if the specified key exists, even if the corresponding value
> -is undefined.
> +Returns true if the specified key exists, no matter what the value. (A value
> +must exist in the configuration file, though.) Parameters are the same as
> +C<config>
>
> =cut
>
> sub exists {
> - my($self,$file)=@_;
> - my($dir) = $self->dir;
> - -e "$dir/$file";
> + my($self,$file, $section)=@_;
> + my($dir) = $self->{dir};
> + $section = "default" if !defined $section;
> +
> + if ($file =~ /(.*)\/(.*)/) { #subdirectories translate to sections...
> + $section = $1; #backwards compatability hack
> + $file = $2;
> + }
> +
> + my $result = eval '$configs{$dir}->{config}->val("default",$file)';
> +
> + if ($@) {
> + croak "FATAL: Problem in FS::Conf::exists!";
> + } else {
> + return $result;
> + }
> }
>
> -=back
> -
> -=head1 BUGS
> -
> -Write access (with locking) should be implemented.
> -
> -=head1 SEE ALSO
> -
> -config.html from the base documentation contains a list of configuration files.
> -
> -=cut
>
> 1;
--
meow
_ivan
More information about the freeside-devel
mailing list