diff options
Diffstat (limited to 'pg_conftool')
-rwxr-xr-x | pg_conftool | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/pg_conftool b/pg_conftool new file mode 100755 index 0000000..6772b66 --- /dev/null +++ b/pg_conftool @@ -0,0 +1,233 @@ +#!/usr/bin/perl +# Read and edit PostgreSQL config files +# vim:sw=4:et: +# +# (C) 2014-2017 Christoph Berg <myon@debian.org> +# +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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. + +use strict; +use warnings; +use Getopt::Long; +use PgCommon qw(quote_conf_value user_cluster_map read_cluster_conf_file + read_conf_file set_conffile_value set_conf_value disable_conffile_value + disable_conf_value cluster_exists error config_bool); + +## option parsing + +sub help ($;$) +{ + my ($exit, $error) = @_; + print STDERR "Error: $error\n" if ($error); + print "Usage: + $0 [options] [<version> <cluster name>] [<configfile>] <command> + +Options: + -b --boolean Format output as boolean + -s --short Print only value + -v --verbose Verbose output + --help This help + +Commands: + show <parameter>|all + set <parameter> <value> + remove <parameter> + edit +"; + exit $exit; +} + +my $boolean = 0; +my $short = 0; +my $verbose = 0; + +Getopt::Long::Configure ("bundling"); +help(1) unless GetOptions ( + 'help' => sub { help(0); }, + 'b|boolean' => \$boolean, + 's|short' => \$short, + 'v|verbose' => \$verbose, +); + +# find command in argument array +my $cmdidx; +for (my $i = 0; $i < @ARGV; $i++) { + if ($ARGV[$i] =~ /^(show|get|set|remove|delete|disable|edit)$/) { + $cmdidx = $i; + last; + } +} +help(1, 'No command given') unless (defined $cmdidx); + +my ($version, $cluster, $conffile); +if ($cmdidx == 0) { # operate on postgresql.conf in default cluster + ($version, $cluster) = user_cluster_map(); + error "No default cluster found" unless ($cluster); + $conffile = 'postgresql.conf'; +} elsif ($cmdidx == 1) { # operate on given file; default cluster must exist if file is relative + $conffile = $ARGV[0]; + unless ($conffile =~ m!^/!) { + ($version, $cluster) = user_cluster_map(); + error "No default cluster found" unless ($cluster); + } +} elsif ($cmdidx == 2) { # version cluster, postgresql.conf + ($version, $cluster, $conffile) = ($ARGV[0], $ARGV[1], 'postgresql.conf'); +} elsif ($cmdidx == 3) { # version cluster conffile + ($version, $cluster, $conffile) = ($ARGV[0], $ARGV[1], $ARGV[2]); +} else { + help(1, 'Too many arguments before command'); +} + +if ($cluster) { # the cluster needs to exist unless an absolute conffile was given + error "Cluster $version $cluster does not exist" + unless (cluster_exists $version, $cluster); +} + +splice @ARGV, 0, $cmdidx; # remove everything before the command +$ARGV[0] = 'show' if ($ARGV[0] eq 'get'); # accept alternative variants of some commands +$ARGV[0] = 'remove' if ($ARGV[0] =~ /delete|disable/); + +my ($cmd, $key, $value); +if ($ARGV[0] =~ /^(edit)$/) { + help(1, "$ARGV[0] takes no argument") unless (@ARGV == 1); + ($cmd) = @ARGV; +} elsif ($ARGV[0] =~ /^(show|remove)$/) { + help(1, "$ARGV[0] needs exactly one argument") unless (@ARGV == 2); + ($cmd, $key) = @ARGV; +} else { + help(1, "$ARGV[0] needs exactly two arguments") unless (@ARGV == 3); + ($cmd, $key, $value) = @ARGV; +} +#print "$version $cluster $conffile $cmd $key $value\n"; + +## main + +if ($cmd eq 'show') { + my %conf; + if ($conffile =~ m!^/!) { + %conf = read_conf_file ($conffile); + } else { + %conf = read_cluster_conf_file ($version, $cluster, $conffile); + } + + if ($key eq 'all') { + foreach my $k (sort keys %conf) { + printf "%s = %s\n", $k, quote_conf_value($conf{$k}); + } + } elsif (exists $conf{$key}) { + $conf{$key} = config_bool($conf{$key}) ? 'on' : 'off' if ($boolean); # normalize boolean output on request + if ($short) { + printf "%s\n", $conf{$key}; + } else { + printf "%s = %s\n", $key, quote_conf_value($conf{$key}); + } + } else { + print "# $key not found in $conffile\n" if ($verbose); + exit 1; + } + +} elsif ($cmd eq 'set') { + if ($conffile =~ m!^/!) { + set_conffile_value ($conffile, $key, $value); + } else { + set_conf_value ($version, $cluster, $conffile, $key, $value); + } + +} elsif ($cmd eq 'remove') { + if ($conffile =~ m!^/!) { + disable_conffile_value ($conffile, $key); + } else { + disable_conf_value ($version, $cluster, $conffile, $key); + } + +} elsif ($cmd eq 'edit') { + my $editor = 'vi'; + if ($ENV{EDITOR}) { + ($editor) = $ENV{EDITOR} =~ /(.*)/; # untaint + } + if ($conffile =~ m!^/!) { + system $editor, $conffile; + } else { + system $editor, "$PgCommon::confroot/$version/$cluster/$conffile"; + } +} + +__END__ + +=head1 NAME + +pg_conftool - read and edit PostgreSQL cluster configuration files + +=head1 SYNOPSIS + +B<pg_conftool> [I<options>] [I<version> I<cluster>] [I<configfile>] B<command> + +=head1 DESCRIPTION + +B<pg_conftool> allows showing and setting parameters in PostgreSQL configuration +files. + +If I<version> I<cluster> is omitted, it defaults to the default cluster (see +user_clusters(5) and postgresqlrc(5)). If I<configfile> is omitted, it defaults +to B<postgresql.conf>. I<configfile> can also be a path, in which case +I<version> I<cluster> is ignored. + +=head1 OPTIONS + +=over 4 + +=item B<-b>, B<--boolean> + +Format boolean value as B<on> or B<off> (not for "show all"). + +=item B<-s>, B<--short> + +Show only the value (instead of key = value pair). + +=item B<-v>, B<--verbose> + +Verbose output. + +=item B<--help> + +Print help. + +=back + +=head1 COMMANDS + +=over 4 + +=item B<show> I<parameter>|B<all> + +Show a parameter, or all present in this config file. + +=item B<set> I<parameter> I<value> + +Set or update a parameter. + +=item B<remove> I<parameter> + +Remove (comment out) a parameter from a config file. + +=item B<edit> + +Open the config file in an editor. Unless B<$EDITOR> is set, B<vi> is used. + +=back + +=head1 SEE ALSO + +user_clusters(5), postgresqlrc(5) + +=head1 AUTHOR + +Christoph Berg L<E<lt>myon@debian.orgE<gt>> |