Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manager: check if repository container has been initialised #4889

Merged
merged 1 commit into from
Apr 29, 2021

Conversation

mbercx
Copy link
Member

@mbercx mbercx commented Apr 29, 2021

Fixes #4885

When loading the backend of the profile with the Manager._load_backend
method, the get_repository_container method of the Profile is
called, initialising a container for the profile in case is has not yet
been initialised. This causes issues during the migration of the
database/repository, since here the presence of the container directory
results in a critical failure of the migration command.

Here we add a check in the _load_backend method to see if the
container of the profile has already been initialised. If it has, the
repository uuid obtained from the container, if not it is set to None.
This also removes the warning that was printed during the migration
or the creation of a new profile, since the repository uuid obtained
from the database backend is also None before the migration.

When loading the backend of the profile with the `Manager._load_backend`
method, the `get_repository_container` method of the `Profile` is
called, initialising a container for the profile in case is has not yet
been initialised. This causes issues during the migration of the
database/repository, since here the presence of the container directory
results in a critical failure of the migration command.

Here we add a check in the `_load_backend` method to see if the
container of the profile has already been initialised. If it has, the
repository uuid obtained from the container, if not it is set to `None`.
This also removes the warning that was printed during the migration,
since the repository uuid obtained from the database backend is also `None`
in before the migration.
@mbercx mbercx added priority/critical-blocking must be resolved before next release topic/repository labels Apr 29, 2021
@mbercx mbercx added this to the v2.0.0 milestone Apr 29, 2021
@mbercx mbercx requested a review from sphuber April 29, 2021 10:07
@mbercx
Copy link
Member Author

mbercx commented Apr 29, 2021

I've tried this for my development database and it seems to work fine for the migration. I did get the following warning though:

Warning:                                                                                                                                                                
Detected repository folders that were missing the required subfolder `path` or `raw_input`. The paths of those nodes repository folders have been written to a log file: /home/mbercx/envs/aiida-dev/setup/profile/migration-repository-missing-subfolder-4i32qdwj.json

I do tend to mess around with my development database/repo quite a bit, so I may have messed it up somewhere. Will clone a different production database and try again with this branch.

container.init_container(clear=True, **self.defaults['repository']) # pylint: disable=unsubscriptable-object

return container

@property
def container_is_initialised(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering if we should remove container from these methods. I know that I called the method get_repository_container but the container part really comes from this particular implementation with the disk-objectstore. If we were to ever change it (don't think we will but in principle) the container concept may disappear. Maybe it would be better to have the following method and property names:

def get_repository() -> `Repository`
def is_repository_initialised
def initialise_repository

Looking at this more, currently get_repository_container returns the Container instance, but this is also a leaky abstraction. Some of the calls to this method currently just use it to get the UUID of the repo. Since then I added Profile.get_repository_uuid which is better and those places should use that instead.

Ok, this was a bit a train of thought and I am now thinking that we should just merge this and then I will do another PR with some proposed interface and name changes. What do you think?

Copy link
Contributor

@CasperWA CasperWA Apr 29, 2021

Choose a reason for hiding this comment

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

Sounds good to me. Then we can move on and you (@mbercx) can disregard my review comments since it should be updated anyway in the upcoming PR and they are not functionally critical.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, then I will merge this now and include your comments in the next PR. Then we can start testing the migration again. Thanks guys

@property
def _container_path(self):
"""Return the path to the container of the profile file repository."""
return os.path.join(self.repository_path, 'container')
Copy link
Contributor

Choose a reason for hiding this comment

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

self.repository_path should be a subclass of pathlib.Path.

Suggested change
return os.path.join(self.repository_path, 'container')
return self.repository_path / 'container'

return container.is_initialised

@property
def _container_path(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
def _container_path(self):
def _container_path(self) -> pathlib.Path:

def container_is_initialised(self):
"""Check if the container of the profile file repository has already been initialised."""
from disk_objectstore import Container
filepath = self._container_path
Copy link
Contributor

Choose a reason for hiding this comment

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

Why didn't pre-commit catch this?

Suggested change
filepath = self._container_path
filepath = self._container_path

container.init_container(clear=True, **self.defaults['repository']) # pylint: disable=unsubscriptable-object

return container

@property
def container_is_initialised(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
def container_is_initialised(self):
def container_is_initialised(self) -> bool:

container.init_container(clear=True, **self.defaults['repository']) # pylint: disable=unsubscriptable-object

return container

@property
def container_is_initialised(self):
"""Check if the container of the profile file repository has already been initialised."""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Check if the container of the profile file repository has already been initialised."""
"""Return whether the container of the profile file repository has already been initialised."""

Comment on lines +149 to +151
filepath = self._container_path
container = Container(filepath)
return container.is_initialised
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
filepath = self._container_path
container = Container(filepath)
return container.is_initialised
return Container(self._container_path).is_initialised

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, if this is a more or less "constant" property, you could store it as a private variable and only create the Container instance once per call to this property, returning the "cached" private variable all the other times instead. I.e., you store the first result here in the private variable.

@codecov
Copy link

codecov bot commented Apr 29, 2021

Codecov Report

Merging #4889 (3a9518e) into develop (287d138) will decrease coverage by 0.01%.
The diff coverage is 75.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #4889      +/-   ##
===========================================
- Coverage    80.08%   80.08%   -0.00%     
===========================================
  Files          514      514              
  Lines        36567    36576       +9     
===========================================
+ Hits         29280    29287       +7     
- Misses        7287     7289       +2     
Flag Coverage Δ
django 74.60% <75.00%> (+0.03%) ⬆️
sqlalchemy 73.50% <75.00%> (-<0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
aiida/manage/manager.py 80.45% <0.00%> (-0.90%) ⬇️
aiida/manage/configuration/profile.py 95.11% <100.00%> (+0.20%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 287d138...3a9518e. Read the comment docs.

@sphuber sphuber self-requested a review April 29, 2021 10:31
Copy link
Contributor

@sphuber sphuber left a comment

Choose a reason for hiding this comment

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

Fanfuckingtastic

@sphuber sphuber dismissed CasperWA’s stale review April 29, 2021 10:32

will be addressed in follow-up PR

@sphuber sphuber merged commit c7897c5 into aiidateam:develop Apr 29, 2021
@mbercx mbercx deleted the fix/4885/container-initialized branch April 29, 2021 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority/critical-blocking must be resolved before next release topic/repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Repository database compatibility check shows when creating new profile
3 participants