summaryrefslogtreecommitdiffstats
path: root/pg_conftool
diff options
context:
space:
mode:
Diffstat (limited to 'pg_conftool')
-rwxr-xr-xpg_conftool233
1 files changed, 233 insertions, 0 deletions
diff --git a/pg_conftool b/pg_conftool
new file mode 100755
index 0000000..0c98e4d
--- /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 to show and set 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>>