| #!/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. |
| # ----------------------------------------------------------------------- |
| |
| |
| import os |
| import sys |
| import getopt |
| |
| import shutil |
| import subprocess |
| from stat import * |
| |
| import string |
| import random |
| |
| from ducc_util import DuccUtil |
| |
| from ducc_base import Properties |
| from ducc_base import Property |
| |
| from ducc_base import find_ducc_home |
| from ducc_base import find_localhost |
| |
| from ducc import Ducc |
| |
| import db_util as dbu |
| |
| # |
| # Create and initialize the DUCC database. In a new installation this is handled by |
| # ducc_post_install. Older installations need to run db_create as one of the steps |
| # of migration to the DB. |
| # |
| class DbCreate(DuccUtil): |
| |
| def usage(self, msg): |
| |
| if ( msg != None ): |
| print ' '.join(msg) |
| |
| |
| print 'DbCreate configures the database and installs the schema.' |
| print '' |
| print "Usage:" |
| print " db_create [options]" |
| print " If no options defaults are used for expected parameters." |
| print "" |
| print "Options:" |
| print " [-d, --db-password] <root password for database>" |
| print " This is the password DUCC uses to manage the database." |
| print "" |
| print " [-h, -? --help]" |
| print " Prints this message." |
| print "" |
| sys.exit(1) |
| |
| def main(self, argv): |
| |
| self.cmd_name_nodetool = 'nodetool' |
| |
| self.database_automanage = True |
| self.database_host_list = None |
| self.database_user = None |
| self.database_pw = None |
| |
| try: |
| opts, args = getopt.getopt(argv, 'a:o:u:d:n:h?', ['db-automanage=', 'db-host-list=', 'db-user=', 'db-password=', 'help']) |
| except: |
| self.usage("Invalid arguments " + ' '.join(argv)) |
| |
| |
| for ( o, a ) in opts: |
| if o in ('-a', '--db-automanage'): |
| if(o in { 'True', 'T', 'true', 't'}): |
| self.database_automanage = True |
| else: |
| self.database_automanage = False |
| if o in ('-o', '--db-host-list'): |
| self.database_host_list = a |
| if o in ('-u', '--db-user'): |
| self.database_user = a |
| if o in ('-d', '--db-password'): |
| self.database_pw = a |
| elif o in ('-h', '-?', '--help'): |
| self.usage(None) |
| |
| |
| |
| # abort db create if db already running |
| status = 'unknown' |
| cmd = self.DUCC_HOME+'/cassandra-server/bin/nodetool' |
| p = subprocess.Popen([cmd, 'info'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
| out, err = p.communicate() |
| if ((err != None) and (err != '')): |
| if (err.startswith(self.cmd_name_nodetool+': Failed to connect')): |
| status = 'down' |
| elif ((out != None) and (out != '')): |
| for line in out.splitlines(): |
| if(line.startswith('Uptime')): |
| status = 'up' |
| break |
| if(status != 'down'): |
| print 'unsafe to proceed, database status: '+status |
| return |
| |
| if( self.database_host_list == None ) : |
| self.database_host_list = self.ducc_properties.get("ducc.database.host.list") |
| if( self.database_host_list == None ) : |
| self.database_host_list = self.ducc_properties.get("ducc.database.host") |
| if( self.database_host_list == None ) : |
| self.database_host_list = self.ducc_properties.get("ducc.head") |
| |
| if ( self.database_user == None ): |
| self.database_user = 'ducc' |
| |
| if ( self.database_pw == None ): |
| self.database_pw = self.generate_pw() |
| |
| # start with merged properties |
| self.merge_properties(); |
| |
| # configure the database for local system and initialize the schema |
| db_node = self.ducc_properties.get("ducc.head") |
| if ( dbu.configure_database(self.DUCC_HOME, self.ducc_head, self.jvm, self.database_automanage, self.database_host_list, self.database_user, db_pw) ): |
| private_props_name = self.DUCC_HOME + '/resources.private/ducc.private.properties' |
| |
| print 'Writing database password to', private_props_name |
| ducc_site_properties = Properties(); |
| site_props_name = self.DUCC_HOME + '/resources/site.ducc.properties' |
| ducc_site_properties.load(site_props_name) |
| ducc_site_properties.put('ducc.database.automanage', str(self.database_automanage)); |
| ducc_site_properties.delete('ducc.database.host'); |
| ducc_site_properties.put('ducc.database.host.list', self.database_host_list); |
| ducc_site_properties.put('ducc.database.user', self.database_user); |
| ducc_site_properties.put('ducc.service.persistence.impl', 'org.apache.uima.ducc.database.StateServicesDb' , ['# Service manager persistence']) |
| ducc_site_properties.put('ducc.job.history.impl' , 'org.apache.uima.ducc.database.HistoryManagerDb' , ['# History and checkpoint']) |
| ducc_site_properties.put('ducc.rm.persistence.impl' , 'org.apache.uima.ducc.database.RmStatePersistence', ['# RM state persistence']) |
| |
| # if we don't die before this we need to enable db in site.ducc.properties and set the |
| # db password into resources.private/ducc.private.properties |
| ducc_site_properties.write(site_props_name) |
| |
| private_props_name = self.DUCC_HOME + '/resources.private/ducc.private.properties' |
| private_properties = Properties() |
| private_properties.load(private_props_name) |
| private_properties.delete('db_password') |
| private_properties.put('db_password', self.database_pw, ['#Db password, default is randomly generated']); |
| private_properties.write(private_props_name) |
| |
| # remerge to insure it's all correct and ready to go |
| self.merge_properties(); |
| |
| # generate a random string between 8 and 16 characters long |
| def generate_pw(self): |
| pwlen = random.randrange(8,16) |
| reply = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(pwlen)]) |
| return reply |
| |
| if __name__ == "__main__": |
| |
| instance = DbCreate() |
| instance.main(sys.argv[1:]) |