Skip to content

Commit 5b3f5d2

Browse files
committed
wip
1 parent 7cc0c02 commit 5b3f5d2

File tree

2 files changed

+775
-655
lines changed

2 files changed

+775
-655
lines changed

src/aiida/cmdline/commands/cmd_computer.py

Lines changed: 93 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from aiida.cmdline.params import arguments, options
2121
from aiida.cmdline.params.options.commands import computer as options_computer
2222
from aiida.cmdline.utils import echo, echo_tabulate
23-
from aiida.cmdline.utils.common import validate_output_filename
23+
from aiida.cmdline.utils.common import validate_output_filename, tabulate
2424
from aiida.cmdline.utils.decorators import with_dbenv
2525
from aiida.common.exceptions import EntryPointError, ValidationError
2626
from aiida.plugins.entry_point import get_entry_point_names
@@ -842,214 +842,120 @@ def computer_export_config(computer, output_file, user, overwrite, sort):
842842
default='ssh-config',
843843
help='Specify the computer source (default: ssh-config)',
844844
)
845-
@click.option(
846-
'--auto-setup',
847-
is_flag=True,
848-
default=True,
849-
help='Automatically run setup and configure commands after saving config files',
850-
)
851845
@click.pass_context
852846
@with_dbenv()
853-
def computer_search(ctx, pattern, source, auto_setup):
854-
"""Search for computers in the AiiDA registries and setup them up in your profile.
847+
def computer_search(ctx, pattern, source):
848+
"""Search for computers and setup them in your profile.
855849
856850
If PATTERN is provided, search for computers matching that pattern.
857851
If no pattern is provided, show all available computers.
858852
859-
This command allows you to discover and setup computers from:\n
860-
- The community AiiDA code registry at https://github.com/aiidateam/aiida-code-registry/\n
861-
- The AiiDA resource registry at https://github.com/aiidateam/aiida-resource-registry/\n
862-
- Your local SSH configuration at ``~/.ssh/config``
853+
This command allows you to discover and setup computers from:
854+
- The community AiiDA code registry
855+
- The AiiDA resource registry
856+
- Your local SSH configuration at ~/.ssh/config
863857
"""
864-
865-
from aiida.cmdline.utils.common import tabulate
866858
from aiida.cmdline.utils.registry_helpers import (
867-
fetch_code_registry_data,
868-
fetch_resource_registry_data,
869-
fetch_ssh_config_data,
870-
get_computer_configure_config,
871-
get_computer_setup_config,
872-
get_computers_table,
873-
interactive_computer_selector,
874-
interactive_variant_selector,
875-
process_template_variables,
876-
save_config_to_file,
877-
)
878-
879-
echo.echo_report('Fetching AiiDA registries...')
880-
# NOTE: There is quite some overlap between code registry and resource registry
881-
# code registry: 'daint.cscs.ch', 'imxgesrv1.epfl.ch', 'lsmosrv6', 'fidis.epfl.ch', 'tigu.empa.ch', 'paratera',
882-
# 'merlin.psi.ch', 'eiger.cscs.ch'
883-
# resource registry: 'eiger.cscs.ch', 'daint.cscs.ch', 'merlin.psi.ch', 'merlin7.psi.ch'
884-
# if source == 'both':
885-
# registry_data = fetch_code_registry_data() | fetch_resource_registry_data()
886-
if source == 'ssh-config':
887-
registry_data = fetch_ssh_config_data()
888-
else:
889-
echo.echo_report('Fetching AiiDA registries...')
890-
if source == 'resource-registry':
891-
registry_data = fetch_resource_registry_data()
892-
elif source == 'code-registry':
893-
registry_data = fetch_code_registry_data()
894-
echo.echo_success(f'Successfully fetched AiiDA registry data. Found {len(registry_data)} computers.')
895-
896-
matching_systems = None
897-
if pattern:
898-
matching_systems = [system for system in registry_data.keys() if pattern in system]
899-
if not matching_systems:
900-
echo.echo_warning(f"No computers found matching pattern '{pattern}'")
901-
if not click.confirm('\nWould you like to show all available systems in the registry?'):
902-
return
903-
table = get_computers_table(registry_data)
904-
echo.echo(
905-
tabulate(table, headers=['System', 'Variants', 'Hostname', 'Codes (default variant)'], tablefmt='grid')
906-
)
907-
else:
908-
registry_data = {match: registry_data[match] for match in matching_systems}
909-
echo.echo_report(f"Systems in the registry matching the pattern '{pattern}'")
910-
table = get_computers_table(registry_data)
911-
echo.echo(
912-
tabulate(table, headers=['System', 'Variants', 'Hostname', 'Codes (default variant)'], tablefmt='grid')
913-
)
914-
915-
else:
916-
echo.echo_report('All available systems in the registries:')
917-
table = get_computers_table(registry_data)
918-
echo.echo(
919-
tabulate(table, headers=['System', 'Variants', 'Hostname', 'Codes (default variant)'], tablefmt='grid')
920-
)
859+
ComputerSearchService,
860+
ComputerSelector,
861+
ComputerSetupHandler,
862+
ComputerSource,
863+
) # noqa: PLC0415
921864

922-
# import ipdb
865+
# Convert string to enum
866+
source_enum = ComputerSource(source)
923867

924-
# ipdb.set_trace()
925-
# if source == 'ssh-config':
926-
# import ipdb
868+
# Initialize service
869+
service = ComputerSearchService()
927870

928-
# ipdb.set_trace()
871+
# Fetch data
872+
echo.echo_report('Fetching computer data from sources...')
873+
registry_data = service.fetch_data(source_enum)
929874

930-
# Offer to select a computer from the retrieved table
931-
if not click.confirm('\nWould you like to select a computer?', default=True):
875+
if not registry_data:
876+
echo.echo_error('No computer data could be fetched from any source.')
932877
return
933878

934-
# TODO: Don't call variant selector for Computer from `ssh-config`
935-
936-
# Handle computer selection based on pattern matching
937-
if matching_systems and len(matching_systems) == 1:
938-
# Only one match, use it directly and just select variant
939-
selected_computer = matching_systems[0]
940-
echo.echo_report(f'Using the only matching computer: {selected_computer}')
941-
selected_variant = interactive_variant_selector(registry_data, selected_computer)
942-
if not selected_variant:
943-
return
944-
selection = (selected_computer, selected_variant)
945-
else:
946-
# Multiple matches or no pattern, let user choose computer and variant
947-
selected_computer = interactive_computer_selector(registry_data)
948-
if not selected_computer:
949-
return
950-
951-
selected_variant = interactive_variant_selector(registry_data, selected_computer)
952-
if not selected_variant:
953-
return
954-
955-
selection = (selected_computer, selected_variant)
956-
957-
system_name, variant = selection
958-
959-
# Get the raw configurations
960-
setup_config = get_computer_setup_config(registry_data, system_name, variant)
961-
configure_config = get_computer_configure_config(registry_data, system_name, variant)
879+
echo.echo_success(f'Total: {len(registry_data)} computers available from all sources.')
962880

963-
echo.echo_info(f'\n📋 Processing configuration for {system_name} ({variant})')
964-
965-
# Process template variables for setup config
966-
echo.echo_info('\n🔧 Processing computer setup configuration...')
967-
processed_setup_config = process_template_variables(setup_config)
968-
if processed_setup_config is None:
969-
echo.echo_info('Configuration processing was cancelled.')
881+
# Filter by pattern if provided
882+
if pattern:
883+
matching_data = service.filter_by_pattern(pattern)
884+
if not matching_data:
885+
echo.echo_warning(f"No computers found matching pattern '{pattern}'")
886+
if not click.confirm('\nWould you like to show all available systems?'):
887+
return
888+
echo.echo_report('All available systems:')
889+
else:
890+
echo.echo_report(f"Systems matching the pattern '{pattern}':")
891+
registry_data = matching_data
892+
else:
893+
echo.echo_report('All available systems:')
894+
895+
# Handle SSH-only source differently
896+
if source_enum == ComputerSource.SSH_CONFIG:
897+
# Show table of SSH config computers
898+
print(tabulate(
899+
[[i+1, k] for i, k in enumerate(registry_data.keys())],
900+
headers=['#', 'SSH Config Computer'],
901+
tablefmt='grid'))
902+
echo.echo_report('Computers registered in the ~/.ssh/config can be set up using the `core.ssh_async` transport')
903+
echo.echo_report('This transport plugin automatically uses your OS SSH configuration')
904+
echo.echo_report('for connection settings including ProxyJump, IdentityFile, and other SSH options.')
905+
echo.echo_report('For more information, see the AiiDA documentation on SSH transport plugins.')
970906
return
971907

972-
# Process template variables for configure config
973-
echo.echo_info('\n🔐 Processing computer configure configuration...')
974-
processed_configure_config = process_template_variables(configure_config)
975-
if processed_configure_config is None:
976-
echo.echo_info('Configuration processing was cancelled.')
908+
selector = ComputerSelector(registry_data)
909+
selection = _get_computer_selection(selector, pattern)
910+
if not selection:
977911
return
978912

913+
system_name, variant = selection
979914

980-
if source == 'ssh-config':
981-
echo.echo_report(
982-
"We recommend running `verdi computer setup` with the `core.ssh_async` transport plugin."
983-
"This will automatically use your operating system (OpenSSH) configuration."
984-
)
985-
if auto_setup:
986-
echo.echo_warning(
987-
"Automatic setup is not possible as necessary AiiDA options not contained in ssh-config file."
988-
)
915+
# Handle SSH config computers differently
916+
if system_name.startswith('ssh:'):
917+
hostname = system_name.replace('ssh:', '')
918+
ComputerSetupHandler.handle_ssh_config_setup(system_name, hostname)
989919
return
990920

991-
# Save both configurations to files
992-
echo.echo_info('Saving configurations to files...')
993-
994-
setup_file = save_config_to_file(processed_setup_config, 'setup', system_name, variant)
995-
configure_file = save_config_to_file(processed_configure_config, 'configure', system_name, variant)
996-
997-
# Get the computer label from the setup config for the configure command
998-
computer_label = processed_setup_config.get('label', f'{system_name}_{variant}')
999-
1000-
# Get the transport type from the setup config for the configure command
1001-
transport_type = processed_setup_config.get('transport', 'core.ssh')
1002-
1003-
if auto_setup:
1004-
1005-
echo.echo_report('\n🚀 Automatically setting up computer...')
1006-
1007-
# Invoke computer setup command
1008-
from aiida.plugins import SchedulerFactory, TransportFactory
1009-
1010-
# Convert strings to entry point objects (not loaded classes)
1011-
processed_setup_config_copy = processed_setup_config.copy()
1012-
1013-
# Get the entry point objects (load=False to get the entry point, not the loaded class)
1014-
if 'scheduler' in processed_setup_config_copy:
1015-
scheduler_ep = SchedulerFactory(processed_setup_config_copy['scheduler'], load=False)
1016-
processed_setup_config_copy['scheduler'] = scheduler_ep
1017-
1018-
if 'transport' in processed_setup_config_copy:
1019-
transport_ep = TransportFactory(processed_setup_config_copy['transport'], load=False)
1020-
processed_setup_config_copy['transport'] = transport_ep
1021-
1022-
# Now invoke with the entry point objects
1023-
ctx.invoke(computer_setup, non_interactive=False, **processed_setup_config_copy)
1024-
echo.echo_success('✅ Computer setup completed successfully!')
1025-
1026-
# Invoke computer configure command
1027-
echo.echo_info('\n🔧 Automatically configuring computer...')
1028-
1029-
# Import the transport CLI to get the configure command
1030-
from aiida.transports import cli as transport_cli
1031-
1032-
configure_cmd = transport_cli.create_configure_cmd(transport_type)
1033-
1034-
# Get the computer object to pass to configure command
1035-
from aiida.orm import Computer
1036-
1037-
computer = Computer.collection.get(label=computer_label)
921+
# Prompt user before setup
922+
if not click.confirm(f'Would you like to set up the computer "{system_name}" with variant "{variant}" now?', default=True):
923+
print('Setup cancelled.')
924+
return
1038925

1039-
# Invoke the configure command with the config file
1040-
import ipdb
926+
# Handle registry computers
927+
ComputerSetupHandler.handle_registry_setup(ctx, selector, system_name, variant, auto_setup=True)
1041928

1042-
ipdb.set_trace()
1043-
ctx.invoke(
1044-
configure_cmd,
1045-
computer=computer,
1046-
config_file=configure_file,
1047-
)
1048-
echo.echo_success('✅ Computer configuration completed successfully!')
1049-
echo.echo_success(f'🎉 Computer "{computer_label}" is now ready to use!')
1050929

1051-
else:
1052-
echo.echo('To set up the computer, run:')
1053-
echo.echo(f' verdi computer setup --config {setup_file}')
1054-
echo.echo('\nTo configure the computer, run:')
1055-
echo.echo(f' verdi computer configure {transport_type} {computer_label} --config {configure_file}')
930+
def _get_computer_selection(selector, pattern):
931+
"""Get computer and variant selection from user."""
932+
# Check if pattern matches exactly one system
933+
if pattern:
934+
matching_systems = [system for system in selector.registry_data.keys() if pattern in system]
935+
if len(matching_systems) == 1:
936+
selected_computer = matching_systems[0]
937+
echo.echo_report(f'Using the only matching computer: {selected_computer}')
938+
939+
# Skip variant selection for SSH config
940+
if selected_computer.startswith('ssh:'):
941+
return (selected_computer, 'ssh_config')
942+
943+
selected_variant = selector.select_variant(selected_computer)
944+
if not selected_variant:
945+
return None
946+
return (selected_computer, selected_variant)
947+
948+
# Interactive selection
949+
selected_computer = selector.select_computer()
950+
if not selected_computer:
951+
return None
952+
953+
# Skip variant selection for SSH config
954+
if selected_computer.startswith('ssh:'):
955+
return (selected_computer, 'ssh_config')
956+
957+
selected_variant = selector.select_variant(selected_computer)
958+
if not selected_variant:
959+
return None
960+
961+
return (selected_computer, selected_variant)

0 commit comments

Comments
 (0)