if opt.new_data and opt.new_data[0] == '~': options['new_data'] = os.path.expanduser(opt.new_data) if opt.basedir and opt.basedir[0] == '~': options['basedir'] = os.path.expanduser(opt.basedir) if opt.new_data and opt.new_data[0] == '.': options['new_data'] = os.path.abspath(opt.new_data) if opt.basedir and opt.basedir[0] == '.': options['basedir'] = os.path.abspath(opt.basedir) # Parse source connection values if we have a running server if opt.basedir is None: try: conn = parse_connection(opt.server) except exception.FormatError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err) except exception.UtilError: _, err, _ = sys.exc_info() parser.error("Server connection values invalid: %s." % err.errmsg) else: conn = None try: res = serverclone.clone_server(conn, options) except exception.UtilError: _, e, _ = sys.exc_info() print("ERROR: %s" % e.errmsg) sys.exit(1) sys.exit()
'basedir': opt.basedir, 'delete': opt.delete, } # Expand user paths and resolve relative paths if opt.new_data and opt.new_data[0] == '~': options['new_data'] = os.path.expanduser(opt.new_data) if opt.basedir and opt.basedir[0] == '~': options['basedir'] = os.path.expanduser(opt.basedir) if opt.new_data and opt.new_data[0] == '.': options['new_data'] = os.path.abspath(opt.new_data) if opt.basedir and opt.basedir[0] == '.': options['basedir'] = os.path.abspath(opt.basedir) # Parse source connection values if we have a running server if opt.basedir is None: try: conn = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") else: conn = None try: res = serverclone.clone_server(conn, options) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1) exit()
def _spawn_server(options): """Spawn a server to use for reading .frm files This method spawns a new server instance on the port specified by the user in the options dictionary. options[in] Options from user Returns tuple - (Server instance, new datdir) or raises exception on error """ verbosity = int(options.get("verbosity", 0)) quiet = options.get("quiet", False) new_port = options.get("port", 3310) user = options.get("user", None) start_timeout = int(options.get("start_timeout", 10)) # 1) create a directory to use for new datadir # If the user is not the same as the user running the script... if user_change_as_root(options): # Since Python libraries correctly restrict temporary folders to # the user who runs the script and /tmp is protected on some # platforms, we must create the folder in the current folder temp_datadir = os.path.join(os.getcwd(), str(uuid.uuid4())) os.mkdir(temp_datadir) else: temp_datadir = tempfile.mkdtemp() if verbosity > 1 and not quiet: print "# Creating a temporary datadir =", temp_datadir # 2) spawn a server pointed to temp if not quiet: if user: print("# Spawning server with --user={0}.".format(user)) print "# Starting the spawned server on port %s ..." % new_port, sys.stdout.flush() bootstrap_options = { 'new_data': temp_datadir, 'new_port': new_port, 'new_id': 101, 'root_pass': "******", 'mysqld_options': None, 'verbosity': verbosity if verbosity > 1 else 0, 'basedir': options.get("basedir"), 'delete': True, 'quiet': True if verbosity <= 1 else False, 'user': user, 'start_timeout': start_timeout, } if verbosity > 1 and not quiet: print try: serverclone.clone_server(None, bootstrap_options) except UtilError as error: if error.errmsg.startswith("Unable to communicate"): err = ". Clone server error: {0}".format(error.errmsg) proc_id = int(error.errmsg.split("=")[1].strip('.')) print("ERROR Attempting to stop failed spawned server. " " Process id = {0}.".format(proc_id)) if os.name == "posix": try: os.kill(proc_id, subprocess.signal.SIGTERM) except OSError: pass else: try: subprocess.Popen("taskkill /F /T /PID %i" % proc_id, shell=True) except: pass raise UtilError(_SPAWN_SERVER_ERROR.format(err)) else: raise if verbosity > 1 and not quiet: print "# Connecting to spawned server" conn = { "user": "******", "passwd": "root", "host": "127.0.0.1", "port": options.get("port"), } server_options = { 'conn_info': conn, 'role': "frm_reader_bootstrap", } server = Server(server_options) try: server.connect() except UtilError: raise UtilError(_SPAWN_SERVER_ERROR.format("")) if not quiet: print "done." return (server, temp_datadir)
def _spawn_server(options): """Spawn a server to use for reading .frm files This method spawns a new server instance on the port specified by the user in the options dictionary. options[in] Options from user Returns tuple - (Server instance, new datdir) or raises exception on error """ verbosity = int(options.get("verbosity", 0)) quiet = options.get("quiet", False) new_port = options.get("port", 3310) user = options.get("user", None) start_timeout = int(options.get("start_timeout", 10)) # 1) create a directory to use for new datadir # If the user is not the same as the user running the script... if user_change_as_root(options): # Since Python libraries correctly restrict temporary folders to # the user who runs the script and /tmp is protected on some # platforms, we must create the folder in the current folder temp_datadir = os.path.join(os.getcwd(), str(uuid.uuid4())) os.mkdir(temp_datadir) else: temp_datadir = tempfile.mkdtemp() if verbosity > 1 and not quiet: print "# Creating a temporary datadir =", temp_datadir # 2) spawn a server pointed to temp if not quiet: if user: print("# Spawning server with --user={0}.".format(user)) print "# Starting the spawned server on port %s ..." % new_port, sys.stdout.flush() bootstrap_options = { 'new_data': temp_datadir, 'new_port': new_port, 'new_id': 101, 'root_pass': "******", 'mysqld_options': None, 'verbosity': verbosity if verbosity > 1 else 0, 'basedir': options.get("basedir"), 'delete': True, 'quiet': True if verbosity <= 1 else False, 'user': user, 'start_timeout': start_timeout, } if verbosity > 1 and not quiet: print try: serverclone.clone_server(None, bootstrap_options) except UtilError as error: if error.errmsg.startswith("Unable to communicate"): err = ". Clone server error: {0}".format(error.errmsg) proc_id = int(error.errmsg.split("=")[1].strip('.')) print( "ERROR Attempting to stop failed spawned server. " " Process id = {0}.".format(proc_id)) if os.name == "posix": try: os.kill(proc_id, subprocess.signal.SIGTERM) except OSError: pass else: try: subprocess.Popen("taskkill /F /T /PID %i" % proc_id, shell=True) except: pass raise UtilError(_SPAWN_SERVER_ERROR.format(err)) else: raise if verbosity > 1 and not quiet: print "# Connecting to spawned server" conn = { "user": "******", "passwd": "root", "host": "127.0.0.1", "port": options.get("port"), } server_options = { 'conn_info': conn, 'role': "frm_reader_bootstrap", } server = Server(server_options) try: server.connect() except UtilError: raise UtilError(_SPAWN_SERVER_ERROR.format("")) if not quiet: print "done." return (server, temp_datadir)
print "# Getting users..." user_list=[] if opt.users_to_copy is None: users = server1.exec_query("SELECT user, host " "FROM mysql.user " "WHERE user != 'root' and user != ''") for user in users: user_list.append(user[0]+'@'+user[1]) else: for user in opt.users_to_copy.split(","): user_list.append(user) # Clone the server print "# Cloning server instance..." try: res = serverclone.clone_server(conn, opt.new_data, opt.new_port, opt.new_id, "root", None, False, True) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1) # Set connection values dest_values = { "user" : conn.get("user"), "passwd" : "root", "host" : conn.get("host"), "port" : opt.new_port, "unix_socket" : os.path.join(opt.new_data, "mysql.sock") } # Build dictionary of options options = {
print "# Getting users..." user_list = [] if opt.users_to_copy is None: users = server1.exec_query("SELECT user, host " "FROM mysql.user " "WHERE user != 'root' and user != ''") for user in users: user_list.append(user[0] + '@' + user[1]) else: for user in opt.users_to_copy.split(","): user_list.append(user) # Clone the server print "# Cloning server instance..." try: res = serverclone.clone_server(conn, opt.new_data, opt.new_port, opt.new_id, "root", None, False, True) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1) # Set connection values dest_values = { "user": conn.get("user"), "passwd": "root", "host": conn.get("host"), "port": opt.new_port, "unix_socket": os.path.join(opt.new_data, "mysql.sock") } # Build dictionary of options options = {"quiet": True, "force": True}
# Optional additional command-line options parser.add_option("--mysqld", action="store", dest="mysqld", type="string", help="Additional options for mysqld") # Add verbosity and quiet mode add_verbosity(parser, True) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Fail if no database path specified. if opt.new_data is None: parser.error("No new database path. Use --help for available options.") # Warn if root-password is left off. if opt.rootpass is None or opt.rootpass == "": print "# WARNING: Root password for new instance has not been set." # Parse source connection values try: conn = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") try: res = serverclone.clone_server( conn, opt.new_data, opt.new_port, opt.new_id, opt.rootpass, opt.mysqld, opt.verbosity >= 1, opt.quiet ) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1)
type="string", help="Additional options for mysqld") # Add verbosity and quiet mode add_verbosity(parser, True) # Now we process the rest of the arguments. opt, args = parser.parse_args() # Fail if no database path specified. if opt.new_data is None: parser.error("No new database path. Use --help for available options.") # Warn if root-password is left off. if opt.rootpass is None or opt.rootpass == '': print "# WARNING: Root password for new instance has not been set." # Parse source connection values try: conn = parse_connection(opt.server) except: parser.error("Source connection values invalid or cannot be parsed.") try: res = serverclone.clone_server(conn, opt.new_data, opt.new_port, opt.new_id, opt.rootpass, opt.mysqld, opt.verbosity >= 1, opt.quiet) except exception.UtilError, e: print "ERROR:", e.errmsg exit(1)
def run(self): self.res_fname = "result.txt" srv0_con_str = self.build_connection_string(self.servers.get_server(0)) cmd_str = "mysqlserverclone.py --server={0} ".format(srv0_con_str) test_num = 1 port1 = int(self.servers.get_next_port()) newport = "--new-port={0} ".format(port1) comment = ("Test case {0} - error: no --new-data " "option".format(test_num)) res = self.run_test_case(2, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 comment = "Test case {0} - error: clone remote server".format(test_num) res = self.run_test_case( 2, "mysqlserverclone.py " "--server=root:root@notme:90125 " "--new-data=/nada --delete-data " "--new-id=7 {0} ".format(newport), comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 comment = "Test case {0} - error: no login".format(test_num) res = self.run_test_case( 1, "mysqlserverclone.py " "--server=root:root@localhost:90125 " "--new-data=/nada --delete-data " "--new-id=7 {0}".format(newport), comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 comment = "Test case {0} - error: cannot connect".format(test_num) res = self.run_test_case( 1, "mysqlserverclone.py --server=nope@" "localhost:38310 --new-data=/nada " "--new-id=7 --delete-data " "--root-password=nope {0}".format(newport), comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 cmd_str = "{0} --new-id={1} {2} {3} {4}".format( cmd_str, self.servers.get_next_id(), newport, "--root-password=root ", "--new-data=/not/there/yes") comment = "Test case {0} - cannot create directory".format(test_num) res = self.run_test_case(1, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 # Make the directory and put a file in it new_dir = os.path.join(os.getcwd(), "test123") shutil.rmtree(new_dir, True) os.mkdir(new_dir) f_out = open(os.path.join(new_dir, "temp123"), "w") f_out.write("test") f_out.close() cmd_str = ("mysqlserverclone.py --server=root:nope@nothere " "--new-data={0} --new-id=7 --root-password=nope " "{1}".format(new_dir, newport)) comment = "Test case {0} - error: --new-data exists".format(test_num) res = self.run_test_case(2, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 shutil.rmtree(new_dir, True) cmd_str = ("mysqlserverclone.py --server=root:nope@localhost " "--new-data={0} --new-id=7 --root-password=nope " "{1}".format(new_dir, newport)) comment = ("Test case {0} - --new-data does not exist (but cannot " "connect)".format(test_num)) res = self.run_test_case(1, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 cmd_str = ("mysqlserverclone.py --server={0} --new-port={1} " "--new-data={2} --root=root" "".format(srv0_con_str, self.servers.get_server(0).port, new_dir)) comment = ("Test case {0} - attempt to use existing " "port".format(test_num)) res = self.run_test_case(1, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 cmd_str = ("mysqlserverclone.py --server={0} --new-port={1} " "--new-data=lo{2}ng --root=root" "".format(srv0_con_str, port1, "o" * 200)) comment = ("Test case {0} - use invalid big path in --new-data" "".format(test_num)) res = self.run_test_case(1, cmd_str, comment) if not res: raise MUTLibError("{0}: failed".format(comment)) test_num += 1 comment = ("Test case {0} - No minimum required Free space for path " "in --new-data".format(test_num)) if self.debug: print("\n{0}".format(comment)) else: self.results.append("{0}\n".format(comment)) next_port = self.servers.get_next_port() self.test_path = "temp_{0}".format(next_port) options = { 'new_data': self.test_path, 'new_port': next_port, 'new_id': next_port, 'root_pass': "******", 'mysqld_options': None, 'verbosity': "", 'quiet': True, 'cmd_file': None, 'basedir': "", 'delete': False, 'start_timeout': 10, 'force': False, } temp_req_free_space = serverclone.REQ_FREE_SPACE min_mb = 120000000 serverclone.REQ_FREE_SPACE = min_mb conn = self.servers.get_server(0).get_connection_values() test_passed = False try: serverclone.clone_server(conn, options) except UtilError as err: err_msg = "mysqlserverclone needs at least {0} MB".format(min_mb) if err_msg in err.errmsg: if self.debug: print("Pass") else: self.results.append("Pass") test_passed = True if not test_passed: raise MUTLibError("{0}: failed".format(comment)) serverclone.REQ_FREE_SPACE = temp_req_free_space # Mask known platform-dependent lines self.mask_result("Error 2003:", "2003", "####") self.mask_result("Error 1045", "1045", "####:") self.replace_any_result([ "ERROR: Can't connect to MySQL server on ", "Error ####: Can't connect to MySQL server", "Error ####:(28000):", "Error Can't connect to MySQL server on", "ERROR: Access denied for user", "Error Access denied for user" ], "Error ####: Can't connect to MySQL server on 'nothere:####'\n") self.replace_result( "# Cloning the MySQL server running on ", "# Cloning the MySQL server running on " "XXXXX-XXXXX.\n") self.replace_result("# -uroot", "# -uroot [...]\n") self.replace_result( "ERROR: Unable to create directory", "ERROR: Unable to create directory " "'/not/there/yes'\n") self.replace_substring_portion("ERROR: Port ", "in use", "ERROR: Port ##### in use") self.replace_substring_portion( "ERROR: The --new-data path '", " is too long", "ERROR: The --new-data path 'XXXX' " "is too long") return True