def process_settings(app_instance, app_py_path, channel_layer): app_settings = get_app_settings(app_instance.package) # In the case the app isn't installed, has no settings, or it is an extension, # skip configuring services/settings if not app_settings: send_notification("No Services found to configure.", channel_layer) return unlinked_settings = app_settings['unlinked_settings'] services = [] for setting in unlinked_settings: if setting.__class__.__name__ == "CustomSetting": continue service_type = get_service_type_from_setting(setting) newSetting = { "name": setting.name, "required": setting.required, "description": setting.description, "service_type": service_type, "setting_type": get_setting_type_from_setting(setting), "options": get_service_options(service_type) } services.append(newSetting) get_data_json = { "data": services, "returnMethod": "configure_services", "jsHelperFunction": "processServices", "app_py_path": app_py_path, "current_app_name": app_instance.package } send_notification(get_data_json, channel_layer)
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 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)
def configure_services_from_file(services, app_name): from tethys_apps.models import CustomSetting if services['version']: del services['version'] for service_type in services: if services[service_type] is not None: current_services = services[service_type] for setting_name in current_services: if service_type == 'custom_setting': try: custom_setting = CustomSetting.objects.get( name=setting_name) except ObjectDoesNotExist: write_warning( f'Custom setting named "{setting_name}" could not be found in app "{app_name}". ' f'Skipping...') continue try: custom_setting.value = current_services[setting_name] custom_setting.clean() custom_setting.save() write_success( f'CustomSetting: "{setting_name}" was assigned the value: ' f'"{current_services[setting_name]}"') except ValidationError: write_error( "Incorrect value type given for custom setting '{}'. Please adjust " "services.yml or set the value in the app's settings page." .format(setting_name)) else: app_settings = get_app_settings(app_name) # In the case the app isn't installed, has no settings, or it is an extension, # skip configuring services/settings if not app_settings: write_msg( f'No settings found for app "{app_name}". Skipping automated configuration...' ) return unlinked_settings = app_settings['unlinked_settings'] setting_found = False for setting in unlinked_settings: if setting.name != setting_name: continue setting_found = True service_id = current_services[setting_name] if not service_id: write_warning( f'No service given for setting "{setting_name}". Skipping...' ) continue find_and_link(service_type, setting_name, service_id, app_name, setting) if not setting_found: write_warning( f'Service setting "{setting_name}" already configured or does not exist in app ' f'"{app_name}". Skipping...')
def run_interactive_services(app_name): write_msg( 'Running Interactive Service Mode. ' 'Any configuration options in services.yml or portal_config.yml will be ignored...' ) write_msg('Hit return at any time to skip a step.') app_settings = get_app_settings(app_name) # In the case the app isn't installed, has no settings, or it is an extension, # skip configuring services/settings if not app_settings: write_msg( f'No settings found for app "{app_name}". Skipping interactive configuration...' ) return unlinked_settings = app_settings['unlinked_settings'] for setting in unlinked_settings: valid = False configure_text = "Configuring {}".format(setting.name) star_out = '*' * len(configure_text) write_msg(f"\n{star_out}\n{configure_text}\n{star_out}") write_msg(f"Type: {setting.__class__.__name__}\n" f"Description: {setting.description}\n" f"Required: {setting.required}") if hasattr(setting, 'value'): while not valid: write_msg( '\nEnter the desired value for the current custom setting: {}' .format(setting.name)) try: value = get_interactive_input() if value != "": try: setting.value = value setting.clean() setting.save() valid = True write_success( "{} successfully set with value: {}.".format( setting.name, value)) except ValidationError: write_error( "Incorrect value type given for custom setting '{}'. Please try again" .format(setting.name)) else: write_msg("Skipping setup of {}".format(setting.name)) valid = True except (KeyboardInterrupt, SystemExit): write_msg('\nInstall Command cancelled.') exit(0) else: # List existing services args = Namespace() for conf in ['spatial', 'persistent', 'wps', 'dataset']: setattr(args, conf, False) setattr(args, get_setting_type(setting), True) services = services_list_command(args)[0] if len(services) <= 0: write_warning( 'No compatible services found. See:\n\n tethys services create {} -h\n' .format(get_setting_type(setting))) continue while not valid: write_msg( '\nEnter the service ID/Name to link to the current service setting: {}.' .format(setting.name)) try: service_id = get_interactive_input() if service_id != "": try: setting_type = get_setting_type_from_setting( setting) service_type = get_service_type_from_setting( setting) except RuntimeError as e: write_error(str(e) + ' Skipping...') break # Validate the given service id valid_service = validate_service_id( service_type, service_id) if valid_service: link_service_to_app_setting( service_type, service_id, app_name, setting_type, setting.name) valid = True else: write_error( 'Incorrect service ID/Name. Please try again.') else: write_msg("Skipping setup of {}".format(setting.name)) valid = True except (KeyboardInterrupt, SystemExit): write_msg('\nInstall Command cancelled.') exit(0)