def test_get_manage_path(self): # mock the input args with manage attribute args = mock.MagicMock(manage='') # call the method ret = cli_helper.get_manage_path(args=args) # check whether the response has manage self.assertIn('manage.py', ret)
def manage_command(args): """ Management commands. """ # Get the path to manage.py manage_path = get_manage_path(args) # Define the process to be run primary_process = None if args.command == MANAGE_START: if args.port: primary_process = ['python', manage_path, 'runserver', args.port] else: primary_process = ['python', manage_path, 'runserver'] elif args.command == MANAGE_COLLECTSTATIC: # Run pre_collectstatic intermediate_process = ['python', manage_path, 'pre_collectstatic'] run_process(intermediate_process) # Setup for main collectstatic primary_process = ['python', manage_path, 'collectstatic'] if args.noinput: primary_process.append('--noinput') elif args.command == MANAGE_COLLECTWORKSPACES: # Run collectworkspaces command if args.force: primary_process = ['python', manage_path, 'collectworkspaces', '--force'] else: primary_process = ['python', manage_path, 'collectworkspaces'] elif args.command == MANAGE_COLLECT: # Convenience command to run collectstatic and collectworkspaces # Run pre_collectstatic intermediate_process = ['python', manage_path, 'pre_collectstatic'] run_process(intermediate_process) # Setup for main collectstatic intermediate_process = ['python', manage_path, 'collectstatic'] if args.noinput: intermediate_process.append('--noinput') run_process(intermediate_process) # Run collectworkspaces command primary_process = ['python', manage_path, 'collectworkspaces'] elif args.command == MANAGE_CREATESUPERUSER: primary_process = ['python', manage_path, 'createsuperuser'] if primary_process: run_process(primary_process)
def migrate_tethys_db(db_alias=None, **kwargs): """Run migrations for the Tethys Portal database Args: db_alias: name of the database as specified in the `settings.py` file. **kwargs: processed key word arguments from commandline Returns: error code """ msg = 'Running migrations for Tethys database...' manage_path = get_manage_path(None) db_alias = db_alias or 'default' args = ['python', manage_path, 'migrate', '--database', db_alias] return _run_process(args, msg, **kwargs)
def uninstall_command(args): """ Uninstall an app command. """ # Get the path to manage.py manage_path = get_manage_path(args) item_name = args.app_or_extension process = ['python', manage_path, 'tethys_app_uninstall', item_name] if args.is_extension: process.append('-e') if args.is_forced: process.append('-f') try: subprocess.call(process) except KeyboardInterrupt: pass
def syncstores_command(args): """ Sync persistent stores. """ # Get the path to manage.py manage_path = get_manage_path(args) # This command is a wrapper for a custom Django manage.py method called syncstores. # See tethys_apps.mangement.commands.syncstores process = ['python', manage_path, 'syncstores'] if args.refresh: valid_inputs = ('y', 'n', 'yes', 'no') no_inputs = ('n', 'no') proceed = input( '{1}WARNING:{2} You have specified the database refresh option. This will drop all of the ' 'databases for the following apps: {0}. This could result in significant data loss and ' 'cannot be undone. Do you wish to continue? (y/n): '.format( ', '.join(args.app), TC_WARNING, TC_ENDC)).lower() while proceed not in valid_inputs: proceed = input( 'Invalid option. Do you wish to continue? (y/n): ').lower() if proceed not in no_inputs: process.extend(['-r']) else: print('Operation cancelled by user.') exit(0) if args.firsttime: process.extend(['-f']) if args.database: process.extend(['-d', args.database]) if args.app: process.extend(args.app) try: subprocess.call(process) except KeyboardInterrupt: pass
def uninstall_app(data, channel_layer): manage_path = get_manage_path({}) app_name = data['name'] send_uninstall_messages('Starting Uninstall. Please wait...', channel_layer) try: # Check if application had provisioned any Persistent stores and clear them out from tethys_apps.models import TethysApp target_app = TethysApp.objects.filter(package=app_name)[0] ps_db_settings = target_app.persistent_store_database_settings if len(ps_db_settings): for setting in ps_db_settings: # If there is a db for this PS, drop it try: if setting.persistent_store_database_exists(): logger.info( "Droping Database for persistent store setting: " + str(setting)) setting.drop_persistent_store_database() except TethysAppSettingNotAssigned: pass else: logger.info("No Persistent store services found for: " + app_name) except IndexError: # Couldn't find the target application logger.info( "Couldn't find the target application for removal of databases. Continuing clean up" ) except Exception as e: # Something wrong with the persistent store setting # Could not connect to the database logger.info(e) logger.info( "Couldn't connect to database for removal. Continuing clean up") process = ['python', manage_path, 'tethys_app_uninstall', app_name] process.append('-f') try: subprocess.call(process) except KeyboardInterrupt: pass send_uninstall_messages( 'Tethys App Uninstalled. Running Conda/GitHub Cleanup...', channel_layer) try: [resp, err, code] = conda_run(Commands.REMOVE, [ "--force", "-c", "tethysplatform", "--override-channels", data['name'] ]) logger.info(resp) if err: logger.error(err) except PackagesNotFoundError: # This was installed using GitHub. Try to clean out github_installed = get_github_install_metadata() for app in github_installed: if app['name'] == data['name']: # remove App Directory shutil.rmtree(app['path']) clear_github_cache_list() send_uninstall_messages('Uninstall completed. Restarting server...', channel_layer)
def migrate_tethys_db(db_alias=None, **kwargs): msg = 'Running migrations for Tethys database...' manage_path = get_manage_path(None) db_alias = db_alias or 'default' args = ['python', manage_path, 'migrate', '--database', db_alias] _run_process(args, msg)
def restart_server(data, channel_layer, run_collect_all=True): # Check if Install Running file is present and delete it app_workspace = app.get_app_workspace() workspace_directory = app_workspace.path install_running_path = os.path.join(workspace_directory, 'install_status', 'installRunning') if os.path.exists(install_running_path): os.remove(install_running_path) manage_path = get_manage_path({}) if data["restart_type"] == "install" or data["restart_type"] == "update": # Run SyncStores logger.info("Running Syncstores for app: " + data["name"]) intermediate_process = [ 'python', manage_path, 'syncstores', data["name"], '-f' ] run_process(intermediate_process) if 'runserver' in sys.argv: logger.info("Dev Mode. Attempting to restart by changing file") dir_path = os.path.dirname(os.path.realpath(__file__)) file_path = os.path.join(dir_path, 'model.py') with open(file_path, "w") as f: f.write("import os") else: if run_collect_all and (data["restart_type"] == "install" or data["restart_type"] == "gInstall" or data["restart_type"] == "update"): logger.info("Running Tethys Collectall") intermediate_process = ['python', manage_path, 'pre_collectstatic'] run_process(intermediate_process) # Setup for main collectstatic intermediate_process = [ 'python', manage_path, 'collectstatic', '--noinput' ] run_process(intermediate_process) # Run collectworkspaces command intermediate_process = [ 'python', manage_path, 'collectworkspaces', '--force' ] run_process(intermediate_process) try: command = 'supervisorctl restart all' subprocess.run(['sudo'], check=True) sudoPassword = app.get_custom_setting('sudo_server_pass') p = os.system('echo %s|sudo -S %s' % (sudoPassword, command)) except Exception as e: logger.error(e) logger.info( "No SUDO. Docker container implied. Restarting without SUDO") # Error encountered while running sudo. Let's try without sudo # Check if the restart dir exists. If yes then use that dir instead of RESTART_FILE_PATH = "/var/lib/tethys_persist/restart" if os.path.isdir(RESTART_FILE_PATH): logger.info("Restart Directory found. Creating restart file.") Path(os.path.join(RESTART_FILE_PATH, 'restart')).touch() else: p = os.system(command)