diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-06-08 08:44:47 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-06-08 09:02:33 +0300 |
commit | 2a05c7dd59041edbd32d10dae9f6a66d7ba547a4 (patch) | |
tree | 0e95b5be7fbcf2e22f7f45f15cdd156725bb4fa2 | |
parent | 2330e16c397269364c56160ea0ecac0401ea1d9b (diff) | |
download | mysqlstat-2a05c7dd59041edbd32d10dae9f6a66d7ba547a4.tar.gz mysqlstat-2a05c7dd59041edbd32d10dae9f6a66d7ba547a4.tar.bz2 |
Add setup script
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | setup/Makefile.am | 14 | ||||
-rw-r--r-- | setup/mysqlstat-setup.pl | 293 |
4 files changed, 310 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index ad9ef68..18821d9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,3 +17,3 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = src +SUBDIRS = src setup EXTRA_DIST=git2chg.awk diff --git a/configure.ac b/configure.ac index de177fd..24bb003 100644 --- a/configure.ac +++ b/configure.ac @@ -91,3 +91,3 @@ AC_ARG_WITH([snmp-config-dir], esac]) - + # Generate output @@ -96,2 +96,3 @@ AC_CONFIG_FILES([ src/Makefile + setup/Makefile ]) diff --git a/setup/Makefile.am b/setup/Makefile.am new file mode 100644 index 0000000..2f40efa --- /dev/null +++ b/setup/Makefile.am @@ -0,0 +1,14 @@ +EXTRA_DIST=mysqlstat-setup.pl + +all:; + +install-exec-local: + test -d $(DESTDIR)$(bindir) || $(mkdir_p) $(DESTDIR)$(bindir) + sed -e 's|[@]DLMODDIR[@]|@DLMODDIR@|' \ + -e 's|[@]CONFDIR[@]|@CONFDIR@|' \ + $(srcdir)/mysqlstat-setup.pl > $(DESTDIR)$(bindir)/mysqlstat-setup + chmod +x $(DESTDIR)$(bindir)/mysqlstat-setup + +uninstall-local: + rm -f $(DESTDIR)$(bindir)/mysqlstat-setup + diff --git a/setup/mysqlstat-setup.pl b/setup/mysqlstat-setup.pl new file mode 100644 index 0000000..eb54084 --- /dev/null +++ b/setup/mysqlstat-setup.pl @@ -0,0 +1,293 @@ +#!/usr/bin/perl + +use strict; +use DBI; +use Pod::Usage; +use Pod::Man; +use Getopt::Long qw(:config gnu_getopt no_ignore_case); +use File::Basename; +use File::Temp qw{tempfile}; + +=head1 NAME + +mysqlstat-setup - sets up mysqlstat Net-SNMP module + +=head1 SYNOPSIS + +B<mysqlstat-setup> +[B<-f>] +[B<-u> I<USER>] +[B<-p> I<PASSWORD>] +[B<-C> I<CONFDIR>] +[B<-L> I<LIBDIR>] +[B<--defaults-file=>I<FILE>] +[B<--force>] +[B<--host=>I<HOST>] +[B<--user=>I<USER>] +[B<--password=>I<PASSWORD>] +[B<--snmp-user=>I<USER>] +[B<--snmp-password=>I<PASSWORD>] +[B<--confdir> I<CONFDIR>] +[B<--libdir> I<LIBDIR>] + +B<mysqlstat-setup> +[B<-h>] +[B<--help>] +[B<--usage>] + +=head1 DESCRIPTION + +=head1 OPTIONS + +=cut + +my $progname = basename($0); +my $progdescr = 'Set up mysqlstat module'; + +use constant EX_OK => 0; +use constant EX_ERR => 1; + +my $libdir = q{@DLMODDIR@}; # Directory where mysqlstat.so lives. +my $confdir = q{@CONFDIR@}; # SNMP configuration directory. + +my $mysql_user; # MySQL administrator user +my $mysql_password; # His password +my $mysql_defaults_file; # Options file to use (default ~/.my.cnf) +my $mysql_host; # Host name or IP +my $mysql_port; # Port the server is listening on. + +my $snmp_user = 'snmp'; # MySQL user the plugin will be using. +my $snmp_password; # MySQL password for $snmp_user +my $snmp_host = 'localhost'; # Host to use +my $force; # Force setup even if $confdir/mysqlstat.cnf is found. + +my $sofile; # Full pathname of mysqlstat.so +my $mysqlstat_cnf; # Full pathname of mysqlstat.cnf + +my $owner_uid; # Owner UID ... +my $owner_gid; # ... and GID for the mysqlstat.cnf file. + +sub error { + my $text = shift; + print STDERR "$progname: $text\n"; + if (@_) { + print STDERR "\n"; + foreach $text (@_) { + print STDERR " $text\n"; + } + print STDERR "\n"; + } +} + +sub db_connect { + my $arg; + $arg .= ":host=$mysql_host" if defined $mysql_host; + $arg .= ":port=$mysql_port" if defined $mysql_port; + $arg .= ":;mysql_read_default_file=$mysql_defaults_file" + if defined $mysql_defaults_file; + if (!$arg + or (!defined($mysql_user) and !defined($mysql_defaults_file))) { + my $my_cnf = "$ENV{HOME}/.my.cnf"; + if (-r $my_cnf) { + error("info: using mysql option file $my_cnf"); + $arg .= ":;mysql_read_default_file=$my_cnf"; + } + } + $arg = 'DBI:mysql'.$arg; + + my $dbd = DBI->connect($arg, $mysql_user, $mysql_password, + { PrintError => 0, AutoCommit => 1 }); + unless ($dbd) { + error("can't connect to MySQL server: ".$DBI::errstr); + exit EX_ERR; + } + return $dbd; +} + +# db_modify(DB, QUERY, ARGS) +sub db_modify { + my $dbd = shift; + my $q = shift; + my $sth = $dbd->prepare($q); + my $res = $sth->execute(@_) or croak($sth->errstr); + $sth->finish; + return $res; +} + +sub sql_create_user { + my $dbd = db_connect(); + my $q = q{GRANT PROCESS, REPLICATION CLIENT ON *.* TO ?@?}; + my @args = ($snmp_user, $snmp_host); + if ($snmp_password) { + push @args, $snmp_password; + $q .= ' IDENTIFIED BY ?'; + } + db_modify($dbd, $q, @args); + db_modify($dbd, 'FLUSH PRIVILEGES'); + $dbd->disconnect; +} + +sub edit_cnf { + my $m = umask(077); + open(my $fd, '>', $mysqlstat_cnf) + or die "can't open $mysqlstat_cnf for writing: $!"; + print $fd "[mysqlstat]\n"; + print $fd "user=$snmp_user\n"; + print $fd "password=$snmp_password\n" if $snmp_password; + print $fd "host=$snmp_host\n" if $snmp_host and $snmp_host ne 'localhost'; + chown $owner_uid, $owner_gid, $fd; + close $fd; + umask($m); +} + +sub backup { + my $name = shift; + my $bkname = "${name}~"; + backup($bkname) if -f $bkname; + unless (rename($name, $bkname)) { + error("can't create backup file $bkname: $!"); + return 0; + } + return 1; +} + +sub edit_snmp_conf { + my $snmpd_conf = "$confdir/snmpd.conf"; + $snmpd_conf = readlink $snmpd_conf if -l $snmpd_conf; + + open(my $fd, '<', $snmpd_conf) + or die "can't open $snmpd_conf for reading: $!"; + + my $line = 0; + my $dlmod_line; + while (<$fd>) { + ++$line; + chomp; + s/^\s+//; + next if /^#/; + if (/^dlmod\s/) { + my @a = split /\s+/; + if ($a[$#a] eq $sofile) { + error("info: $sofile already loaded in $snmpd_conf:$line"); + return 1; + } + $dlmod_line = $line; + } + } + seek $fd, 0, 0; + + my ($ofd, $filename) = tempfile('snmpd.XXXXXX', DIR => $confdir); + if ($dlmod_line) { + $line = 0; + while (<$fd>) { + print $ofd $_; + if (++$line == $dlmod_line) { + print $ofd "# This line was added by $progname\n"; + print $ofd "dlmod mysqlstat_mib $sofile\n"; + } + } + } else { + while (<$fd>) { + print $ofd $_; + } + print $ofd "# This line was added by $progname\n"; + print $ofd "dlmod mysqlstat_mib $sofile\n"; + } + close $fd; + close $ofd; + + unless (backup($snmpd_conf)) { + error("can't preserve backup copy of $snmpd_conf"); + error("updated configuration left in file $filename"); + } elsif (not rename($filename, $snmpd_conf)) { + error("failed to rename $filename to $snmpd_conf"); + error("updated configuration left in file $filename"); + } +} + +# +GetOptions("h" => sub { + pod2usage(-message => "$progname: $progdescr", + -exitstatus => EX_OK); + }, + "help" => sub { + pod2usage(-exitstatus => EX_OK, -verbose => 2); + }, + "usage" => sub { + pod2usage(-exitstatus => EX_OK, -verbose => 0); + }, + "user|u=s" => \$mysql_user, + "password|p=s" => \$mysql_password, + "defaults-file=s" => \$mysql_defaults_file, + "host=s" => \$mysql_host, + "snmp-user=s" => \$snmp_user, + "snmp-password=s" => \$snmp_password, + "snmp-host=s" => \$snmp_host, + "confdir|C=s" => \$confdir, + "libdir|L=s" => \$libdir, + "force|f" => \$force + ) or exit(EX_ERR); + +unless ($libdir =~ m#^/#) { + error('NetSNMP library directory is not set', + "It appears you invoked a copy of $progname that hasn't been installed.", + "If you are confident in what you're doing, then please use", + "the --libdir=DIR option to inform the program about the location of the", + "library directory. Otherwise, please use the program that has been", + "installed properly."); + exit EX_ERR; +} + +unless ($confdir =~ m#^/#) { + error('NetSNMP configuration directory is not set', + "It appears you invoked a copy of $progname that hasn't been installed.", + "If you are confident in what you're doing, then please use", + "the --confdir=DIR option to inform the program about the location of the", + "configuration directory. Otherwise, please use the program that has been", + "installed properly."); + exit EX_ERR; +} + +$sofile = "$libdir/mysqlstat.so"; + +unless (-f $sofile) { + error("the library $sofile is not found"); + exit EX_ERR; +} + +$mysqlstat_cnf = "$confdir/mysqlstat.cnf"; +if (-e $mysqlstat_cnf and not $force) { + error("file $mysqlstat_cnf already exists", + "If you are sure you wan't to re-setup mysqlstat, use the --force option, e.g.:", + " $progname --force"); + exit EX_ERR; +} + +unless ($< == 0) { + error("must be run as root"); + exit EX_ERR; +} +unless (-d $confdir) { + error("no such directory: $confdir"); + exit EX_ERR; +} + +unless (-r "$confdir/snmpd.conf") { + error("the file $confdir/snmpd.conf does not exist or is not readable", + "If NetSNMP configuration files are located in another directory,", + "then reconfigure mysqlstat with the --with-snmp-config-dir=DIR option", + "and rerun $progname"); + exit EX_ERR; +} + +my @st = stat "$confdir/snmpd.conf" + or die "can't stat $confdir/snmpd.conf: $!"; +($owner_uid, $owner_gid) = @st[4..5]; + +# 1. Create MySQL user & grant it the necessary privs. +sql_create_user; +# 2. Edit $CONFDIR/mysqlstat.cnf +edit_cnf; +# 3. Edit snmpd.conf +edit_snmp_conf; + |