Ejemplo n.º 1
0
def install_packages(conda_config, update_installed=False):
    # Compile channels arguments
    install_args = []
    if validate_schema('channels', conda_config):
        channels = conda_config['channels']
        for channel in channels:
            install_args.extend(['-c', channel])

    # Install all Packages
    if validate_schema('packages', conda_config):
        if not update_installed:
            install_args.extend(['--freeze-installed'])
        else:
            write_warning(
                'Warning: Updating previously installed packages. This could break your Tethys environment.'
            )
        install_args.extend(conda_config['packages'])
        write_msg("Running conda installation tasks...")
        [resp, err, code] = conda_run(Commands.INSTALL,
                                      *install_args,
                                      use_exception_handler=False,
                                      stdout=None,
                                      stderr=None)
        if code != 0:
            write_error(
                'Warning: Packages installation ran into an error. Please try again or a manual install'
            )
Ejemplo n.º 2
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())
Ejemplo n.º 3
0
def run_sync_stores(app_name, linked_settings):
    from tethys_apps.models import PersistentStoreConnectionSetting, PersistentStoreDatabaseSetting

    linked_persistent = False
    for setting in linked_settings:
        if isinstance(setting, PersistentStoreDatabaseSetting) or isinstance(
                setting, PersistentStoreConnectionSetting):
            linked_persistent = True

    if linked_persistent:
        write_msg('Running syncstores for app {}'.format(app_name))
        call(['tethys', 'syncstores', app_name])
Ejemplo n.º 4
0
def run_services(app_name, args):
    file_path = Path('./services.yml') if args.services_file is None else Path(
        args.services_file)

    if not file_path.exists():
        write_msg("No Services file found.")
        return

    services = open_file(file_path)

    if services and len(services) > 0:
        configure_services_from_file(services, app_name)
    else:
        write_msg("No Services listed in Services file.")
Ejemplo n.º 5
0
def run_portal_install(app_name):

    file_path = Path(get_tethys_home_dir()) / 'portal_config.yml'

    if not file_path.exists():
        write_msg(
            "No Portal Services file found. Searching for local app level services.yml..."
        )
        return False

    write_msg("Portal install file found...Processing...")
    portal_options = open_file(file_path)
    app_check = portal_options and 'apps' in portal_options and portal_options[
        'apps']
    if app_check and app_name in portal_options[
            'apps'] and 'services' in portal_options['apps'][app_name]:
        services = portal_options['apps'][app_name]['services']
        if services and len(services) > 0:
            configure_services_from_file(services, app_name)
        else:
            write_msg(
                "No app configuration found for app: {} in portal config file. "
                "Searching for local app level services.yml... ".format(
                    app_name))
            return False

    else:
        write_msg("No apps configuration found in portal config file. "
                  "Searching for local app level services.yml... ")
        return False

    return True
Ejemplo n.º 6
0
def run_portal_install(file_path, app_name):

    if file_path is None:
        file_path = './portal.yml'

    if not os.path.exists(file_path):
        write_msg(
            "No Portal Services file found. Moving to look for local app level services.yml..."
        )
        return False

    write_msg("Portal install file found...Processing...")
    portal_options = open_file(file_path)
    app_check = 'apps' in portal_options
    if app_check and app_name in portal_options[
            'apps'] and 'services' in portal_options['apps'][app_name]:
        services = portal_options['apps'][app_name]['services']
        if services and len(services) > 0:
            configure_services(services, app_name)
        else:
            write_msg(
                "No app configuration found for app: {} in portal config file. "
                "Moving to look for local app level services.yml... ".format(
                    app_name))
            return False

    else:
        write_msg("No apps configuration found in portal config file. "
                  "Moving to look for local app level services.yml... ")
        return False

    return True
Ejemplo n.º 7
0
def run_services(app_name, args):
    services_file = args.services_file

    if services_file is None:
        file_path = './services.yml'
    else:
        file_path = services_file

    if not os.path.exists(file_path):
        write_msg("No Services file found.")
        return

    services = open_file(file_path)

    if services and len(services) > 0:
        configure_services(services, app_name)
    else:
        write_msg("No Services listed in Services file.")
Ejemplo n.º 8
0
def install_packages(conda_config):
    # Compile channels arguments
    install_args = []
    if validate_schema('channels', conda_config):
        channels = conda_config['channels']
        for channel in channels:
            install_args.extend(['-c', channel])

    # Install all Packages
    if validate_schema('packages', conda_config):
        install_args.extend(conda_config['packages'])
        write_msg("Running conda installation tasks...")
        [resp, err, code] = conda_run(Commands.INSTALL,
                                      *install_args,
                                      use_exception_handler=False,
                                      stdout=None,
                                      stderr=None)
        if code != 0:
            write_error(
                'Warning: Packages installation ran into an error. Please try again or a manual install'
            )
Ejemplo n.º 9
0
def print_unconfigured_settings(app_name, unlinked_settings):
    if len(unlinked_settings) > 0:
        write_msg(
            f'\nThe following settings were not configured for app: {app_name}:\n'
        )
        write_msg('{0: <50}{1: <50}{2: <15}'.format('Name', 'Type',
                                                    'Required'))

        for unlinked_setting in unlinked_settings:
            write_msg('{0: <50}{1: <50}{2: <15}'.format(
                unlinked_setting.name, unlinked_setting.__class__.__name__,
                str(unlinked_setting.required)))
Ejemplo n.º 10
0
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)
Ejemplo n.º 11
0
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...')
Ejemplo n.º 12
0
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)