-
Notifications
You must be signed in to change notification settings - Fork 192
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
👌 IMPROVE: Configuration migrations #5319
Conversation
Allow for both upgrades and downgrades, and expose this in the CLI. This will allow a route for user to downgrade their configuration, if they try a new version of aiida, but then want to return to an old version.
I haven't added tests for the CLI commands yet @sphuber; will do if you agree they make sense in general Note, this is a prelude to adding a migration, to "compartmentalize" config required by a backend ( |
Codecov Report
@@ Coverage Diff @@
## develop #5319 +/- ##
===========================================
+ Coverage 82.11% 82.13% +0.03%
===========================================
Files 534 533 -1
Lines 38398 38480 +82
===========================================
+ Hits 31526 31603 +77
- Misses 6872 6877 +5
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
Cheers @chrisjsewell , guess my first question would be what the advantage is of having this a manual operation? Why shouldn't we just do this automatically? Is the reason because certain downgrades may be lossy? But even in that case, if they want to downgrade, they are forced to migrate anyway, and there will be an automatic backup. So maybe an automatic migration is still the easiest for users? |
@sphuber how can you automatically downgrade using an old version of aiida, that does not have that migration available 😬 |
I thought the goal of the downgrade was the following scenario:
I thought that your description described this scenario, and this would now allow the user to call Edit: nevermind, I just got the point. Ok, so then we should provide clear instructions (which we can now only do in |
But how can aiida-core v1 downgrade from a future version? |
Yep 👍 |
One major problem that I see with all this is that in order to really try a new version of AiiDA, they will have to migrate their database and those are not downgradable, so there is no point in downgrading the config because you won't be able to use the profile anyway. But I guess, the config can hold more than one profile, and non-migrated profiles could then at least still be used again with an older installation. So maybe this can still be useful. Think just that it should be clearly documented that people should not expect to be able to freely move back and forth between versions. Once you move forward and migrate (both config and storage) you are most likely going to be stuck with that version. |
What if you upgrade and create a new profile, then want to downgrade and use an older (unmigrated) profile? |
Fair. I guess that there are some niche use cases, so I am fine with moving forward with this. Just think we should be very clear up front that the fact that this is here, it isn't possible to always arbitrarily migrate back and forth. Will now review the rest of the PR. |
aiida/cmdline/commands/cmd_config.py
Outdated
@click.option('--version', type=int, default=None, help='Upgrade to specific version (default current).') | ||
def verdi_config_upgrade(version, path): | ||
"""Print a configuration, upgraded to a specific version.""" | ||
from aiida.manage.configuration import CURRENT_CONFIG_VERSION, get_config_path, upgrade_config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this the explicit default in the option, or is aiida.manage
one of the modules we cannot import top-level because of loading time?
aiida/cmdline/commands/cmd_config.py
Outdated
|
||
|
||
@verdi_config.command('upgrade') | ||
@click.argument('path', required=False, default=None, type=click.Path(exists=True, path_type=Path)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want this to be configurable? There should always be just a single config.json
per instance, shouldn't there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I think I will remove this command since, on calling the command, verdi is already auto-upgrading, rendering it kinda useless.
The main thing is the downgrad command
config.setdefault('CONFIG_VERSION', {})['OLDEST_COMPATIBLE'] = 0 | ||
|
||
def downgrade(self, config: ConfigType) -> None: | ||
config.setdefault('CONFIG_VERSION', {})['OLDEST_COMPATIBLE'] = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the downgrade not remove these keys, since they were added in the upgrade?
from uuid import uuid4 # we require this import here, to patch it in the tests | ||
for profile in config.get('profiles', {}).values(): | ||
profile.setdefault('PROFILE_UUID', uuid4().hex) | ||
config.setdefault('CONFIG_VERSION', {})['OLDEST_COMPATIBLE'] = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this line necessary? That is from the previous migration no?
|
||
def downgrade(self, config: ConfigType) -> None: | ||
config.setdefault('CONFIG_VERSION', {})['OLDEST_COMPATIBLE'] = 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, this is not really a downgrade since it does not undo the upgrade. Could this cause issues if actually loading the downgrade config with an older version of aiida-core
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, a downgrade is not to "undo an upgrade", it is to make it compliant with the lower versions schema.
As mentioned above, in #5320, I have also removed the fact that Profile strips unknown keys.
I think there may even be an open issue about this: someone inadvertently used an older version of aiida, which stripped these keys, then tried to upgrade again and it was no longer working
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, happy to go ahead with that behavior if it will be guaranteed to work and we assume that behavior from now on
why though? I don't see any reason why not |
I think I've answered all your comments @sphuber, there is just the outstanding issue of the |
Maybe in theory it could be possible, but it is not clear that we always can. The config may be more lenient with allowing additional keys, and so having downgrades not being a full undo of an upgrade, but to me it is not clear that with the PostgreSQL database we have the same luxury. Besides, it would mean an even greater development load by forcing us to implement and test the downgrade of each migration, which would also be non-trivial. In any case, the majority of migrations at this moment don't have downgrades, so those would have to be written first. But I really don't think we should go down this road. |
well, I'd not all of the sqlalchemy migrations have at least some form of downgrade, which we rely on for the migration testing (you have to migrate down, before you can migrate up) but no I'm not suggesting we put much more effort into supporting this |
Ok this should be good to go @sphuber |
aiida/cmdline/commands/cmd_config.py
Outdated
|
||
@verdi_config.command('downgrade') | ||
@click.argument('version', type=int) | ||
@click.option( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct me if I am wrong, but I don't think you answered my question yet why we need the option to specify an arbitrary input and output file. Since this is user facing it should simply always operate on the currently configured config file. I would suggest to remove this additional complexity since I don't think it is needed for now and you don't have tests for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
aiida/cmdline/commands/cmd_config.py
Outdated
|
||
|
||
@verdi_config.command('downgrade') | ||
@click.argument('version', type=int) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this a type=click.Choice
and get the available numbers dynamically from the available migrations? That would make it a lot better from a UI perspective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @chrisjsewell . I am approving so we can merge this, but I did still wanted to note that because the writing of the config in the downgrade
command now goes outside of the Config
class, there will be no automatic backup created. Maybe this is something we want to add in the future to prevent losing a configuration if the downgrade were to ever be incorrect.
Allow for both upgrades and downgrades, and expose this in the CLI.
This will allow a route for user to downgrade their configuration,
if they try a new version of aiida, but then want to return to an old version.