From 7a10f990b8ef923d9a558a1b434c4cc71f03aec3 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 5 Oct 2023 10:30:57 -0600 Subject: [PATCH 01/12] Add simple prototype of functionality to push to spack caches --- lib/ramble/ramble/application.py | 11 ++++--- lib/ramble/ramble/application_types/spack.py | 15 +++++++++ lib/ramble/ramble/cmd/workspace.py | 32 +++++++++++++++++++ .../ramble/language/modifier_language.py | 15 +++++++++ lib/ramble/ramble/modifier.py | 3 ++ lib/ramble/ramble/pipeline.py | 24 ++++++++++++-- lib/ramble/ramble/spack_runner.py | 30 +++++++++++++++++ 7 files changed, 123 insertions(+), 7 deletions(-) diff --git a/lib/ramble/ramble/application.py b/lib/ramble/ramble/application.py index 0c0dba4e0..84231c3ef 100644 --- a/lib/ramble/ramble/application.py +++ b/lib/ramble/ramble/application.py @@ -58,7 +58,7 @@ class ApplicationBase(object, metaclass=ApplicationMeta): _workload_exec_key = 'executables' _inventory_file_name = 'ramble_inventory.json' _status_file_name = 'ramble_status.json' - _pipelines = ['analyze', 'archive', 'mirror', 'setup'] + _pipelines = ['analyze', 'archive', 'mirror', 'setup', 'pushtocache'] # TODO: why do we repeat this in so many places #: Lists of strings which contains GitHub usernames of attributes. #: Do not include @ here in order not to unnecessarily ping the users. @@ -1490,10 +1490,11 @@ def env_vars(self): license_conf = ramble.config.config.get_config('licenses', scope=scope) if license_conf: - app_licenses = license_conf[self.name] - if app_licenses: - # Append logic to source file which contains the exports - command.append(f". {{license_input_dir}}/{self.license_inc_name}") + if self.name in license_conf: + app_licenses = license_conf[self.name] + if app_licenses: + # Append logic to source file which contains the exports + command.append(f". {{license_input_dir}}/{self.license_inc_name}") # Process environment variable actions for env_var_set in self._env_variable_sets: diff --git a/lib/ramble/ramble/application_types/spack.py b/lib/ramble/ramble/application_types/spack.py index d57c217b2..1efcb74d9 100644 --- a/lib/ramble/ramble/application_types/spack.py +++ b/lib/ramble/ramble/application_types/spack.py @@ -365,6 +365,21 @@ def _mirror_software(self, workspace): with self.logger.force_echo(): tty.die(e) + register_phase('push_to_spack_cache', pipeline='pushtocache', depends_on=[]) + + def _push_to_spack_cache(self, workspace): + try: + # TODO: make sure this is called as infrequently as possible + # TODO: this is a lot of repeated stuff, can we DRY with out pipelines? + self.spack_runner.set_dry_run(workspace.dry_run) + env_path = self.expander.env_path + self.spack_runner.set_env(env_path) + self.spack_runner.activate() + self.spack_runner.push_to_spack_cache(workspace.spack_cache_path) + except ramble.spack_runner.RunnerError as e: + with self.logger.force_echo(): + tty.die(e) + def populate_inventory(self, workspace, force_compute=False, require_exist=False): """Add software environment information to hash inventory""" diff --git a/lib/ramble/ramble/cmd/workspace.py b/lib/ramble/ramble/cmd/workspace.py index e454c278d..7aa018d18 100644 --- a/lib/ramble/ramble/cmd/workspace.py +++ b/lib/ramble/ramble/cmd/workspace.py @@ -51,6 +51,7 @@ 'concretize', 'setup', 'analyze', + 'pushtocache', 'info', 'edit', 'mirror', @@ -404,6 +405,37 @@ def workspace_analyze(args): workspace_run_pipeline(args, pipeline) +def workspace_pushtocache(args): + current_pipeline = ramble.pipeline.pipelines.pushtocache + ws = ramble.cmd.require_active_workspace(cmd_name='workspace pushtocache') + + # TODO: this is repeated for pipelines, can we DRY it? + filters = ramble.filters.Filters( + phase_filters=args.phases, + include_where_filters=args.where, + exclude_where_filters=args.exclude_where + ) + pipeline_cls = ramble.pipeline.pipeline_class(current_pipeline) + + pipeline = pipeline_cls(ws, filters, spack_cache_path=args.cache_path) + + workspace_run_pipeline(args, pipeline) + pipeline.run() + + +def workspace_pushtocache_setup_parser(subparser): + """push workspace envs to a given spack buildcache""" + + subparser.add_argument( + '-d', dest='cache_path', + default=None, + required=True, + help='Path to spack cache.') + + arguments.add_common_arguments(subparser, ['phases', 'include_phase_dependencies', + 'where', 'exclude_where']) + + def workspace_info_setup_parser(subparser): """Information about a workspace""" subparser.add_argument('-v', '--verbose', action='count', default=0, diff --git a/lib/ramble/ramble/language/modifier_language.py b/lib/ramble/ramble/language/modifier_language.py index 9ccd05735..87faeecd6 100644 --- a/lib/ramble/ramble/language/modifier_language.py +++ b/lib/ramble/ramble/language/modifier_language.py @@ -35,6 +35,21 @@ def _execute_mode(mod): return _execute_mode +@modifier_directive('default_modes') +def default_mode(name, **kwargs): + """Define a default mode for this modifier. + + The default mode will be used if modifier mode is not specified in an experiment.""" + + def _execute_default_mode(mod): + if name not in mod.modes: + raise DirectiveError(f'default_mode directive given an invalid mode for modifier ' + f'{mod.name}. Valid modes are {str(list(mod.modes.keys()))}') + mod.default_mode = name + + return _execute_default_mode + + @modifier_directive('variable_modifications') def variable_modification(name, modification, method='set', mode=None, modes=None, **kwargs): """Define a new variable modification for a mode in this modifier. diff --git a/lib/ramble/ramble/modifier.py b/lib/ramble/ramble/modifier.py index 1d84a11ad..ee5e36130 100644 --- a/lib/ramble/ramble/modifier.py +++ b/lib/ramble/ramble/modifier.py @@ -66,6 +66,9 @@ def set_usage_mode(self, mode): """ if mode: self._usage_mode = mode + elif hasattr(self, 'default_mode'): + self._usage_mode = self.default_mode + tty.msg(f' Using default usage mode {self._usage_mode} on modifier {self.name}') else: if len(self.modes) > 1 or len(self.modes) == 0: raise InvalidModeError('Cannot auto determine usage ' diff --git a/lib/ramble/ramble/pipeline.py b/lib/ramble/ramble/pipeline.py index 078a1c01b..e2f7c6809 100644 --- a/lib/ramble/ramble/pipeline.py +++ b/lib/ramble/ramble/pipeline.py @@ -319,13 +319,33 @@ def _complete(self): | stat.S_IROTH | stat.S_IXOTH) -pipelines = Enum('pipelines', ['analyze', 'archive', 'mirror', 'setup']) +class PushToCachePipeline(Pipeline): + """Class for the pushtocache pipeline""" + + name = 'pushtocache' + + def __init__(self, workspace, filters, spack_cache_path=None): + super().__init__(workspace, filters) + self.action_string = 'Pushing to Spack Cache' + self.spack_cache_path = spack_cache_path + + def _prepare(self): + super()._prepare() + self.workspace.spack_cache_path = self.spack_cache_path + + def _complete(self): + tty.msg('Pushed envs to spack cache %s' % self.spack_cache_path) + + +# TODO: should this use the classes `.name`? +pipelines = Enum('pipelines', ['analyze', 'archive', 'mirror', 'setup', 'pushtocache']) _pipeline_map = { pipelines.analyze: AnalyzePipeline, pipelines.archive: ArchivePipeline, pipelines.mirror: MirrorPipeline, - pipelines.setup: SetupPipeline + pipelines.setup: SetupPipeline, + pipelines.pushtocache: PushToCachePipeline } diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index 7cc1cfe3d..a571d47fa 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -676,6 +676,36 @@ def mirror_environment(self, mirror_path): %-4d added %-4d failed to fetch.""" % (0, 0, 0) + def get_env_hash_list(self): + self._check_active() + args = [ + 'find', + '--format', + '/{hash}' + ] + output = self.spack(*args, output=str).strip() + return output + + def push_to_spack_cache(self, spack_cache_path): + """Push packages for a given env to the spack cache""" + self._check_active() + + hash_list = self.get_env_hash_list() + + args = [ + "buildcache", + "push", + "-a", # TODO: remove this, it's just here for testing + spack_cache_path, + hash_list + ] + + if not self.dry_run: + return self.spack(*args, output=str).strip() + else: + self._dry_run_print(self.spack, args) + return + def _dry_run_print(self, executable, args): tty.msg('DRY-RUN: would run %s' % executable) tty.msg(' with args: %s' % args) From 361a9f14bdf060e459347365ef8cd960257de22b Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 10 Oct 2023 08:56:53 -0600 Subject: [PATCH 02/12] Add caching to cache push --- lib/ramble/ramble/application_types/spack.py | 5 ++++- lib/ramble/ramble/spack_runner.py | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/ramble/ramble/application_types/spack.py b/lib/ramble/ramble/application_types/spack.py index 1efcb74d9..f4d7c2cb2 100644 --- a/lib/ramble/ramble/application_types/spack.py +++ b/lib/ramble/ramble/application_types/spack.py @@ -369,13 +369,16 @@ def _mirror_software(self, workspace): def _push_to_spack_cache(self, workspace): try: - # TODO: make sure this is called as infrequently as possible # TODO: this is a lot of repeated stuff, can we DRY with out pipelines? self.spack_runner.set_dry_run(workspace.dry_run) + env_path = self.expander.env_path self.spack_runner.set_env(env_path) self.spack_runner.activate() + self.spack_runner.push_to_spack_cache(workspace.spack_cache_path) + + self.spack_runner.deactivate() except ramble.spack_runner.RunnerError as e: with self.logger.force_echo(): tty.die(e) diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index a571d47fa..5617d75f3 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -690,6 +690,10 @@ def push_to_spack_cache(self, spack_cache_path): """Push packages for a given env to the spack cache""" self._check_active() + if self.pushed_to_cache: + tty.msg(f'Environment {self.env_path} already pushed. Skipping...') + return + hash_list = self.get_env_hash_list() args = [ @@ -706,6 +710,8 @@ def push_to_spack_cache(self, spack_cache_path): self._dry_run_print(self.spack, args) return + self.pushed_to_cache = True + def _dry_run_print(self, executable, args): tty.msg('DRY-RUN: would run %s' % executable) tty.msg(' with args: %s' % args) From 952659d02ab08f01551462ad9abd184439d5cd6e Mon Sep 17 00:00:00 2001 From: Bob Date: Tue, 10 Oct 2023 11:34:58 -0600 Subject: [PATCH 03/12] address reviewer comments --- lib/ramble/ramble/application.py | 2 +- lib/ramble/ramble/pipeline.py | 1 - lib/ramble/ramble/spack_runner.py | 9 ++++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ramble/ramble/application.py b/lib/ramble/ramble/application.py index 84231c3ef..a98ce24ea 100644 --- a/lib/ramble/ramble/application.py +++ b/lib/ramble/ramble/application.py @@ -58,7 +58,7 @@ class ApplicationBase(object, metaclass=ApplicationMeta): _workload_exec_key = 'executables' _inventory_file_name = 'ramble_inventory.json' _status_file_name = 'ramble_status.json' - _pipelines = ['analyze', 'archive', 'mirror', 'setup', 'pushtocache'] # TODO: why do we repeat this in so many places + _pipelines = ['analyze', 'archive', 'mirror', 'setup', 'pushtocache'] #: Lists of strings which contains GitHub usernames of attributes. #: Do not include @ here in order not to unnecessarily ping the users. diff --git a/lib/ramble/ramble/pipeline.py b/lib/ramble/ramble/pipeline.py index e2f7c6809..900ab8169 100644 --- a/lib/ramble/ramble/pipeline.py +++ b/lib/ramble/ramble/pipeline.py @@ -337,7 +337,6 @@ def _complete(self): tty.msg('Pushed envs to spack cache %s' % self.spack_cache_path) -# TODO: should this use the classes `.name`? pipelines = Enum('pipelines', ['analyze', 'archive', 'mirror', 'setup', 'pushtocache']) _pipeline_map = { diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index 5617d75f3..3d4caaf41 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -49,6 +49,7 @@ class SpackRunner(object): global_config_name = 'config:spack:global' install_config_name = 'config:spack:install' + pushtocache_config_name = 'config:spack:pushtocache' concretize_config_name = 'config:spack:concretize' env_create_args = [ @@ -699,11 +700,17 @@ def push_to_spack_cache(self, spack_cache_path): args = [ "buildcache", "push", - "-a", # TODO: remove this, it's just here for testing spack_cache_path, hash_list ] + user_flags = ramble.config.get(f'{self.pushtocache_config_name}:flags') + + args = [] + + if user_flags is not None: + args.extend(shlex.split(user_flags)) + if not self.dry_run: return self.spack(*args, output=str).strip() else: From b32ed8a6923faa4fbdccea0ba887f893ea38c96f Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 11 Oct 2023 15:28:35 -0600 Subject: [PATCH 04/12] update command to allow args --- lib/ramble/ramble/cmd/workspace.py | 9 ++++----- lib/ramble/ramble/schema/config.py | 18 ++++++++++++++++++ lib/ramble/ramble/spack_runner.py | 19 ++++++++++--------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/lib/ramble/ramble/cmd/workspace.py b/lib/ramble/ramble/cmd/workspace.py index 7aa018d18..78041d66a 100644 --- a/lib/ramble/ramble/cmd/workspace.py +++ b/lib/ramble/ramble/cmd/workspace.py @@ -312,7 +312,8 @@ def workspace_concretize(args): def workspace_run_pipeline(args, pipeline): - if args.include_phase_dependencies: + include_phase_dependencies = getattr(args, 'include_phase_dependencies', None) + if include_phase_dependencies: with ramble.config.override('config:include_phase_dependencies', True): pipeline.run() else: @@ -409,9 +410,8 @@ def workspace_pushtocache(args): current_pipeline = ramble.pipeline.pipelines.pushtocache ws = ramble.cmd.require_active_workspace(cmd_name='workspace pushtocache') - # TODO: this is repeated for pipelines, can we DRY it? filters = ramble.filters.Filters( - phase_filters=args.phases, + phase_filters='*', include_where_filters=args.where, exclude_where_filters=args.exclude_where ) @@ -432,8 +432,7 @@ def workspace_pushtocache_setup_parser(subparser): required=True, help='Path to spack cache.') - arguments.add_common_arguments(subparser, ['phases', 'include_phase_dependencies', - 'where', 'exclude_where']) + arguments.add_common_arguments(subparser, ['where', 'exclude_where']) def workspace_info_setup_parser(subparser): diff --git a/lib/ramble/ramble/schema/config.py b/lib/ramble/ramble/schema/config.py index 1d1139f66..c0eb0661f 100644 --- a/lib/ramble/ramble/schema/config.py +++ b/lib/ramble/ramble/schema/config.py @@ -86,6 +86,24 @@ }, 'additionalProperties': False }, + 'buildcache': { + 'type': 'object', + 'default': { + 'flags': '', + 'prefix': '', + }, + 'properties': { + 'flags': { + 'type': 'string', + 'default': '', + }, + 'prefix': { + 'type': 'string', + 'default': '' + } + }, + 'additionalProperties': False + }, }, 'additionalProperties': False, } diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index 3d4caaf41..021e6ad69 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -49,7 +49,7 @@ class SpackRunner(object): global_config_name = 'config:spack:global' install_config_name = 'config:spack:install' - pushtocache_config_name = 'config:spack:pushtocache' + buildcache_config_name = 'config:spack:buildcache' concretize_config_name = 'config:spack:concretize' env_create_args = [ @@ -98,6 +98,7 @@ def __init__(self, shell='bash', dry_run=False): self.concretized = False self.installed = False + self.pushed_to_cache = False self.hash = None self.env_path = None self.active = False @@ -684,7 +685,7 @@ def get_env_hash_list(self): '--format', '/{hash}' ] - output = self.spack(*args, output=str).strip() + output = self.spack(*args, output=str).strip().replace('\n', ' ') return output def push_to_spack_cache(self, spack_cache_path): @@ -699,25 +700,25 @@ def push_to_spack_cache(self, spack_cache_path): args = [ "buildcache", - "push", - spack_cache_path, - hash_list + "push" ] + user_flags = ramble.config.get(f'{self.buildcache_config_name}:flags') - user_flags = ramble.config.get(f'{self.pushtocache_config_name}:flags') - - args = [] + tty.debug("Running with user flags: {}".format(user_flags)) if user_flags is not None: args.extend(shlex.split(user_flags)) + args.extend( [ spack_cache_path, hash_list ] ) + + self.pushed_to_cache = True + if not self.dry_run: return self.spack(*args, output=str).strip() else: self._dry_run_print(self.spack, args) return - self.pushed_to_cache = True def _dry_run_print(self, executable, args): tty.msg('DRY-RUN: would run %s' % executable) From c6d610d0a67b5056b627640d40baa2f4377e92b1 Mon Sep 17 00:00:00 2001 From: Bob Date: Wed, 11 Oct 2023 15:47:10 -0600 Subject: [PATCH 05/12] remove impossible cachcing --- lib/ramble/ramble/spack_runner.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index 021e6ad69..fc5cfcbf9 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -97,15 +97,12 @@ def __init__(self, shell='bash', dry_run=False): 'share', 'spack', script) self.concretized = False - self.installed = False - self.pushed_to_cache = False self.hash = None self.env_path = None self.active = False self.compilers = [] self.includes = [] self.dry_run = dry_run - self.concretized = False self.compiler_config_dir = None self.configs = [] self.configs_applied = False @@ -618,10 +615,6 @@ def install(self): """ self._check_active() - if self.installed: - tty.msg(f'Environment {self.env_path} is already installed. Skipping installation...') - return - install_flags = ramble.config.get(f'{self.install_config_name}:flags') args = [] @@ -634,8 +627,6 @@ def install(self): else: self._dry_run_print(self.installer, args) - self.installed = True - def get_package_path(self, package_spec): """Return the installation directory for a package""" loc_args = ['location', '-i'] @@ -692,10 +683,6 @@ def push_to_spack_cache(self, spack_cache_path): """Push packages for a given env to the spack cache""" self._check_active() - if self.pushed_to_cache: - tty.msg(f'Environment {self.env_path} already pushed. Skipping...') - return - hash_list = self.get_env_hash_list() args = [ @@ -711,8 +698,6 @@ def push_to_spack_cache(self, spack_cache_path): args.extend( [ spack_cache_path, hash_list ] ) - self.pushed_to_cache = True - if not self.dry_run: return self.spack(*args, output=str).strip() else: From 083e968656bd87908e42b1b76872a937c45c2fb0 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 11:30:18 -0600 Subject: [PATCH 06/12] Remap hypen based args to underscore named functions --- lib/ramble/ramble/cmd/workspace.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/ramble/ramble/cmd/workspace.py b/lib/ramble/ramble/cmd/workspace.py index 78041d66a..4e6b16027 100644 --- a/lib/ramble/ramble/cmd/workspace.py +++ b/lib/ramble/ramble/cmd/workspace.py @@ -685,6 +685,12 @@ def workspace_mirror(args): subcommand_functions = {} +def sanitize_arg_name(base_name): + """Allow function names to be remaped (eg `-` to `_`) """ + formatted_name = base_name.replace('-', '_') + return formatted_name + + def setup_parser(subparser): sp = subparser.add_subparsers(metavar='SUBCOMMAND', dest='workspace_command') @@ -696,13 +702,14 @@ def setup_parser(subparser): aliases = [] # add commands to subcommands dict - function_name = 'workspace_%s' % name + function_name = sanitize_arg_name('workspace_%s' % name) + function = globals()[function_name] for alias in [name] + aliases: subcommand_functions[alias] = function # make a subparser and run the command's setup function on it - setup_parser_cmd_name = 'workspace_%s_setup_parser' % name + setup_parser_cmd_name = sanitize_arg_name('workspace_%s_setup_parser' % name) setup_parser_cmd = globals()[setup_parser_cmd_name] subsubparser = sp.add_parser( From 9190dfaadaed01936d4960879b91e4dea54b7c3e Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 11:38:44 -0600 Subject: [PATCH 07/12] Rename arg to have hypens --- lib/ramble/ramble/cmd/workspace.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ramble/ramble/cmd/workspace.py b/lib/ramble/ramble/cmd/workspace.py index 4e6b16027..2bfe7a7d1 100644 --- a/lib/ramble/ramble/cmd/workspace.py +++ b/lib/ramble/ramble/cmd/workspace.py @@ -51,7 +51,7 @@ 'concretize', 'setup', 'analyze', - 'pushtocache', + 'push-to-cache', 'info', 'edit', 'mirror', @@ -406,7 +406,7 @@ def workspace_analyze(args): workspace_run_pipeline(args, pipeline) -def workspace_pushtocache(args): +def workspace_push_to_cache(args): current_pipeline = ramble.pipeline.pipelines.pushtocache ws = ramble.cmd.require_active_workspace(cmd_name='workspace pushtocache') @@ -423,7 +423,7 @@ def workspace_pushtocache(args): pipeline.run() -def workspace_pushtocache_setup_parser(subparser): +def workspace_push_to_cache_setup_parser(subparser): """push workspace envs to a given spack buildcache""" subparser.add_argument( From da86eaf83ad821b3c25f1614d858178f1d20dff0 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 12:30:24 -0600 Subject: [PATCH 08/12] Add caching to proactively avoid repeated pushes --- lib/ramble/ramble/application_types/spack.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ramble/ramble/application_types/spack.py b/lib/ramble/ramble/application_types/spack.py index f4d7c2cb2..eff5d68c0 100644 --- a/lib/ramble/ramble/application_types/spack.py +++ b/lib/ramble/ramble/application_types/spack.py @@ -368,11 +368,17 @@ def _mirror_software(self, workspace): register_phase('push_to_spack_cache', pipeline='pushtocache', depends_on=[]) def _push_to_spack_cache(self, workspace): + + env_path = self.expander.env_path + cache_tupl = ('push-to-cache', env_path) + if workspace.check_cache(cache_tupl): + tty.debug('{} already pushed, skipping'.format(cache_tupl)) + return + else: + workspace.add_to_cache(cache_tupl) + try: - # TODO: this is a lot of repeated stuff, can we DRY with out pipelines? self.spack_runner.set_dry_run(workspace.dry_run) - - env_path = self.expander.env_path self.spack_runner.set_env(env_path) self.spack_runner.activate() From bd7ef5bedf49f01160f55eb421da15f928d9b00d Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 12:31:36 -0600 Subject: [PATCH 09/12] fix cycle detection for divergent pipelines --- lib/ramble/ramble/application.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ramble/ramble/application.py b/lib/ramble/ramble/application.py index a98ce24ea..c0a4980ae 100644 --- a/lib/ramble/ramble/application.py +++ b/lib/ramble/ramble/application.py @@ -155,6 +155,9 @@ def build_phase_order(self): for pipeline in self._pipelines: pipeline_phases = [] + if pipeline not in self.phase_definitions: + self.phase_definitions[pipeline] = [] + # Detect cycles for phase in self.phase_definitions[pipeline].keys(): From dbb5540a470fae76ec87b9a0c6e17c097aa89e94 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 12:50:24 -0600 Subject: [PATCH 10/12] update bash completion --- share/ramble/ramble-completion.bash | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/ramble/ramble-completion.bash b/share/ramble/ramble-completion.bash index 3f1872c59..41739d02a 100755 --- a/share/ramble/ramble-completion.bash +++ b/share/ramble/ramble-completion.bash @@ -631,7 +631,7 @@ _ramble_workspace() { then RAMBLE_COMPREPLY="-h --help" else - RAMBLE_COMPREPLY="activate archive deactivate create concretize setup analyze info edit mirror list ls remove rm" + RAMBLE_COMPREPLY="activate archive deactivate create concretize setup analyze push-to-cache info edit mirror list ls remove rm" fi } @@ -673,6 +673,10 @@ _ramble_workspace_analyze() { RAMBLE_COMPREPLY="-h --help -f --formats -u --upload --always-print-foms --phases --include-phase-dependencies --where --exclude-where" } +_ramble_workspace_push_to_cache() { + RAMBLE_COMPREPLY="-h --help -d --where --exclude-where" +} + _ramble_workspace_info() { RAMBLE_COMPREPLY="-h --help -v --verbose" } From 7fb6188dffe035ea706a7964a26035db3ec6bc3c Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 12:51:06 -0600 Subject: [PATCH 11/12] update bash commands --- lib/ramble/ramble/application.py | 2 +- lib/ramble/ramble/spack_runner.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ramble/ramble/application.py b/lib/ramble/ramble/application.py index c0a4980ae..4aeaf6aad 100644 --- a/lib/ramble/ramble/application.py +++ b/lib/ramble/ramble/application.py @@ -156,7 +156,7 @@ def build_phase_order(self): pipeline_phases = [] if pipeline not in self.phase_definitions: - self.phase_definitions[pipeline] = [] + self.phase_definitions[pipeline] = {} # Detect cycles for phase in self.phase_definitions[pipeline].keys(): diff --git a/lib/ramble/ramble/spack_runner.py b/lib/ramble/ramble/spack_runner.py index fc5cfcbf9..33cb6b2a0 100644 --- a/lib/ramble/ramble/spack_runner.py +++ b/lib/ramble/ramble/spack_runner.py @@ -696,7 +696,7 @@ def push_to_spack_cache(self, spack_cache_path): if user_flags is not None: args.extend(shlex.split(user_flags)) - args.extend( [ spack_cache_path, hash_list ] ) + args.extend([spack_cache_path, hash_list]) if not self.dry_run: return self.spack(*args, output=str).strip() @@ -704,7 +704,6 @@ def push_to_spack_cache(self, spack_cache_path): self._dry_run_print(self.spack, args) return - def _dry_run_print(self, executable, args): tty.msg('DRY-RUN: would run %s' % executable) tty.msg(' with args: %s' % args) From 1e847177a078d85144cf388f8249ec58538f700f Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 12 Oct 2023 13:16:19 -0600 Subject: [PATCH 12/12] fix bad merge --- lib/ramble/ramble/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ramble/ramble/pipeline.py b/lib/ramble/ramble/pipeline.py index 89106a037..af5970cc0 100644 --- a/lib/ramble/ramble/pipeline.py +++ b/lib/ramble/ramble/pipeline.py @@ -354,10 +354,10 @@ def _prepare(self): def _complete(self): tty.msg('Pushed envs to spack cache %s' % self.spack_cache_path) - + pipelines = Enum('pipelines', [AnalyzePipeline.name, ArchivePipeline.name, MirrorPipeline.name, - SetupPipeline.name] + SetupPipeline.name, PushToCachePipeline.name] ) _pipeline_map = {