You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2012/10/22 13:28:24 UTC

git commit: CLOUDSTACK-374: Allow users to choose mgmt server host

Updated Branches:
  refs/heads/master 1055ea8f6 -> 947d8cc6d


CLOUDSTACK-374: Allow users to choose mgmt server host

Users can now explicitly specify cluster management server node IP.
Example:

cloud-setup-database user:passwd@dbhost -i 192.168.1.10, or
cloud-setup-database user:passwd@dbhost --mshost 192.168.1.10

Also, strips off trailing whitespaces.

Signed-off-by: Rohit Yadav <bh...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/947d8cc6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/947d8cc6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/947d8cc6

Branch: refs/heads/master
Commit: 947d8cc6de6b69394457fd6f07d3bba82e14fd9f
Parents: 1055ea8
Author: Rohit Yadav <bh...@apache.org>
Authored: Mon Oct 22 16:46:57 2012 +0530
Committer: Rohit Yadav <bh...@apache.org>
Committed: Mon Oct 22 16:56:50 2012 +0530

----------------------------------------------------------------------
 setup/bindir/cloud-setup-databases.in |  149 +++++++++++++++-------------
 1 files changed, 78 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/947d8cc6/setup/bindir/cloud-setup-databases.in
----------------------------------------------------------------------
diff --git a/setup/bindir/cloud-setup-databases.in b/setup/bindir/cloud-setup-databases.in
index 040be5b..3368fa0 100755
--- a/setup/bindir/cloud-setup-databases.in
+++ b/setup/bindir/cloud-setup-databases.in
@@ -77,12 +77,12 @@ class DBDeployer(object):
         def backUpDbDotProperties():
             dbpPath = os.path.join(self.dbConfPath, 'db.properties')
             copyPath = os.path.join(self.dbConfPath, 'db.properties.origin')
-            
+
             if os.path.isfile(dbpPath):
                 shutil.copy2(dbpPath, copyPath)
-        
+
         backUpDbDotProperties()
-    
+
     def postRun(self):
         def cleanOrRecoverDbDotProperties():
             dbpPath = os.path.join(self.dbConfPath, 'db.properties')
@@ -91,24 +91,24 @@ class DBDeployer(object):
                 if not self.success:
                     shutil.copy2(copyPath, dbpPath)
                 os.remove(copyPath)
-        
+
         cleanOrRecoverDbDotProperties()
         if os.path.exists(self.tmpMysqlFile):
             os.remove(self.tmpMysqlFile)
-                
-        
+
+
     def info(self, msg, result=None):
         output = ""
         if msg is not None:
             output = "%-80s"%msg
-            
+
         if result is True:
             output += "[ \033[92m%-2s\033[0m ]\n"%"OK"
         elif result is False:
             output += "[ \033[91m%-6s\033[0m ]\n"%"FAILED"
         sys.stdout.write(output)
         sys.stdout.flush()
-    
+
     def debug(self, msg):
         msg = "DEBUG:%s"%msg
         sys.stdout.write(msg)
@@ -121,13 +121,13 @@ class DBDeployer(object):
         else:
             self.dbDotProperties[key] = (value, self.dbDotPropertiesIndex)
             self.dbDotPropertiesIndex += 1
-    
+
     def getDbProperty(self, key):
         if not self.dbDotProperties.has_key(key):
             return None
         (value, index) = self.dbDotProperties[key]
         return value
-        
+
     def runMysql(self, text, table, isRoot=False):
         kwargs = {}
         if not isRoot:
@@ -136,7 +136,7 @@ class DBDeployer(object):
         else:
             kwargs['user'] = self.rootuser
             if self.rootpassword != '': kwargs['passwd'] = self.rootpassword
-            
+
         kwargs['port'] = self.port
         kwargs['host'] = self.host
 
@@ -148,7 +148,7 @@ class DBDeployer(object):
             mysqlCmds.append('<')
             mysqlCmds.append(self.tmpMysqlFile)
             runCmd(mysqlCmds)
-            
+
         except Exception, e:
             err = '''Encountering an error when executing mysql script
 ----------------------------------------------------------------------
@@ -163,13 +163,13 @@ Sql parameters:
 ----------------------------------------------------------------------
             '''%(table, e.__str__(), kwargs)
             self.errorAndExit(err)
-        
+
     def errorAndExit(self, msg):
         self.postRun()
         err = '''\n\nWe apologize for below error:
-***************************************************************      
+***************************************************************
 %s
-*************************************************************** 
+***************************************************************
 Please run:
 
     cloud-setup-database -h
@@ -184,7 +184,7 @@ for full help
         if not self.rootuser:
             self.info("No mysql root user specified, will not create Cloud DB schema\n", None)
             return
-        
+
         replacements = (
                 ("CREATE USER cloud identified by 'cloud';",
                     "CREATE USER %s@`localhost` identified by '%s'; CREATE USER %s@`%%` identified by '%s';"%(
@@ -211,7 +211,7 @@ for full help
                 ("CALL `test`.`drop_user_if_exists`() ;",
                     ""),
             )
-        
+
         for f in ["create-database","create-schema","create-database-premium","create-schema-premium"]:
             p = os.path.join(self.dbFilesPath,"%s.sql"%f)
             if not os.path.exists(p): continue
@@ -220,7 +220,7 @@ for full help
             self.info("Applying %s"%p)
             self.runMysql(text, p, True)
             self.info(None, True)
-        
+
         if self.serversetup:
             conf = os.path.join(self.dbConfPath, 'db.properties')
             pcp = os.path.pathsep.join( glob.glob( os.path.join ( r"@PREMIUMJAVADIR@" , "*" ) ) )
@@ -243,21 +243,21 @@ for full help
             self.info("Applying %s"%p)
             self.runMysql(text, p, True)
             self.info(None, True)
-                
+
         for f in ["templates","create-index-fk"]:
             p = os.path.join(self.dbFilesPath,"%s.sql"%f)
             text = file(p).read()
             self.info("Applying %s"%p)
             self.runMysql(text, p, True)
             self.info(None, True)
-            
+
         p = os.path.join(self.dbFilesPath,"schema-level.sql")
         if os.path.isfile(p):
             text = file(p).read()
             self.info("Applying %s"%p)
             self.runMysql(text, p, True)
             self.info(None, True)
-            
+
         awsApiDbDir = '/usr/share/cloud/setup/bridge/db'
         for f in ["cloudbridge_db.sql"]:
             p = os.path.join(awsApiDbDir,f)
@@ -277,7 +277,7 @@ for full help
                 self.info("Applying %s"%p)
                 self.runMysql(text, p, True)
                 self.info(None, True)
-               
+
     def prepareDBFiles(self):
         def prepareDBDotProperties():
             dbpPath = os.path.join(self.dbConfPath, 'db.properties')
@@ -289,7 +289,7 @@ for full help
                 line = line.strip()
                 if line.startswith("#"): key = line; value = ''; passed = True
                 if line == '' or line == '\n': key = self.magicString + str(emptyLine); value = ''; emptyLine += 1; passed = True
-                
+
                 try:
                     if not passed:
                         (key, value) = line.split('=', 1)
@@ -312,9 +312,9 @@ for example:
                     self.errorAndExit(err)
                 self.putDbProperty(key, value)
             self.info("Preparing %s"%dbpPath, True)
-        
+
         prepareDBDotProperties()
-    
+
     def finalize(self):
         def finalizeDbProperties():
             entries = []
@@ -327,12 +327,12 @@ for example:
                 else:
                     entries.insert(index, "%s=%s"%(key, value))
             file(os.path.join(self.dbConfPath, 'db.properties'), 'w').write('\n'.join(entries))
-        
+
         self.info("Finalizing setup ...", None)
         finalizeDbProperties()
         self.info(None, True)
         self.success = True # At here, we have done successfully and nothing more after this flag is set
-            
+
     def grabSystemInfo(self):
         def getIpAddr():
             try:
@@ -346,10 +346,11 @@ for example:
                 return '127.0.0.1'
             except Exception, e:
                 return "127.0.0.1"
-        
-        self.ip = getIpAddr()
-        self.info("Detected local IP address as %s, will use as cluster management server node IP"%self.ip, True)
-            
+
+        if not self.ip:
+            self.ip = getIpAddr()
+            self.info("Detected local IP address as %s, will use as cluster management server node IP" % self.ip, True)
+
     def checkSystemSetup(self):
         def checkCloudDbFiles():
             self.info("Checking Cloud database files ...", None)
@@ -357,25 +358,25 @@ for example:
             for dbf in dbfpaths:
                 if not os.path.exists(dbf):
                     self.errorAndExit("Cannot find %s"%dbf)
-            
+
             coreSchemas = ['create-database.sql', 'create-schema.sql', 'templates.sql', 'create-index-fk.sql']
             if not self.serversetup:
                 coreSchemas.append('server-setup.sql')
-            
+
             checkingList = [os.path.join(self.dbFilesPath, x) for x in coreSchemas]
             checkingList.append(self.encryptionJarPath)
             for f in checkingList:
                 if not os.path.isfile(f):
                     self.errorAndExit("Cloud DB required file %s was not found"%f)
             self.info(None, True)
-        
+
         def checkDbserverHostname():
             self.info("Checking mysql server hostname ...", None)
             if resolves_to_ipv6(self, self.port):
                 err = "%s resolves to an IPv6 address.  The CloudStack does not support IPv6 yet.\nPlease fix this issue in either /etc/hosts or your DNS configuration.\n"%self.host
                 self.errorAndExit(err)
             self.info(None, True)
-        
+
         def checkHostName():
             self.info("Checking local machine hostname ...", None)
             try:
@@ -384,7 +385,7 @@ for example:
                 err = "The host name of this computer does not resolve to an IP address.\nPlease use your operating system's network setup tools to fix this ('hostname --fqdn' %s).\n"%e.__str__()
                 self.errorAndExit(err)
             self.info(None, True)
-        
+
         def checkSELinux():
             self.info("Checking SELinux setup ...", None)
             try:
@@ -395,54 +396,54 @@ for example:
                 if e.errno == 2: pass
                 else: self.errorAndExit(e.__str__())
             self.info(None, True)
-                
+
         checkCloudDbFiles()
         checkHostName()
         checkSELinux()
-    
+
     def processEncryptionStuff(self):
         def encrypt(input):
             cmd = ['java','-classpath',self.encryptionJarPath,'org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI', 'encrypt.sh', 'input=%s'%input, 'password=%s'%self.mgmtsecretkey,'verbose=false']
             return runCmd(cmd).strip('\n')
-        
+
         def saveMgmtServerSecretKey():
             if self.encryptiontype == 'file':
                 file(self.encryptionKeyFile, 'w').write(self.mgmtsecretkey)
-                
+
         def formatEncryptResult(value):
             return 'ENC(%s)'%value
-        
+
         def encryptDBSecretKey():
             self.putDbProperty('db.cloud.encrypt.secret', formatEncryptResult(encrypt(self.dbsecretkey)))
-        
+
         def encryptDBPassword():
             dbPassword = self.getDbProperty('db.cloud.password')
             if dbPassword == '': return # Don't encrypt empty password
             if dbPassword == None: self.errorAndExit('Cannot find db.cloud.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
             self.putDbProperty('db.cloud.password', formatEncryptResult(encrypt(dbPassword)))
-            
+
             usagePassword = self.getDbProperty('db.usage.password')
             if usagePassword == '': return # Don't encrypt empty password
             if usagePassword == None: self.errorAndExit('Cannot find db.usage.password in %s'%os.path.join(self.dbConfPath, 'db.properties'))
             self.putDbProperty('db.usage.password', formatEncryptResult(encrypt(usagePassword)))
-        
+
         self.info("Processing encryption ...", None)
         self.putDbProperty("db.cloud.encryption.type", self.encryptiontype)
         saveMgmtServerSecretKey()
         encryptDBSecretKey()
         encryptDBPassword()
         self.info(None, True)
-        
+
     def parseOptions(self):
         def parseOtherOptions():
             if self.options.rootcreds:
                 self.rootuser,self.rootpassword = parseUserAndPassword(self.options.rootcreds)
                 if self.rootuser == self.user:
                     self.errorAndExit("--deploy-as= user name cannot be the user name supplied for the connection credentials")
-                
+
                 self.info("Mysql root user name:%s"%self.rootuser, True)
                 self.info("Mysql root user password:%s"%self.rootpassword, True)
-                
+
             if self.options.serversetup:
                 if not self.options.rootcreds:
                     self.errorAndExit("--auto= requires valid --deploy-as= credentials")
@@ -450,12 +451,16 @@ for example:
                     self.errorAndExit("%s is not a valid file"%self.options.serversetup)
                 self.serversetup = self.options.serversetup
                 self.info("User specified server-setup.sql file at %s"%self.serversetup, True)
-            
+
+            if self.options.mshostip:
+                self.ip = self.options.mshostip
+                self.info("Using specified cluster management server node IP %s" % self.options.mshostip, True)
+
             self.encryptiontype = self.options.encryptiontype
             self.mgmtsecretkey = self.options.mgmtsecretkey
             self.dbsecretkey = self.options.dbsecretkey
             self.isDebug = self.options.debug
-            
+
         def parseUserAndPassword(cred):
             stuff = cred.split(':')
             if len(stuff) != 1 and len(stuff) != 2:
@@ -467,13 +472,13 @@ for example:
                 password = ''
             else:
                 password = stuff[1]
-                
+
             forbidden = "' \\`"
             for f in forbidden:
                 if f in user: self.errorAndExit("User name cannot have the %r characters"%f)
                 if f in password: self.errorAndExit("Password cannot have the %r characters"%f)
             return user, password
-            
+
         def parseCasualCredit():
             def parseHostInfo(info):
                 stuff = info.split(":")
@@ -488,18 +493,18 @@ for example:
                 else:
                     self.errorAndExit("Invalid host and port format, it must be in format of host:port (%s)"%info)
                 return host, port
-    
+
             if len(self.args) == 0:
                 self.errorAndExit("Please specify user:password@hostname")
             if len(self.args) > 1:
                 self.errorAndExit("There are more than one parameters for user:password@hostname (%s)"%self.args)
-            
+
             arg = self.args[0]
             stuff = arg.split("@", 1)
             if len(stuff) == 1: stuff.append("localhost")
             self.user,self.password = parseUserAndPassword(stuff[0])
             self.host,self.port = parseHostInfo(stuff[1])
-            
+
             self.info("Mysql user name:%s"%self.user, True)
             if self.password:
                 self.info("Mysql user password:%s"%self.password, True)
@@ -507,32 +512,32 @@ for example:
                 self.info("Mysql user password:", True)
             self.info("Mysql server ip:%s"%self.host, True)
             self.info("Mysql server port:%s"%self.port, True)
-        
+
         def validateParameters():
             if self.encryptiontype != 'file' and self.encryptiontype != 'web':
                 self.errorAndExit('Wrong encryption type %s, --encrypt-type can only be "file" or "web'%self.encryptiontype)
-            
+
     #---------------------- option parsing and command line checks ------------------------
         usage = """%prog user:[password]@mysqlhost:[port] [--deploy-as=rootuser:[rootpassword]] [--auto=/path/to/server-setup.xml] [-e ENCRYPTIONTYPE] [-m MGMTSECRETKEY] [-k DBSECRETKEY] [--debug]
-    
+
     This command sets up the CloudStack Management Server and CloudStack Usage Server database configuration (connection credentials and host information) based on the first argument.
-    
+
     If the the --deploy-as option is present, this command will also connect to the database using the administrative credentials specified as the value for the --deploy-as argument, construct the database environment needed to run the CloudStack Management Server, and alter the password specified for the user in the first argument.  In this case, the user name specified in --deploy-as= cannot be the same as the user name specified for the connection credentials that the CloudStack Management Server will be set up with.
-    
+
     If a server-setup.xml cloud setup information file is specified with the --auto option, this command will also construct a customized database environment according to the cloud setup information in the file.
-    
+
     The port and the password are optional and can be left out..  If host is omitted altogether, it will default to localhost.
-    
+
     Examples:
-    
-    %prog cloud:secret 
+
+    %prog cloud:secret
         sets user cloud and password 'secret' up in
         @MSCONF@/db.properties, using localhost as the
         database server
-        
-    %prog sheng:rules@192.168.1.1 
+
+    %prog sheng:rules@192.168.1.1
         sets these credentials up in @MSCONF@/db.properties
-        
+
     %prog alex:founder@1.2.3.4 --deploy-as=root:nonsense
         sets alex up as the MySQL user, then connects as the root user
         with password 'nonsense', and recreates the databases, creating
@@ -542,7 +547,7 @@ for example:
         In addition actions performing in above example, using 'password' as management server encryption key
         and 'dbpassword' as database encryption key, saving management server encryption key to a file as the
         encryption type specified by -e is file.
-    
+
     %prog alena:tests@5.6.7.8 --deploy-as=root:nonsense --auto=/root/server-setup.xml
         sets alena up as the MySQL user, then connects as the root user
         with password 'nonsense' to server 5.6.7.8, then recreates the
@@ -562,12 +567,14 @@ for example:
                           help="Secret key used to encrypt confidential parameters in db.properties. A string, default is password")
         self.parser.add_option("-k", "--database-secretkey", action="store", type="string", dest="dbsecretkey", default="password",
                           help="Secret key used to encrypt sensitive database values. A string, default is password")
-        
+        self.parser.add_option("-i", "--mshost", action="store", type="string", dest="mshostip", default="",
+                          help="Cluster management server host IP. A string, by default it will try to detect a local IP")
+
         (self.options, self.args) = self.parser.parse_args()
         parseCasualCredit()
         parseOtherOptions()
         validateParameters()
-    
+
     def run(self):
         try:
             self.preRun()
@@ -580,7 +587,7 @@ for example:
             self.finalize()
         finally:
             self.postRun()
-        
+
         print ''
         print "CloudStack has successfully initialized database, you can check your database configuration in %s"%os.path.join(self.dbConfPath, 'db.properties')
         print ''
@@ -588,4 +595,4 @@ for example:
 if __name__ == "__main__":
    o = DBDeployer()
    o.run()
-        
+