1818 */
1919package com .cloud .upgrade ;
2020
21- import java .io .File ;
22- import java .io .FileNotFoundException ;
23- import java .io .FileReader ;
24- import java .io .IOException ;
21+ import java .io .*;
2522import java .sql .Connection ;
23+ import java .sql .DriverManager ;
2624import java .sql .SQLException ;
25+ import java .sql .Statement ;
2726import java .util .ArrayList ;
2827import java .util .List ;
28+ import java .util .Properties ;
2929
3030import com .cloud .utils .PropertiesUtil ;
3131
3636// Creates the CloudStack Database by using the 4.0 schema and apply
3737// upgrade steps to it.
3838public class DatabaseCreator {
39+
3940 protected static void printHelp (String cmd ) {
4041 System .out .println (
41- "DatabaseCreator creates the database schema by removing the \n " +
42+ "\n DatabaseCreator creates the database schema by removing the \n " +
4243 "previous schema, creating the schema, and running \n " +
4344 "through the database updaters." );
44- System .out .println ("Usage: " + cmd + " [db.properties files] [schema.sql files] [database upgrade class]" );
45+ System .out .println ("Usage: " + cmd + " [options] [db.properties file] [schema.sql files] [database upgrade class]\n Options:"
46+ + "\n --database=a,b comma separate databases to initialize, use the db name in db.properties defined as db.xyz.host, xyz should be passed"
47+ + "\n --rootpassword=password, by default it will try with an empty password"
48+ + "\n --dry or -d, this would not run any process, just does a dry run"
49+ + "\n --verbose or -v to print running sql commands, by default it won't print them"
50+ + "\n --help or -h for help" );
51+ }
52+
53+ private static boolean fileExists (String file ) {
54+ File f = new File (file );
55+ if (!f .exists ())
56+ System .out .println ("========> WARNING: Provided file does not exist: " + file );
57+ return f .exists ();
58+ }
59+
60+ private static void runScript (Connection conn , Reader reader , String filename , boolean verbosity ) {
61+ ScriptRunner runner = new ScriptRunner (conn , false , true , verbosity );
62+ try {
63+ runner .runScript (reader );
64+ } catch (IOException e ) {
65+ System .err .println ("Unable to read " + filename + ": " + e .getMessage ());
66+ System .exit (1 );
67+ } catch (SQLException e ) {
68+ System .err .println ("Unable to execute " + filename + ": " + e .getMessage ());
69+ System .exit (1 );
70+ }
71+ }
72+
73+ private static void runQuery (String host , String port , String rootPassword , String query , boolean dryRun ) {
74+ System .out .println ("============> Running query: " + query );
75+ Connection conn = null ;
76+ try {
77+ conn = DriverManager .getConnection (String .format ("jdbc:mysql://%s:%s/" , host , port ),
78+ "root" , rootPassword );
79+ Statement stmt = conn .createStatement ();
80+ if (!dryRun )
81+ stmt .executeUpdate (query );
82+ conn .close ();
83+ } catch (SQLException e ) {
84+ System .out .println ("SQL exception in trying initDB: " + e );
85+ System .exit (1 );
86+ }
87+ }
88+
89+ private static void initDB (String dbPropsFile , String rootPassword , String [] databases , boolean dryRun ) {
90+ Properties dbProperties = new Properties ();
91+ try {
92+ dbProperties .load (new FileInputStream (new File (dbPropsFile )));
93+ } catch (IOException e ) {
94+ System .out .println ("IOError: unable to load/read db properties file: " + e );
95+ System .exit (1 );
96+ }
97+
98+ for (String database : databases ) {
99+ String host = dbProperties .getProperty (String .format ("db.%s.host" , database ));
100+ String port = dbProperties .getProperty (String .format ("db.%s.port" , database ));
101+ String username = dbProperties .getProperty (String .format ("db.%s.username" , database ));
102+ String password = dbProperties .getProperty (String .format ("db.%s.password" , database ));
103+ String dbName = dbProperties .getProperty (String .format ("db.%s.name" , database ));
104+ System .out .println (String .format ("========> Initializing database=%s with host=%s port=%s username=%s password=%s" , dbName , host , port , username , password ));
105+
106+ List <String > queries = new ArrayList <String >();
107+ queries .add (String .format ("drop database if exists `%s`" , dbName ));
108+ queries .add (String .format ("create database `%s`" , dbName ));
109+ queries .add (String .format ("GRANT ALL ON %s.* to '%s'@`localhost` identified by '%s'" , dbName , username , password ));
110+ queries .add (String .format ("GRANT ALL ON %s.* to '%s'@`%%` identified by '%s'" , dbName , username , password ));
111+
112+ for (String query : queries ) {
113+ runQuery (host , port , rootPassword , query , dryRun );
114+ }
115+ }
45116 }
46117
47118 public static void main (String [] args ) {
48- List < String > dbPropFiles = new ArrayList < String >() ;
119+ String dbPropsFile = "" ;
49120 List <String > sqlFiles = new ArrayList <String >();
50121 List <String > upgradeClasses = new ArrayList <String >();
122+ String [] databases = new String [] {};
123+ String rootPassword = "" ;
124+ boolean verbosity = false ;
125+ boolean dryRun = false ;
51126
127+ // Process opts
52128 for (String arg : args ) {
53- if (arg .endsWith (".sql" )) {
129+ if (arg .equals ("--help" ) || arg .equals ("-h" )) {
130+ printHelp ("DatabaseCreator" );
131+ System .exit (0 );
132+ } else if (arg .equals ("--verbose" ) || arg .equals ("-v" )) {
133+ verbosity = true ;
134+ } else if (arg .equals ("--dry" ) || arg .equals ("-d" )) {
135+ dryRun = true ;
136+ } else if (arg .startsWith ("--rootpassword=" )) {
137+ rootPassword = arg .substring (arg .lastIndexOf ("=" ) + 1 , arg .length ());
138+ } else if (arg .startsWith ("--database=" )) {
139+ databases = arg .substring (arg .lastIndexOf ("=" ) + 1 , arg .length ()).split ("," );
140+ } else if (arg .endsWith (".sql" )) {
54141 sqlFiles .add (arg );
55- } else if (arg .endsWith (".properties" ) || arg .endsWith ("properties.override" )) {
56- dbPropFiles .add (arg );
142+ } else if (arg .endsWith (".properties" )) {
143+ if (!dbPropsFile .endsWith ("properties.override" ) && fileExists (arg ))
144+ dbPropsFile = arg ;
145+ } else if (arg .endsWith ("properties.override" )) {
146+ if (fileExists (arg ))
147+ dbPropsFile = arg ;
57148 } else {
58149 upgradeClasses .add (arg );
59150 }
60151 }
61152
62- if ((dbPropFiles . size () == 0 )
153+ if ((dbPropsFile . isEmpty () )
63154 || (sqlFiles .size () == 0 ) && upgradeClasses .size () == 0 ) {
64155 printHelp ("DatabaseCreator" );
65156 System .exit (1 );
66157 }
67158
68- // Process db.properties files
69- for (String dbPropFile : dbPropFiles ) {
70-
71- }
159+ Transaction .initDataSource (dbPropsFile );
160+ initDB (dbPropsFile , rootPassword , databases , dryRun );
72161
73162 // Process sql files
74163 for (String sqlFile : sqlFiles ) {
@@ -79,28 +168,18 @@ public static void main(String[] args) {
79168 System .exit (1 );
80169 }
81170
82- System .out .println ("=============> Processing SQL file at " + sqlScript .getAbsolutePath ());
83-
171+ System .out .println ("========> Processing SQL file at " + sqlScript .getAbsolutePath ());
84172 Connection conn = Transaction .getStandaloneConnection ();
85173 try {
86-
87- ScriptRunner runner = new ScriptRunner (conn , false , true );
88174 FileReader reader = null ;
89175 try {
90176 reader = new FileReader (sqlScript );
91177 } catch (FileNotFoundException e ) {
92178 System .err .println ("Unable to read " + sqlFile + ": " + e .getMessage ());
93179 System .exit (1 );
94180 }
95- try {
96- runner .runScript (reader );
97- } catch (IOException e ) {
98- System .err .println ("Unable to read " + sqlFile + ": " + e .getMessage ());
99- System .exit (1 );
100- } catch (SQLException e ) {
101- System .err .println ("Unable to execute " + sqlFile + ": " + e .getMessage ());
102- System .exit (1 );
103- }
181+ if (!dryRun )
182+ runScript (conn , reader , sqlFile , verbosity );
104183 } finally {
105184 try {
106185 conn .close ();
@@ -112,7 +191,7 @@ public static void main(String[] args) {
112191
113192 // Process db upgrade classes
114193 for (String upgradeClass : upgradeClasses ) {
115- System .out .println ("============= > Processing upgrade: " + upgradeClass );
194+ System .out .println ("========> Processing upgrade: " + upgradeClass );
116195 Class <?> clazz = null ;
117196 try {
118197 clazz = Class .forName (upgradeClass );
0 commit comments