def schedulers_remove_command(args): load_apps() from tethys_compute.models import Scheduler scheduler = None name = args.scheduler_name force = args.force try: scheduler = Scheduler.objects.get(name=name) except ObjectDoesNotExist: with pretty_output(FG_RED) as p: p.write('Scheduler with name "{}" does not exist.\nCommand aborted.'.format(name)) exit(0) if force: scheduler.delete() with pretty_output(FG_GREEN) as p: p.write('Successfully removed Scheduler "{0}"!'.format(name)) exit(0) else: proceed = input('Are you sure you want to delete this Scheduler? [y/n]: ') while proceed not in ['y', 'n', 'Y', 'N']: proceed = input('Please enter either "y" or "n": ') if proceed in ['y', 'Y']: scheduler.delete() with pretty_output(FG_GREEN) as p: p.write('Successfully removed Scheduler "{0}"!'.format(name)) exit(0) else: with pretty_output(FG_RED) as p: p.write('Aborted. Scheduler not removed.') exit(1)
def condor_scheduler_create_command(args): load_apps() from tethys_compute.models.condor.condor_scheduler import CondorScheduler name = args.name host = args.endpoint username = args.username password = args.password private_key_path = args.private_key_path private_key_pass = args.private_key_pass existing_scheduler = CondorScheduler.objects.filter(name=name).first() if existing_scheduler: with pretty_output(FG_YELLOW) as p: p.write('A Condor Scheduler with name "{}" already exists. Command aborted.'.format(name)) exit(0) scheduler = CondorScheduler( name=name, host=host, username=username, password=password, private_key_path=private_key_path, private_key_pass=private_key_pass ) scheduler.save() with pretty_output(FG_GREEN) as p: p.write('Condor Scheduler created successfully!') exit(0)
def dask_scheduler_create_command(args): load_apps() from tethys_compute.models.dask.dask_scheduler import DaskScheduler name = args.name host = args.endpoint timeout = args.timeout heartbeat_interval = args.heartbeat_interval dashboard = args.dashboard existing_scheduler = DaskScheduler.objects.filter(name=name).first() if existing_scheduler: with pretty_output(FG_YELLOW) as p: p.write('A Dask Scheduler with name "{}" already exists. Command aborted.'.format(name)) exit(0) scheduler = DaskScheduler( name=name, host=host, timeout=timeout, heartbeat_interval=heartbeat_interval, dashboard=dashboard, ) scheduler.save() with pretty_output(FG_GREEN) as p: p.write('Dask Scheduler created successfully!') exit(0)
def gen_site_content(args): load_apps() from tethys_config.models import Setting, SettingsCategory if args.restore_defaults: from tethys_config.init import setting_defaults Setting.objects.all().delete() general_category = SettingsCategory.objects.get( name="General Settings") setting_defaults(general_category) home_category = SettingsCategory.objects.get(name="Home Page") setting_defaults(home_category) if args.from_file: portal_yaml = Path(get_tethys_home_dir()) / 'portal_config.yml' if portal_yaml.exists(): with portal_yaml.open() as f: site_content_settings = yaml.safe_load(f).get( 'site_content', {}) for arg in site_content_settings: if site_content_settings[arg]: content = site_content_settings[arg] obj = Setting.objects.filter( name=arg_filter[arg.lower()]) obj.update(content=content, date_modified=timezone.now()) else: valid_inputs = ('y', 'n', 'yes', 'no') no_inputs = ('n', 'no') generate_input = input( 'Would you like to generate a template portal_config.yml file that you can then' 'customize? (y/n): ') while generate_input not in valid_inputs: generate_input = input( 'Invalid option. Try again. (y/n): ').lower() if generate_input in no_inputs: write_msg( 'Generation of portal_config.yml file cancelled. Please generate one manually or provide ' 'specific site content arguments.') else: call(['tethys', 'gen', 'portal']) write_msg( '\nRe-run the tethys site command with the --from-file argument.' ) exit(0) for arg in vars(args): if vars(args)[arg] and arg in arg_filter: content = vars(args)[arg].replace('\\n', '\n') obj = Setting.objects.filter(name=arg_filter[arg]) obj.update(content=content, date_modified=timezone.now())
def app_settings_list_command(args): load_apps() app_settings = get_app_settings(args.app) if app_settings is None: return unlinked_settings = app_settings['unlinked_settings'] linked_settings = app_settings['linked_settings'] with pretty_output(BOLD) as p: p.write("\nUnlinked Settings:") if len(unlinked_settings) == 0: with pretty_output() as p: p.write('None') else: is_first_row = True for setting in unlinked_settings: if is_first_row: with pretty_output(BOLD) as p: p.write('{0: <10}{1: <40}{2: <15}'.format( 'ID', 'Name', 'Type')) is_first_row = False with pretty_output() as p: p.write('{0: <10}{1: <40}{2: <15}'.format( setting.pk, setting.name, get_setting_type(setting))) with pretty_output(BOLD) as p: p.write("\nLinked Settings:") if len(linked_settings) == 0: with pretty_output() as p: p.write('None') else: is_first_row = True for setting in linked_settings: if is_first_row: with pretty_output(BOLD) as p: p.write('{0: <10}{1: <40}{2: <15}{3: <20}'.format( 'ID', 'Name', 'Type', 'Linked With')) is_first_row = False if hasattr(setting, 'persistent_store_service'): service_name = setting.persistent_store_service.name elif hasattr(setting, 'spatial_dataset_service'): service_name = setting.spatial_dataset_service.name elif hasattr(setting, 'dataset_service'): service_name = setting.dataset_service.name elif hasattr(setting, 'web_processing_service'): service_name = setting.web_processing_service.name elif hasattr(setting, 'value'): service_name = setting.value with pretty_output() as p: p.write( f'{setting.pk: <10}{setting.name: <40}{get_setting_type(setting): <15}{service_name: <20}' )
def sync_tethys_apps_db(**kwargs): """Sync the Tethys database with the installed apps and extensions Args: **kwargs: processed key word arguments from commandline """ write_info( 'Syncing the Tethys database with installed apps and extensions...') load_apps() from tethys_apps.harvester import SingletonHarvester harvester = SingletonHarvester() harvester.harvest()
def app_settings_remove_command(args): load_apps() from tethys_apps.utilities import remove_ps_database_setting app_package = args.app setting_name = args.name force = args.force success = remove_ps_database_setting(app_package, setting_name, force) if not success: exit(1) exit(0)
def list_command(args): """ List installed apps. """ load_apps() installed_apps = get_installed_tethys_apps() installed_extensions = get_installed_tethys_extensions() if installed_apps: write_info('Apps:') for item in installed_apps: print(' {}'.format(item)) if installed_extensions: write_info('Extensions:') for item in installed_extensions: print(' {}'.format(item))
def app_settings_create_ps_database_command(args): load_apps() from tethys_apps.utilities import create_ps_database_setting app_package = args.app setting_name = args.name setting_description = args.description required = args.required initializer = args.initializer initialized = args.initialized spatial = args.spatial dynamic = args.dynamic success = create_ps_database_setting(app_package, setting_name, setting_description or '', required, initializer or '', initialized, spatial, dynamic) if not success: exit(1) exit(0)
def schedulers_list_command(args): load_apps() schedule_type = args.type.lower() if schedule_type == 'condor': from tethys_compute.models.condor.condor_scheduler import CondorScheduler schedulers = CondorScheduler.objects.all() num_schedulers = len(schedulers) if num_schedulers > 0: with pretty_output(BOLD) as p: p.write('{0: <30}{1: <25}{2: <10}{3: <10}{4: <50}{5: <10}'.format( 'Name', 'Host', 'Username', 'Password', 'Private Key Path', 'Private Key Pass' )) for scheduler in schedulers: p.write('{0: <30}{1: <25}{2: <10}{3: <10}{4: <50}{5: <10}'.format( scheduler.name, scheduler.host, scheduler.username, '******' if scheduler.password else 'None', scheduler.private_key_path, '******' if scheduler.private_key_pass else 'None' )) else: with pretty_output(BOLD) as p: p.write('There are no Condor Schedulers registered in Tethys.') elif schedule_type == 'dask': from tethys_compute.models.dask.dask_scheduler import DaskScheduler schedulers = DaskScheduler.objects.all() num_schedulers = len(schedulers) if num_schedulers > 0: with pretty_output(BOLD) as p: p.write('{0: <30}{1: <25}{2: <10}{3: <30}{4: <50}'.format( 'Name', 'Host', 'Timeout', 'Heartbeat Interval', 'Dashboard' )) for scheduler in schedulers: p.write('{0: <30}{1: <25}{2: <10}{3: <30}{4: <50}'.format( scheduler.name, scheduler.host, scheduler.timeout, scheduler.heartbeat_interval, scheduler.dashboard )) else: with pretty_output(BOLD) as p: p.write('There are no Dask Schedulers registered in Tethys.')
def create_portal_superuser(portal_superuser_name='admin', portal_superuser_email='', portal_superuser_password='******', **kwargs): """Create a superuser account for Tethys Portal Args: portal_superuser_name: username for the Tethys Portal superuser account portal_superuser_email: email for the Tethys Portal superuser account portal_superuser_password: password for the Tethys Portal superuser **kwargs: processed key word arguments from commandline """ write_info( f'Creating Tethys Portal superuser "{portal_superuser_name}"...') load_apps() from django.contrib.auth.models import User # noqa: E402 try: User.objects.create_superuser(portal_superuser_name, portal_superuser_email, portal_superuser_password) except IntegrityError: write_error( f'Tethys Portal Superuser "{portal_superuser_name}" already exists.' )
def test_load_apps(self, mock_django_setup): cli_helper.load_apps() mock_django_setup.assert_called()
def create_portal_superuser(portal_superuser_name='admin', portal_superuser_email='', portal_superuser_password='******', **kwargs): write_info(f'Creating Tethys Portal superuser "{portal_superuser_name}"...') load_apps() from django.contrib.auth.models import User # noqa: E402 User.objects.create_superuser(portal_superuser_name, portal_superuser_email, portal_superuser_password)
def sync_tethys_apps_db(**kwargs): write_info('Syncing the Tethys database with installed apps and extensions...') load_apps() from tethys_apps.harvester import SingletonHarvester harvester = SingletonHarvester() harvester.harvest()
def install_command(args): """ install Command """ app_name = None skip_config = False file_path = Path('./install.yml') if args.file is None else Path(args.file) # Check for install.yml file if not file_path.exists(): write_warning('WARNING: No install file found.') if not args.quiet: valid_inputs = ('y', 'n', 'yes', 'no') no_inputs = ('n', 'no') generate_input = input( 'Would you like to generate a template install.yml file in your current directory ' 'now? (y/n): ') while generate_input not in valid_inputs: generate_input = input( 'Invalid option. Try again. (y/n): ').lower() if generate_input in no_inputs: skip_config = True write_msg('Generation of Install File cancelled.') else: call(['tethys', 'gen', 'install']) write_msg( 'Install file generated. Fill out necessary information and re-install.' ) exit(0) write_warning('Continuing install without configuration.') # Install Dependencies if not skip_config: write_msg("Installing dependencies...") install_options = open_file(file_path) if "name" in install_options: app_name = install_options['name'] if validate_schema('requirements', install_options): requirements_config = install_options['requirements'] skip = False if "skip" in requirements_config: skip = requirements_config['skip'] if skip: write_warning( "Skipping package installation, Skip option found.") elif args.without_dependencies: write_warning("Skipping package installation.") else: if validate_schema('conda', requirements_config): # noqa: E501 conda_config = requirements_config['conda'] install_packages(conda_config, update_installed=args.update_installed) if validate_schema('pip', requirements_config): write_msg("Running pip installation tasks...") call(['pip', 'install', *requirements_config["pip"]]) # Skip the rest if we are installing dependencies only if args.only_dependencies: successful_exit(app_name, "installed dependencies for") # Run Setup.py write_msg("Running application install....") if args.verbose: call(['python', 'setup.py', 'clean', '--all'], stderr=STDOUT) if args.develop: call(['python', 'setup.py', 'develop'], stderr=STDOUT) else: call(['python', 'setup.py', 'install'], stderr=STDOUT) else: call(['python', 'setup.py', 'clean', '--all'], stdout=FNULL, stderr=STDOUT) if args.develop: call(['python', 'setup.py', 'develop'], stdout=FNULL, stderr=STDOUT) else: call(['python', 'setup.py', 'install'], stdout=FNULL, stderr=STDOUT) if args.no_db_sync: successful_exit(app_name) call(['tethys', 'db', 'sync']) # Run Portal Level Config if present if not skip_config: load_apps() if args.force_services: run_services(app_name, args) else: portal_result = run_portal_install(app_name) if not portal_result: run_services(app_name, args) if args.quiet: write_msg( "Quiet mode: No additional service setting validation will be performed." ) else: run_interactive_services(app_name) write_success("Services Configuration Completed.") app_settings = get_app_settings(app_name) if app_settings is not None: linked_settings = app_settings['linked_settings'] unlinked_settings = app_settings['unlinked_settings'] if args.no_sync_stores: write_msg('Skipping syncstores.') else: run_sync_stores(app_name, linked_settings) print_unconfigured_settings(app_name, unlinked_settings) # Check to see if any extra scripts need to be run if validate_schema('post', install_options): write_msg("Running post installation tasks...") for post in install_options["post"]: path_to_post = file_path.resolve().parent / post # Attempting to run processes. process = Popen(str(path_to_post), shell=True, stdout=PIPE) stdout = process.communicate()[0] write_msg("Post Script Result: {}".format(stdout)) successful_exit(app_name)