| #!/usr/bin/env python |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| try: |
| import os, sys, re |
| from optparse import Option, OptionParser |
| from hawqpylib.hawqlib import HawqXMLParser, parse_hosts_file, remove_property_xml, update_xml_property, local_ssh |
| from gppylib.commands.unix import getLocalHostname, getUserName |
| from gppylib.db import dbconn |
| from pygresql.pg import DatabaseError |
| from gppylib.gplog import setup_hawq_tool_logging, quiet_stdout_logging, enable_verbose_logging |
| except ImportError, e: |
| sys.exit('ERROR: Cannot import modules. Please check that you ' |
| 'have sourced greenplum_path.sh. Detail: ' + str(e)) |
| |
| logger, log_filename = setup_hawq_tool_logging('hawq_config',getLocalHostname(),getUserName()) |
| |
| def parseargs(): |
| parser = OptionParser(usage="HAWQ config options.") |
| parser.add_option('-c', '--change', type='string', |
| help="Change HAWQ Property.") |
| parser.add_option('-r', '--remove', type='string', |
| help="Remove HAWQ Property.") |
| parser.add_option('-s', '--show', type='string', |
| help="Change HAWQ Property name.") |
| parser.add_option('-l', '--list', action='store_true', |
| help="List all HAWQ Properties.") |
| parser.add_option('--skipvalidation', action='store_true', default=False) |
| parser.add_option('--ignore-bad-hosts', action='store_true', default=False, |
| help='Skips copying configuration files on host on which SSH fails') |
| parser.add_option('-q', '--quiet', action='store_true', default=False) |
| parser.add_option("-v", "--value", |
| dest="property_value", |
| help="Set HAWQ Property value.") |
| (options, args) = parser.parse_args() |
| |
| if options.quiet: |
| quiet_stdout_logging() |
| |
| if options.change and options.remove: |
| logger.error("Multiple actions specified. See the --help info.") |
| parser.exit() |
| |
| if options.change and not options.property_value: |
| logger.error("change requested but value not specified") |
| parser.exit() |
| |
| if options.show and options.list: |
| logger.error("Multiple actions specified. See the --help info.") |
| parser.exit() |
| |
| if options.show and (options.change or options.remove): |
| logger.error("Multiple actions specified. See the --help info.") |
| parser.exit() |
| |
| if options.list and (options.change or options.remove): |
| logger.error("Multiple actions specified. See the --help info.") |
| parser.exit() |
| |
| if (options.show or options.list) and options.skipvalidation: |
| logger.error("--skipvalidation can not be combined with --show/--list.") |
| parser.exit() |
| |
| return (options, args) |
| |
| |
| def check_property(hawq_site, property_name, property_value): |
| if property_name in hawq_site.hawq_dict: |
| print "GUC %s already exist in hawq-site.xml" % property_name |
| print "Update it with value: %s" % property_value |
| item_exist = True |
| else: |
| print "GUC %s does not exist in hawq-site.xml" % property_name |
| print "Try to add it with value: %s" % property_value |
| item_exist = False |
| return item_exist |
| |
| |
| def check_property_valid(hawq_site, property_name = 'None'): |
| try: |
| dburl = dbconn.DbURL(port=hawq_site.hawq_dict['hawq_master_address_port'], dbname='template1') |
| conn = dbconn.connect(dburl, True) |
| query = "select name, setting from pg_settings where name='%s';" % property_name |
| rows = dbconn.execSQL(conn, query) |
| conn.close() |
| except DatabaseError, ex: |
| print "Failed to connect to database, this script can only be run when the database is up" |
| sys.exit(1) |
| |
| if rows.rowcount == 0: |
| print "This GUC name is not valid, use --skipvalidation to do force update" |
| sys.exit(1) |
| |
| |
| def list_properties(hawq_site): |
| property_name = 'None' |
| property_value = 'None' |
| try: |
| dburl = dbconn.DbURL(port=hawq_site.hawq_dict['hawq_master_address_port'], dbname='template1') |
| conn = dbconn.connect(dburl, True) |
| query = "select name, setting from pg_settings;" |
| rows = dbconn.execSQL(conn, query) |
| conn.close() |
| except DatabaseError, ex: |
| print "Failed to connect to database, this script can only be run when the database is up" |
| sys.exit(1) |
| for row in rows: |
| property_name = row[0] |
| property_value = row[1] |
| print "GUC\t\t: %s" % property_name |
| print "Value\t\t: %s\n" % property_value |
| |
| return property_name, property_value |
| |
| |
| def show_guc(hawq_site, property_name): |
| property_value = 'None' |
| try: |
| dburl = dbconn.DbURL(port=hawq_site.hawq_dict['hawq_master_address_port'], dbname='template1') |
| conn = dbconn.connect(dburl, True) |
| query = "show %s;" % property_name |
| rows = dbconn.execSQL(conn, query) |
| if rows: |
| for row in rows: |
| property_value = row[0] |
| else: |
| print "No such GUC exist" |
| sys.exit(1) |
| conn.close() |
| except DatabaseError, ex: |
| if re.search("unrecognized configuration parameter", ex.__str__()): |
| print "Failed to retrieve GUC information, guc %s does not exist" % property_name |
| elif re.search("could not connect to server", ex.__str__()): |
| print "Failed to retrieve GUC information, the database is not accesible" |
| else: |
| print "Failed to retrieve GUC information: %s" % ex.__str__() |
| sys.exit(1) |
| |
| print "GUC\t\t: %s" % property_name |
| print "Value\t\t: %s" % property_value |
| return None |
| |
| |
| def show_property(hawq_site, property_name): |
| if property_name in hawq_site.hawq_dict: |
| print "GUC\t\t: %s" % property_name |
| print "Value\t\t: %s" % hawq_site.hawq_dict[property_name] |
| else: |
| print "Failed to retrieve GUC information, guc '%s' does not exist in hawq-site.xml" % property_name |
| return None |
| |
| |
| def update_hawq_site(org_config_file, hawq_site, property_name, property_value): |
| result = check_property(hawq_site, property_name, property_value) |
| update_xml_property(org_config_file, property_name, property_value) |
| |
| |
| def sync_hawq_site(config_dir, host_list, ignore_bad_hosts): |
| sync_host_str = "" |
| for node in host_list: |
| sync_host_str += " -h %s" % node |
| result = local_ssh("hawq scp %s %s %s/etc/hawq-site.xml =:%s/etc/" % (sync_host_str, ignore_bad_hosts, config_dir, config_dir), logger) |
| if result != 0: |
| sys.exit("sync hawq-site.xml failed.") |
| |
| if __name__ == '__main__': |
| options, args = parseargs() |
| |
| GPHOME = os.getenv('GPHOME') |
| if not GPHOME: |
| sys.exit("GPHOME environment variable not set, exit") |
| hawq_site = HawqXMLParser(GPHOME) |
| hawq_site.get_all_values() |
| org_config_file = "%s/etc/hawq-site.xml" % GPHOME |
| segment_list = parse_hosts_file(GPHOME) |
| master_host = hawq_site.hawq_dict['hawq_master_address_host'] |
| host_list = segment_list + [master_host] |
| ignore_bad_hosts = '--ignore-bad-hosts' if options.ignore_bad_hosts else '' |
| if 'hawq_standby_address_host' in hawq_site.hawq_dict: |
| standby_host = hawq_site.hawq_dict['hawq_standby_address_host'] |
| if standby_host not in ('None', 'none', ''): |
| host_list = host_list + [standby_host] |
| |
| # Update hawq-site.xml |
| if options.change: |
| if not options.property_value: |
| print "Please specify GUC value" |
| sys.exit(1) |
| if not options.skipvalidation: |
| check_property_valid(hawq_site, options.change) |
| |
| update_hawq_site(org_config_file, hawq_site, options.change, options.property_value) |
| sync_hawq_site(GPHOME, host_list, ignore_bad_hosts) |
| |
| if not options.quiet: |
| latest_hawq_site = HawqXMLParser(GPHOME) |
| latest_hawq_site.get_all_values() |
| show_property(latest_hawq_site, options.change) |
| elif options.show: |
| latest_hawq_site = HawqXMLParser(GPHOME) |
| latest_hawq_site.get_all_values() |
| show_guc(latest_hawq_site, options.show) |
| elif options.list: |
| latest_hawq_site = HawqXMLParser(GPHOME) |
| latest_hawq_site.get_all_values() |
| list_properties(latest_hawq_site) |
| elif options.remove: |
| except_list = ['hawq_master_address_host', 'hawq_master_directory', 'hawq_segment_directory'] |
| if options.remove in except_list: |
| print "Remove %s is not allowed" % options.remove |
| sys.exit(1) |
| remove_property_xml(options.remove, org_config_file, options.quiet) |
| sync_hawq_site(GPHOME, host_list, ignore_bad_hosts) |
| else: |
| print "Please input correct options" |
| sys.exit(1) |