Skip to content

Commit

Permalink
Use only one global var for marking config folder tree (#6610)
Browse files Browse the repository at this point in the history
The changes reduce the use of global variables by replacing `DAEMON_DIR`, `DAEMON_LOG_DIR` and `ACCESS_CONTROL_DIR` as derived from helper class `AiiDAConfigPathResolver`. The `AIIDA_CONFIG_FOLDER` is moved as the class attribute `_glb_aiida_config_folder` of `AiiDAConfigDir` which provide `setter/getter` method for access and set the config_folder globally. 

Meanwhile, the `filepaths` method is depracted from profile and moved to config module. It now called with passing the profile. Since the derived files makes more sense as attaching to the config folder location for every profile.
  • Loading branch information
unkcpz authored Nov 27, 2024
1 parent f74adb9 commit 9baf3ca
Show file tree
Hide file tree
Showing 17 changed files with 175 additions and 123 deletions.
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ repos:
src/aiida/engine/processes/ports.py|
src/aiida/manage/configuration/__init__.py|
src/aiida/manage/configuration/config.py|
src/aiida/manage/configuration/profile.py|
src/aiida/manage/external/rmq/launcher.py|
src/aiida/manage/tests/main.py|
src/aiida/manage/tests/pytest_fixtures.py|
Expand Down
6 changes: 4 additions & 2 deletions src/aiida/cmdline/commands/cmd_presto.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def detect_postgres_config(
"""
import secrets

from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER
from aiida.manage.configuration.settings import AiiDAConfigDir
from aiida.manage.external.postgres import Postgres

dbinfo = {
Expand All @@ -92,13 +92,15 @@ def detect_postgres_config(
except Exception as exception:
raise ConnectionError(f'Unable to automatically create the PostgreSQL user and database: {exception}')

aiida_config_folder = AiiDAConfigDir.get()

return {
'database_hostname': postgres_hostname,
'database_port': postgres_port,
'database_name': database_name,
'database_username': database_username,
'database_password': database_password,
'repository_uri': f'file://{AIIDA_CONFIG_FOLDER / "repository" / profile_name}',
'repository_uri': f'file://{aiida_config_folder / "repository" / profile_name}',
}


Expand Down
4 changes: 2 additions & 2 deletions src/aiida/cmdline/commands/cmd_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ def profile_list():
# This can happen for a fresh install and the `verdi setup` has not yet been run. In this case it is still nice
# to be able to see the configuration directory, for instance for those who have set `AIIDA_PATH`. This way
# they can at least verify that it is correctly set.
from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER
from aiida.manage.configuration.settings import AiiDAConfigDir

echo.echo_report(f'configuration folder: {AIIDA_CONFIG_FOLDER}')
echo.echo_report(f'configuration folder: {AiiDAConfigDir.get()}')
echo.echo_critical(str(exception))
else:
echo.echo_report(f'configuration folder: {config.dirpath}')
Expand Down
5 changes: 3 additions & 2 deletions src/aiida/cmdline/commands/cmd_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ def verdi_status(print_traceback, no_rmq):
from aiida.common.docs import URL_NO_BROKER
from aiida.common.exceptions import ConfigurationError
from aiida.engine.daemon.client import DaemonException, DaemonNotRunningException
from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER
from aiida.manage.configuration.settings import AiiDAConfigDir
from aiida.manage.manager import get_manager

exit_code = ExitCode.SUCCESS
configure_directory = AiiDAConfigDir.get()

print_status(ServiceStatus.UP, 'version', f'AiiDA v{__version__}')
print_status(ServiceStatus.UP, 'config', AIIDA_CONFIG_FOLDER)
print_status(ServiceStatus.UP, 'config', configure_directory)

manager = get_manager()

Expand Down
5 changes: 3 additions & 2 deletions src/aiida/cmdline/params/options/commands/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,12 @@ def get_repository_uri_default(ctx):
"""
import os

from aiida.manage.configuration.settings import AIIDA_CONFIG_FOLDER
from aiida.manage.configuration.settings import AiiDAConfigDir

validate_profile_parameter(ctx)
configure_directory = AiiDAConfigDir.get()

return os.path.join(AIIDA_CONFIG_FOLDER, 'repository', ctx.params['profile'].name)
return os.path.join(configure_directory, 'repository', ctx.params['profile'].name)


def get_quicksetup_repository_uri(ctx, param, value):
Expand Down
18 changes: 9 additions & 9 deletions src/aiida/engine/daemon/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ def __init__(self, profile: Profile):
from aiida.common.docs import URL_NO_BROKER

type_check(profile, Profile)
config = get_config()
self._config = get_config()
self._profile = profile
self._socket_directory: str | None = None
self._daemon_timeout: int = config.get_option('daemon.timeout', scope=profile.name)
self._daemon_timeout: int = self._config.get_option('daemon.timeout', scope=profile.name)

if self._profile.process_control_backend is None:
raise ConfigurationError(
Expand Down Expand Up @@ -156,31 +156,31 @@ def virtualenv(self) -> str | None:

@property
def circus_log_file(self) -> str:
return self.profile.filepaths['circus']['log']
return self._config.filepaths(self.profile)['circus']['log']

@property
def circus_pid_file(self) -> str:
return self.profile.filepaths['circus']['pid']
return self._config.filepaths(self.profile)['circus']['pid']

@property
def circus_port_file(self) -> str:
return self.profile.filepaths['circus']['port']
return self._config.filepaths(self.profile)['circus']['port']

@property
def circus_socket_file(self) -> str:
return self.profile.filepaths['circus']['socket']['file']
return self._config.filepaths(self.profile)['circus']['socket']['file']

@property
def circus_socket_endpoints(self) -> dict[str, str]:
return self.profile.filepaths['circus']['socket']
return self._config.filepaths(self.profile)['circus']['socket']

@property
def daemon_log_file(self) -> str:
return self.profile.filepaths['daemon']['log']
return self._config.filepaths(self.profile)['daemon']['log']

@property
def daemon_pid_file(self) -> str:
return self.profile.filepaths['daemon']['pid']
return self._config.filepaths(self.profile)['daemon']['pid']

def get_circus_port(self) -> int:
"""Retrieve the port for the circus controller, which should be written to the circus port file.
Expand Down
6 changes: 3 additions & 3 deletions src/aiida/manage/configuration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@


def get_config_path():
"""Returns path to .aiida configuration directory."""
from .settings import AIIDA_CONFIG_FOLDER, DEFAULT_CONFIG_FILE_NAME
"""Returns path to aiida configuration file."""
from .settings import DEFAULT_CONFIG_FILE_NAME, AiiDAConfigDir

return os.path.join(AIIDA_CONFIG_FOLDER, DEFAULT_CONFIG_FILE_NAME)
return os.path.join(AiiDAConfigDir.get(), DEFAULT_CONFIG_FILE_NAME)


def load_config(create=False) -> 'Config':
Expand Down
30 changes: 30 additions & 0 deletions src/aiida/manage/configuration/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import json
import os
import uuid
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple

from pydantic import (
Expand Down Expand Up @@ -780,3 +781,32 @@ def _atomic_write(self, filepath=None):

handle.flush()
os.rename(handle.name, self.filepath)

def filepaths(self, profile: Profile):
"""Return the filepaths used by a profile.
:return: a dictionary of filepaths
"""
from aiida.manage.configuration.settings import AiiDAConfigPathResolver

_config_path_resolver: AiiDAConfigPathResolver = AiiDAConfigPathResolver(Path(self.dirpath))
daemon_dir = _config_path_resolver.daemon_dir
daemon_log_dir = _config_path_resolver.daemon_log_dir

return {
'circus': {
'log': str(daemon_log_dir / f'circus-{profile.name}.log'),
'pid': str(daemon_dir / f'circus-{profile.name}.pid'),
'port': str(daemon_dir / f'circus-{profile.name}.port'),
'socket': {
'file': str(daemon_dir / f'circus-{profile.name}.sockets'),
'controller': 'circus.c.sock',
'pubsub': 'circus.p.sock',
'stats': 'circus.s.sock',
},
},
'daemon': {
'log': str(daemon_log_dir / f'aiida-{profile.name}.log'),
'pid': str(daemon_dir / f'aiida-{profile.name}.pid'),
},
}
22 changes: 14 additions & 8 deletions src/aiida/manage/configuration/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def __init__(self, name: str, config: Mapping[str, Any], validate=True):
)

self._name = name
self._attributes: Dict[str, Any] = deepcopy(config)
self._attributes: Dict[str, Any] = deepcopy(config) # type: ignore[arg-type]

# Create a default UUID if not specified
if self._attributes.get(self.KEY_UUID, None) is None:
Expand Down Expand Up @@ -235,22 +235,28 @@ def filepaths(self):
:return: a dictionary of filepaths
"""
from .settings import DAEMON_DIR, DAEMON_LOG_DIR
from aiida.common.warnings import warn_deprecation
from aiida.manage.configuration.settings import AiiDAConfigPathResolver

warn_deprecation('This method has been deprecated, use `filepaths` method from `Config` obj instead', version=3)

daemon_dir = AiiDAConfigPathResolver().daemon_dir
daemon_log_dir = AiiDAConfigPathResolver().daemon_log_dir

return {
'circus': {
'log': str(DAEMON_LOG_DIR / f'circus-{self.name}.log'),
'pid': str(DAEMON_DIR / f'circus-{self.name}.pid'),
'port': str(DAEMON_DIR / f'circus-{self.name}.port'),
'log': str(daemon_log_dir / f'circus-{self.name}.log'),
'pid': str(daemon_dir / f'circus-{self.name}.pid'),
'port': str(daemon_dir / f'circus-{self.name}.port'),
'socket': {
'file': str(DAEMON_DIR / f'circus-{self.name}.sockets'),
'file': str(daemon_dir / f'circus-{self.name}.sockets'),
'controller': 'circus.c.sock',
'pubsub': 'circus.p.sock',
'stats': 'circus.s.sock',
},
},
'daemon': {
'log': str(DAEMON_LOG_DIR / f'aiida-{self.name}.log'),
'pid': str(DAEMON_DIR / f'aiida-{self.name}.pid'),
'log': str(daemon_log_dir / f'aiida-{self.name}.log'),
'pid': str(daemon_dir / f'aiida-{self.name}.pid'),
},
}
Loading

1 comment on commit 9baf3ca

@mbercx
Copy link
Member

@mbercx mbercx commented on 9baf3ca Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty sure this commit broke the nightly build of aiida-quantumespresso:

https://github.com/aiidateam/aiida-quantumespresso/actions/runs/12077661923/job/33680877335

For some reason the self._aiida_path attribute is a str in the test, and so getting the daemon_dir fails.

    @property
    def daemon_dir(self) -> pathlib.Path:
>       return self._aiida_path / DEFAULT_DAEMON_DIR_NAME
E       TypeError: unsupported operand type(s) for /: 'str' and 'str'

../aiida-core/src/aiida/manage/configuration/settings.py:75: TypeError

@unkcpz this should definitely be fixed before any release. :)

Please sign in to comment.