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' )
def check_if_app_installed(app_name): try: [resp, err, code] = conda_run( Commands.LIST, ["-f", "--json", app_name]) if code != 0: # In here maybe we just try re running the install logger.error( "ERROR: Couldn't get list of installed apps to verify if the conda install was successfull") else: conda_search_result = json.loads(resp) if len(conda_search_result) > 0: return conda_search_result[0]["version"] else: return False except RuntimeError as err: err_string = str(err) if "Path not found" in err_string and "tethysapp_warehouse" in err_string: # Old instance of warehouse files present. Need to cleanup err_path = err_string.split(": ")[1] if "EGG-INFO" in err_path: err_path = err_path.replace("EGG-INFO", '') if os.path.exists(err_path): shutil.rmtree(err_path) logger.info("Cleaning up: " + err_path) return check_if_app_installed(app_name)
def continueAfterInstall(installData, channel_layer): # Check if app is installed [resp, err, code] = conda_run(Commands.LIST, [installData['name'], "--json"]) # logger.info(resp, err, code) if code != 0: # In here maybe we just try re running the install logger.error( "ERROR: Couldn't get list of installed apps to verify if the conda install was successfull" ) else: conda_search_result = json.loads(resp) # Check if matching version found for package in conda_search_result: if package["version"] == installData['version']: send_notification("Resuming processing...", channel_layer) detect_app_dependencies(installData['name'], installData['version'], channel_layer) break else: send_notification( "Server error while processing this installation. Please check your logs", channel_layer) logger.error( "ERROR: ContinueAfterInstall: Correct version is not installed of this package." )
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' )
def validate_conda_environment(environment): condenv = environment.get("conda") if condenv is None: return None, None err0 = "Malformed environment.conda attribute" if not isinstance(condenv, dict): return False, err0 err = "" try: for dep in condenv.get("dependencies", []): ms = MatchSpec(dep) info = conda_run(Commands.LIST, ["-f", ms.name])[0] for l in info.split("\n"): l = l.strip() if l.startswith("#"): continue ll = l.split() if len(ll) < 2: continue if ll[0] != ms.name: continue if ms.version is None: break if ms.version.match(ll[1]): break else: msg = "Conda package '{}': {} installed, but {} required" err += msg.format(ms.name, ll[1], ms.version) + "\n" break else: err += "Conda package '{}' not installed\n".format(ms.name) except (KeyError, ValueError, AttributeError): return False, err0 if len(err): return None, err.rstrip("\n") else: return True, None
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)