Skip to content
140 changes: 136 additions & 4 deletions src/aiida/cmdline/commands/cmd_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from aiida.cmdline.params import arguments, options
from aiida.cmdline.params.options.commands import computer as options_computer
from aiida.cmdline.utils import echo, echo_tabulate
from aiida.cmdline.utils.common import validate_output_filename
from aiida.cmdline.utils.common import tabulate, validate_output_filename
from aiida.cmdline.utils.decorators import with_dbenv
from aiida.common.exceptions import EntryPointError, ValidationError
from aiida.plugins.entry_point import get_entry_point_names
Expand Down Expand Up @@ -227,7 +227,7 @@

if not isclose(timing_true, timing_false, rel_tol=rel_tol, abs_tol=abs_tol):
return True, (
f"\n\n{click.style('Warning:', fg='yellow', bold=True)} "
f'\n\n{click.style("Warning:", fg="yellow", bold=True)} '
'The computer is configured to use a login shell, which is slower compared to a normal shell.\n'
f'Command execution time of {timing_true:.3f} versus {timing_false:.3f} seconds, respectively).\n'
'Unless this setting is really necessary, consider disabling it with:\n'
Expand Down Expand Up @@ -345,7 +345,7 @@
from aiida.orm.utils.builders.computer import ComputerBuilder

if kwargs['label'] in get_computer_names():
echo.echo_critical(f"A computer called {kwargs['label']} already exists")
echo.echo_critical(f'A computer called {kwargs["label"]} already exists')

Check warning on line 348 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L348

Added line #L348 was not covered by tests

kwargs['transport'] = kwargs['transport'].name
kwargs['scheduler'] = kwargs['scheduler'].name
Expand Down Expand Up @@ -716,7 +716,7 @@
if config.get(option.name) or config.get(option.name) is False:
if t_opt.get('switch'):
option_value = (
option.opts[-1] if config.get(option.name) else f"--no-{option.name.replace('_', '-')}"
option.opts[-1] if config.get(option.name) else f'--no-{option.name.replace("_", "-")}'
)
elif t_opt.get('is_flag'):
is_default = config.get(option.name) == transport_cli.transport_option_default(
Expand Down Expand Up @@ -832,3 +832,135 @@
)
else:
echo.echo_success(f'Computer<{computer.pk}> {computer.label} configuration exported to file `{output_file}`.')


@verdi_computer.command('search')
@click.argument('pattern', type=str, required=False)
@click.option(
'--source',
type=click.Choice(['code-registry', 'resource-registry', 'ssh-config']),
default='ssh-config',
help='Specify the computer source (default: ssh-config)',
)
@click.pass_context
@with_dbenv()
def computer_search(ctx, pattern, source):
"""Search for computers and setup them in your profile.

If PATTERN is provided, search for computers matching that pattern.
If no pattern is provided, show all available computers.

This command allows you to discover and setup computers from:
- The community AiiDA code registry
- The AiiDA resource registry
- Your local SSH configuration at ~/.ssh/config
"""
from aiida.cmdline.utils.registry_helpers import (

Check warning on line 858 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L858

Added line #L858 was not covered by tests
ComputerSearchService,
ComputerSelector,
ComputerSetupHandler,
ComputerSource,
)

# Convert string to enum
source_enum = ComputerSource(source)

Check warning on line 866 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L866

Added line #L866 was not covered by tests

# Initialize service
service = ComputerSearchService()

Check warning on line 869 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L869

Added line #L869 was not covered by tests

# Fetch data
echo.echo_report('Fetching computer data from sources...')
registry_data = service.fetch_data(source_enum)

Check warning on line 873 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L872-L873

Added lines #L872 - L873 were not covered by tests

if not registry_data:
echo.echo_error('No computer data could be fetched from any source.')
return

Check warning on line 877 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L875-L877

Added lines #L875 - L877 were not covered by tests

echo.echo_success(f'Total: {len(registry_data)} computers available from all sources.')

Check warning on line 879 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L879

Added line #L879 was not covered by tests

# Filter by pattern if provided
if pattern:
matching_data = service.filter_by_pattern(pattern)
if not matching_data:
echo.echo_warning(f"No computers found matching pattern '{pattern}'")
if not click.confirm('\nWould you like to show all available systems?'):
return
echo.echo_report('All available systems:')

Check warning on line 888 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L882-L888

Added lines #L882 - L888 were not covered by tests
else:
echo.echo_report(f"Systems matching the pattern '{pattern}':")
registry_data = matching_data

Check warning on line 891 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L890-L891

Added lines #L890 - L891 were not covered by tests
else:
echo.echo_report('All available systems:')

Check warning on line 893 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L893

Added line #L893 was not covered by tests

# Handle SSH-only source differently
if source_enum == ComputerSource.SSH_CONFIG:

Check warning on line 896 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L896

Added line #L896 was not covered by tests
# Show table of SSH config computers
print(

Check warning on line 898 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L898

Added line #L898 was not covered by tests
tabulate(
[[i + 1, k] for i, k in enumerate(registry_data.keys())],
headers=['#', 'SSH Config Computer'],
tablefmt='grid',
)
)
echo.echo_report('Computers registered in the ~/.ssh/config can be set up using the `core.ssh_async` transport')
echo.echo_report('This transport plugin automatically uses your OS SSH configuration')
echo.echo_report('for connection settings including ProxyJump, IdentityFile, and other SSH options.')
echo.echo_report('For more information, see the AiiDA documentation on SSH transport plugins.')
return

Check warning on line 909 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L905-L909

Added lines #L905 - L909 were not covered by tests

selector = ComputerSelector(registry_data)
selection = _get_computer_selection(selector, pattern)
if not selection:
return

Check warning on line 914 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L911-L914

Added lines #L911 - L914 were not covered by tests

system_name, variant = selection

Check warning on line 916 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L916

Added line #L916 was not covered by tests

# Handle SSH config computers differently
if system_name.startswith('ssh:'):
hostname = system_name.replace('ssh:', '')
ComputerSetupHandler.handle_ssh_config_setup(system_name, hostname)
return

Check warning on line 922 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L919-L922

Added lines #L919 - L922 were not covered by tests

# Prompt user before setup
if not click.confirm(

Check warning on line 925 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L925

Added line #L925 was not covered by tests
f'Would you like to set up the computer "{system_name}" with variant "{variant}" now?', default=True
):
print('Setup cancelled.')
return

Check warning on line 929 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L928-L929

Added lines #L928 - L929 were not covered by tests

# Handle registry computers
ComputerSetupHandler.handle_registry_setup(ctx, selector, system_name, variant, auto_setup=True)

Check warning on line 932 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L932

Added line #L932 was not covered by tests


def _get_computer_selection(selector, pattern):
"""Get computer and variant selection from user."""
# Check if pattern matches exactly one system
if pattern:
matching_systems = [system for system in selector.registry_data.keys() if pattern in system]
if len(matching_systems) == 1:
selected_computer = matching_systems[0]
echo.echo_report(f'Using the only matching computer: {selected_computer}')

Check warning on line 942 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L938-L942

Added lines #L938 - L942 were not covered by tests

# Skip variant selection for SSH config
if selected_computer.startswith('ssh:'):
return (selected_computer, 'ssh_config')

Check warning on line 946 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L945-L946

Added lines #L945 - L946 were not covered by tests

selected_variant = selector.select_variant(selected_computer)
if not selected_variant:
return None
return (selected_computer, selected_variant)

Check warning on line 951 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L948-L951

Added lines #L948 - L951 were not covered by tests

# Interactive selection
selected_computer = selector.select_computer()
if not selected_computer:
return None

Check warning on line 956 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L954-L956

Added lines #L954 - L956 were not covered by tests

# Skip variant selection for SSH config
if selected_computer.startswith('ssh:'):
return (selected_computer, 'ssh_config')

Check warning on line 960 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L959-L960

Added lines #L959 - L960 were not covered by tests

selected_variant = selector.select_variant(selected_computer)
if not selected_variant:
return None

Check warning on line 964 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L962-L964

Added lines #L962 - L964 were not covered by tests

return (selected_computer, selected_variant)

Check warning on line 966 in src/aiida/cmdline/commands/cmd_computer.py

View check run for this annotation

Codecov / codecov/patch

src/aiida/cmdline/commands/cmd_computer.py#L966

Added line #L966 was not covered by tests
Loading
Loading