Skip to content

Commit 9329183

Browse files
authored
Merge branch 'main' into fix-legacy-fixtures
2 parents e5adde7 + 48991ab commit 9329183

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+8253
-1346
lines changed

.github/workflows/ci-code.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,11 @@ jobs:
138138
test-pytest-fixtures:
139139
# Who watches the watchmen?
140140
# Here we test the pytest fixtures in isolation from the rest of aiida-core test suite,
141+
<<<<<<< fix-legacy-fixtures
141142
# since since they can be used outside of aiida core context, e.g. in plugins.
143+
=======
144+
# since they can be used outside of aiida core context, e.g. in plugins.
145+
>>>>>>> main
142146
# Unlike in other workflows in this file, we purposefully don't setup a test profile.
143147

144148
runs-on: ubuntu-24.04
@@ -174,6 +178,7 @@ jobs:
174178
from-lock: 'true'
175179
extras: tests
176180

181+
<<<<<<< fix-legacy-fixtures
177182
- name: Setup SSH
178183
run: .github/workflows/setup_ssh.sh
179184

@@ -182,6 +187,10 @@ jobs:
182187

183188
- name: Test legacy pytest fixtures
184189
run: pytest -sv --cov aiida --noconftest src/aiida/manage/tests/test_pytest_fixtures.py
190+
=======
191+
- name: Test legacy pytest fixtures
192+
run: pytest --cov aiida --noconftest src/aiida/manage/tests/test_pytest_fixtures.py
193+
>>>>>>> main
185194

186195
- name: Upload coverage report
187196
if: github.repository == 'aiidateam/aiida-core'

.pre-commit-config.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ repos:
126126
src/aiida/manage/configuration/__init__.py|
127127
src/aiida/manage/configuration/config.py|
128128
src/aiida/manage/external/rmq/launcher.py|
129-
src/aiida/manage/tests/main.py|
130-
src/aiida/manage/tests/pytest_fixtures.py|
131129
src/aiida/orm/comments.py|
132130
src/aiida/orm/computers.py|
133131
src/aiida/orm/implementation/storage_backend.py|

codecov.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ coverage:
1515
patch:
1616
default:
1717
threshold: 0.1%
18+
19+
ignore:
20+
- src/aiida/tools/_dumping/**/*

docs/source/howto/data.rst

Lines changed: 379 additions & 46 deletions
Large diffs are not rendered by default.

docs/source/reference/command_line.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ Below is a list with all available subcommands.
223223
create Create an empty group with a given label.
224224
delete Delete groups and (optionally) the nodes they contain.
225225
description Change the description of a group.
226+
dump Dump data of an AiiDA group to disk.
226227
list Show a list of existing groups.
227228
move-nodes Move the specified NODES from one group to another.
228229
path Inspect groups of nodes, with delimited label paths.
@@ -397,6 +398,7 @@ Below is a list with all available subcommands.
397398
Commands:
398399
configure-rabbitmq Configure RabbitMQ for a profile.
399400
delete Delete one or more profiles.
401+
dump Dump all data in an AiiDA profile's storage to disk.
400402
list Display a list of all available profiles.
401403
set-default Set a profile as the default profile.
402404
setdefault (Deprecated) Set a profile as the default profile.
@@ -428,8 +430,8 @@ Below is a list with all available subcommands.
428430
--first-name NONEMPTYSTRING First name of the user. [required]
429431
--last-name NONEMPTYSTRING Last name of the user. [required]
430432
--institution NONEMPTYSTRING Institution of the user. [required]
431-
--db-engine [postgresql_psycopg]
432-
Engine to use to connect to the database. [required]
433+
--db-engine [postgresql_psycopg|postgresql_psycopg2]
434+
Engine to use to connect to the database. (deprecated)
433435
--db-backend [core.psql_dos] Database backend to use. [required]
434436
--db-host HOSTNAME Database server host. Leave empty for "peer"
435437
authentication. [required]
@@ -535,8 +537,8 @@ Below is a list with all available subcommands.
535537
--first-name NONEMPTYSTRING First name of the user. [required]
536538
--last-name NONEMPTYSTRING Last name of the user. [required]
537539
--institution NONEMPTYSTRING Institution of the user. [required]
538-
--db-engine [postgresql_psycopg]
539-
Engine to use to connect to the database. [required]
540+
--db-engine [postgresql_psycopg|postgresql_psycopg2]
541+
Engine to use to connect to the database. (deprecated)
540542
--db-backend [core.psql_dos] Database backend to use. [required]
541543
--db-host HOSTNAME Database server host. Leave empty for "peer"
542544
authentication. [required]

docs/source/topics/calculations/usage.rst

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,17 +632,46 @@ Using the ``COPY`` mode, the target path defines another location (on the same f
632632
}
633633
634634
.. note::
635+
In addition to the ``COPY`` mode, the following modes, these storage efficient modes are also are available:
636+
``COMPRESS_TAR``, ``COMPRESS_TARBZ2``, ``COMPRESS_TARGZ``, ``COMPRESS_TARXZ``.
635637
636-
In the future, other methods for stashing may be implemented, such as placing all files in a (compressed) tarball or even stash files on tape.
638+
The stashed files and folders are represented by an output node that is attached to the calculation node through the label ``remote_stash``, as a ``RemoteStashFolderData`` node.
639+
Just like the ``remote_folder`` node, this represents a location or files on a remote machine and so is equivalent to a "symbolic link".
637640
638641
.. important::
639642
640-
If the ``stash`` option namespace is defined for a calculation job, the daemon will perform the stashing operations before the files are retrieved.
643+
If the ``stash`` option namespace is defined for a generic calculation job, the daemon will perform the stashing operations before the files are retrieved.
641644
This means that the stashing happens before the parsing of the output files (which occurs after the retrieving step), such that that the files will be stashed independent of the final exit status that the parser will assign to the calculation job.
642645
This may cause files to be stashed for calculations that will later be considered to have failed.
643646
644-
The stashed files and folders are represented by an output node that is attached to the calculation node through the label ``remote_stash``, as a ``RemoteStashFolderData`` node.
645-
Just like the ``remote_folder`` node, this represents a location or files on a remote machine and so is equivalent to a "symbolic link".
647+
To avoid this scenario, you can instead, stash via a separate calculation job, for example:
648+
649+
.. code-block:: python
650+
651+
from aiida.common.datastructures import StashMode
652+
from aiida.orm import load_node, load_computer
653+
654+
StashCalculation = CalculationFactory('core.stash')
655+
656+
calcjob_node = load_node(<CALCJOB_PK>)
657+
remote_folder = calcjob_node.outputs.remote_folder
658+
659+
inputs = {
660+
'metadata': {
661+
'computer': load_computer(label="localhost"),
662+
'options': {
663+
'stash': {
664+
'source_list': ['aiida.out', 'output.txt'],
665+
'target_base': '/scratch/',
666+
'stash_mode': StashMode.COPY.value,
667+
},
668+
},
669+
},
670+
'source_node': remote_folder,
671+
}
672+
673+
result = run(StashCalculation, **inputs)
674+
646675
647676
.. important::
648677

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ Documentation = 'https://aiida.readthedocs.io'
279279
Home = 'http://www.aiida.net/'
280280
Source = 'https://github.com/aiidateam/aiida-core'
281281

282+
[tool.coverage.run]
283+
omit = [
284+
"src/aiida/tools/_dumping/**/*"
285+
]
286+
282287
[tool.flit.module]
283288
name = 'aiida'
284289

src/aiida/calculations/stash.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class StashCalculation(CalcJob):
2626
2727
inputs = {
2828
'metadata': {
29-
'computer': Computer.collection.get(label="localhost"),
29+
'computer': load_computer(label="localhost"),
3030
'options': {
3131
'resources': {'num_machines': 1},
3232
'stash': {

src/aiida/cmdline/commands/cmd_group.py

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def group_move_nodes(source_group, target_group, force, nodes, all_entries):
137137

138138
if not force:
139139
click.confirm(
140-
f'Are you sure you want to move {len(nodes)} nodes from {source_group} ' f'to {target_group}?', abort=True
140+
f'Are you sure you want to move {len(nodes)} nodes from {source_group} to {target_group}?', abort=True
141141
)
142142

143143
source_group.remove_nodes(nodes)
@@ -325,6 +325,11 @@ def group_relabel(group, label):
325325
echo.echo_critical(str(exception))
326326
else:
327327
echo.echo_success(f"Label changed to '{label}'")
328+
msg = (
329+
'Note that if you are dumping your profile data to disk, to reflect the relabeling of the group, '
330+
'run your `verdi profile dump` command again.'
331+
)
332+
echo.echo_report(msg)
328333

329334

330335
@verdi_group.command('description')
@@ -632,3 +637,106 @@ def group_path_ls(path, type_string, recursive, as_table, no_virtual, with_descr
632637
if no_virtual and child.is_virtual:
633638
continue
634639
echo.echo(child.path, bold=not child.is_virtual)
640+
641+
642+
@verdi_group.command('dump')
643+
@arguments.GROUP()
644+
@options.PATH()
645+
@options.DRY_RUN()
646+
@options.OVERWRITE()
647+
@options.PAST_DAYS()
648+
@options.START_DATE()
649+
@options.END_DATE()
650+
@options.FILTER_BY_LAST_DUMP_TIME()
651+
@options.ONLY_TOP_LEVEL_CALCS()
652+
@options.ONLY_TOP_LEVEL_WORKFLOWS()
653+
@options.DELETE_MISSING()
654+
@options.SYMLINK_CALCS()
655+
@options.INCLUDE_INPUTS()
656+
@options.INCLUDE_OUTPUTS()
657+
@options.INCLUDE_ATTRIBUTES()
658+
@options.INCLUDE_EXTRAS()
659+
@options.FLAT()
660+
@options.DUMP_UNSEALED()
661+
@click.pass_context
662+
@with_dbenv()
663+
def group_dump(
664+
ctx,
665+
group,
666+
path,
667+
dry_run,
668+
overwrite,
669+
past_days,
670+
start_date,
671+
end_date,
672+
filter_by_last_dump_time,
673+
delete_missing,
674+
only_top_level_calcs,
675+
only_top_level_workflows,
676+
symlink_calcs,
677+
include_inputs,
678+
include_outputs,
679+
include_attributes,
680+
include_extras,
681+
flat,
682+
dump_unsealed,
683+
):
684+
"""Dump data of an AiiDA group to disk."""
685+
686+
import traceback
687+
from pathlib import Path
688+
689+
from aiida.cmdline.utils import echo
690+
from aiida.tools._dumping.utils import DumpPaths
691+
692+
warning_msg = (
693+
'This is a new feature which is still in its testing phase. '
694+
'If you encounter unexpected behavior or bugs, please report them via Discourse or GitHub.'
695+
)
696+
echo.echo_warning(warning_msg)
697+
698+
try:
699+
if path is None:
700+
group_path = DumpPaths.get_default_dump_path(group)
701+
dump_base_output_path = Path.cwd() / group_path
702+
echo.echo_report(f'No output path specified. Using default: `{dump_base_output_path}`')
703+
else:
704+
dump_base_output_path = Path(path).resolve()
705+
echo.echo_report(f'Using specified output path: `{dump_base_output_path}`')
706+
707+
# --- Logical Checks ---
708+
if dry_run and overwrite:
709+
msg = (
710+
'`--dry-run` and `--overwrite` selected (or set in config). Overwrite operation will NOT be performed.'
711+
)
712+
echo.echo_warning(msg)
713+
714+
# Run the dumping
715+
group.dump(
716+
output_path=dump_base_output_path,
717+
dry_run=dry_run,
718+
overwrite=overwrite,
719+
past_days=past_days,
720+
start_date=start_date,
721+
end_date=end_date,
722+
filter_by_last_dump_time=filter_by_last_dump_time,
723+
only_top_level_calcs=only_top_level_calcs,
724+
only_top_level_workflows=only_top_level_workflows,
725+
symlink_calcs=symlink_calcs,
726+
include_inputs=include_inputs,
727+
include_outputs=include_outputs,
728+
include_attributes=include_attributes,
729+
include_extras=include_extras,
730+
flat=flat,
731+
dump_unsealed=dump_unsealed,
732+
)
733+
734+
if not dry_run:
735+
msg = f'Raw files for group `{group.label}` dumped into folder `{dump_base_output_path.name}`.'
736+
echo.echo_success(msg)
737+
else:
738+
echo.echo_success('Dry run completed.')
739+
740+
except Exception as e:
741+
msg = f'Unexpected error during dump of group {group.label}:\n ({e!s}).\n'
742+
echo.echo_critical(msg + traceback.format_exc())

0 commit comments

Comments
 (0)