blob: 1bd0191e56b8a0e85c087b9d65d9445ef263a111 [file] [log] [blame]
#!/usr/bin/env python
# coding: UTF-8
# pt-config
#
# Copyright(c) 2015 Uptime Technologies, LLC.
import os, sys
libpath = os.path.abspath(os.path.dirname(sys.argv[0]) + "/../lib")
sys.path.append(libpath)
import getopt
import os
import re
from stat import *
import log
class PostgressqlConf():
fp = None
def __init__(self, conffile):
self.conffile = conffile
log.info("Reading: " + self.conffile)
def open(self):
try:
self.fp = open(self.conffile)
except OSError, err:
log.error(err.strerror + " (" + self.conffile + ")")
sys.exit(1)
except IOError, err:
log.error(err.strerror + " (" + self.conffile + ")")
sys.exit(1)
def find(self, line, key):
m = re.search(key + " *=", line[0:len(key) + 10])
if m is not None:
return True
return False
def is_disabled(self, line, key):
m = re.search("#.*" + key + " *=", line[0:len(key) + 10])
if m is not None:
return True
return False
def parse(self, line):
# quoted value accepts a zero-length string.
m = re.search("(.*=[ ]*')([^']*)('.*)", line)
# non-quoted value
if m is None:
m = re.search("(.*=[ ]*)([^ \t]+)(.*)", line)
return [m.groups(0)[0], m.groups(0)[1], m.groups(0)[2]]
def get(self, key):
self.open()
val = []
for l in self.fp.readlines():
l = l.rstrip('\r\n')
# log.debug("readlines: " + l)
if self.find(l, key) is True:
log.debug("find: " + l)
if self.is_disabled(l, key) is True:
log.debug("disabled: " + l)
a = self.parse(l)
# value and is_disabled?
val.append([ a[1], True ])
else:
log.debug(l)
a = self.parse(l)
log.debug(a[1])
val.append([ a[1], False ])
self.fp.close()
# not found
if len(val) == 0:
return None
return val
def set(self, key, value, dryrun=True):
self.open()
lines = ""
oldline = None
newline = None
for l in self.fp.readlines():
l = l.rstrip('\r\n')
if self.find(l, key) is True:
oldline = l
a = self.parse(l)
l = a[0].replace('#', '') + value + a[2]
newline = l
log.debug("set: " + l)
lines = lines + l + "\n"
if oldline is None and newline is None:
log.error("Parameter %s not found." % args[1])
return False
self.fp.close()
if dryrun is True:
log.info("Dry-run mode:")
log.info(" Old: " + oldline)
log.info(" New: " + newline)
return True
else:
log.info("Applying:")
log.info(" Old: " + oldline)
log.info(" New: " + newline)
return self.update_conf(lines)
def disable(self, key, dryrun=True):
self.open()
lines = ""
oldline = None
newline = None
for l in self.fp.readlines():
l = l.rstrip('\r\n')
if self.find(l, key) is True:
oldline = l
a = self.parse(l)
l = '#' + a[0].replace('#', '') + a[1] + a[2]
newline = l
log.debug("set: " + l)
lines = lines + l + "\n"
self.fp.close()
if oldline is None and newline is None:
log.error("Parameter %s not found." % args[1])
return False
if dryrun is True:
log.info("Dry-run mode:")
log.info(" Old: " + oldline)
log.info(" New: " + newline)
return True
else:
log.info("Applying:")
log.info(" Old: " + oldline)
log.info(" New: " + newline)
return self.update_conf(lines)
def update_conf(self, conf):
st = os.stat(self.conffile)
log.debug(st)
try:
os.rename(self.conffile, self.conffile + ".bak")
except OSError, err:
log.error(err.strerror + " (" + self.conffile + ")")
sys.exit(1)
except IOError, err:
log.error(err.strerror + " (" + self.conffile + ")")
sys.exit(1)
f = open(self.conffile, "w")
f.write(conf)
f.close()
os.chmod(self.conffile, st[ST_MODE])
# if running with superuser, the file owner/group need to be changed.
if os.getuid() == 0:
os.chown(self.conffile, st[ST_UID], st[ST_GID])
log.info("Updated: " + self.conffile)
return True
def usage():
print ""
print "Usage: " + os.path.basename(sys.argv[0]) + " [option...] [command] [param [value]]"
print ""
print "Commands:"
print " get [PARAM] Get a current value of a parameter."
print " set [PARAM] [VALUE] Set a new value for a parameter."
print " disable [PARAM] Comment a parameter out."
print ""
print "Options:"
print " -D, --pgdata=PGDATA Specify a PostgreSQL database cluster."
print " --apply Apply change(s)."
print ""
print " --help Print this help."
print ""
if __name__ == "__main__":
try:
opts, args = getopt.getopt(sys.argv[1:], "D:",
["help", "debug", "pgdata=", "apply", "disable"])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
pgdata = None
if os.environ.get("PGDATA") is not None:
pgdata = os.environ.get("PGDATA")
dryrun = True
debug = False
for o, a in opts:
if o in ("-D", "--pgdata"):
pgdata = a
elif o in ("--debug"):
debug = True
log.setLevel(log.DEBUG)
elif o in ("--apply"):
dryrun = False
elif o in ("--help"):
usage()
sys.exit(0)
else:
print "unknown option: " + o + "," + a
sys.exit(1)
if pgdata is None:
log.info("Specify PGDATA directory.")
usage()
sys.exit(0)
log.debug(args)
if len(args) != 2 and len(args) != 3:
usage()
sys.exit(1)
p = PostgressqlConf(pgdata + '/postgresql.conf')
exit_code = 0
if args[0] == 'get':
v = p.get(args[1])
if v is not None:
for vv in v:
if vv[1] is True:
print(vv[0] + " (disabled)")
else:
print(vv[0])
exit_code = 0
else:
log.error("Parameter %s not found." % args[1])
exit_code = 1
elif args[0] == 'set':
if len(args) < 3:
usage()
sys.exit(1)
r = p.set(args[1], args[2], dryrun)
if r is True:
exit_code = 0
else:
exit_code = 1
elif args[0] == 'disable':
r = p.disable(args[1], dryrun)
if r is True:
exit_code = 0
else:
exit_code = 1
sys.exit(exit_code)