-
-
Notifications
You must be signed in to change notification settings - Fork 751
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
Modify API to remove related files on delete of actions/workflows #5304
Modify API to remove related files on delete of actions/workflows #5304
Conversation
What issue does this PR relate to? This is a big conceptual shift to StackStorm as a whole since the API does not create/modify or delete files in a pack because it is not authoritative, git is. This change would break the fundamental premise of infrastructure as code and would have changes reverted on the next package upgrade creating a lot of confusion for the lay user. |
I think this is related to adding delete functionality into the UI, so the reverse of the workflow composer + that creates a new workflow on disk and in the live pack. However altering the current behaviour of the endpoint might not be the best course of action, as those already using the DELETE endpoint might rely on the fact it deletes from memory and not disk. So I wonder if it should have at least a new parameter to the call that the UI calls, that allows the default behaviour to be unchanged. The create does at the moment creates files if its passed the data_files parameter - which I presume is sent from the UI. |
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.
A few nitpicks that need to be cleaned up.
Also, this code will explode if two different worker processes try to remove the same pack at almost the same time, or if the process cannot remove the files for some reason (eg: permissions issues). Please wrap them in a try/catch block to ignore exceptions where the file is already deleted, and to write a log error if the process doesn't have permission to delete the file.
Just (hopefully) clarify a few points here.
This is true, but removing the entire pack directory,
As far as I'm aware, the workflow composer does not write the action metadata and workflow file out to disk, it only stores them in the database. The overall problem here is that StackStorm allows workflows to be created three different ways:
File management is one of the integration points that the workflow composer/designer lacks. |
@blag - agree with most of your points. I am pretty sure it does write to disk on the composer. It certainly updates the files on edit - as have copied the modified files from the "live" file system to my gitrepo before. There is logic in the modified file to write the data files out on the api create. st2/st2api/st2api/controllers/v1/actions.py Lines 129 to 135 in f507d2e
Rules - get written directly to database and not to file (by the UI), but I believe workflows get written to disk and to database - which is inconsistent!!! |
This is related to delete of action/workflows in general. The current delete operation via API (invoked from CLI or UI related to StackStorm/st2web#898) just deletes the database registration. If operator does a reload, the action/workflow that was deleted just gets registered to the database again. If user manages infra and packs with codes, I don't think this affects or changes that paradigm. They can still manage and load packs and actions thru git, puppet, chef, containers, or which ever way they automate their infra. The target audiences for this change here are mostly action/workflow developers that is using an instance of StackStorm for development to delete an action/workflow. For consistency sake, I would suggest making changes so that rule creation also writes content to disk. |
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.
- Please update the description. The description should explain why you are making this change and how is the change going to work.
- Please make sure there are unit tests that cover the change.
- Can we add a confirmation prompt in the CLI to let user know that the operation will delete files and user can OK or back out of the operation?
Co-authored-by: blag <blag@users.noreply.github.com>
Co-authored-by: blag <blag@users.noreply.github.com>
Sure, I will do the suggested changes. Thanks. |
@m4dcoder Sure, I will write the unit test to cover the made changes. And I will also work on asking for confirmation prompt in the CLI to let user know removal of files to proceed with users agreement or to back out the operation. Thanks |
@m4dcoder if we are going to issue a warning on the CLI and print for confirmation, could we also add a --yes or similar so that you can confirm it on the command line - to make it easier for anyone scripting the cli calls. |
Added try except block for handling PermissionError while removing action files from disk. Also, code is added for logging errors.
Added code to add a confirmation prompt in CLI to let user know that the operation will delete files on disk as well. If user says OK then to proceed otherwise to back out the operation.
@blag I have added try except block for handling PermissionError while removing action files from disk. Also, code is added for logging errors. Please review. Thanks. |
@m4dcoder I have added code to add a confirmation prompt in CLI to let user know that the operation will delete files on disk as well. If user says OK then to proceed otherwise to back out the operation. Please review. Thanks. |
@@ -735,16 +736,29 @@ def __init__(self, resource, *args, **kwargs): | |||
def run(self, args, **kwargs): | |||
resource_id = getattr(args, self.pk_argument_name, None) | |||
instance = self.get_resource(resource_id, **kwargs) | |||
self.manager.delete(instance, **kwargs) | |||
if isinstance(instance, st2client.models.action.Action): |
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.
Is it possible to have a cli argument like --yes so that it is possible to delete actions within having to give input. This makes it much easier for anyone using st2 cli in scripts.
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.
I agree, giving the option -y
or --yes
makes this scriptable.
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.
Also, you should move this changes to the ActionDeleteCommand at /~https://github.com/StackStorm/st2/blob/master/st2client/st2client/commands/action.py#L280 instead of using if isinstance to check if this resource is an Action.
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.
@amanda11 Sure, I will add functionality to have CLI argument --yes or -y. Thanks.
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.
Where are the unit tests?
) | ||
action_metadata_file_path = os.path.join( | ||
BASE_PATH, "packs", pack_name, metadate_file | ||
) |
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.
The pack base path can be overridden (ref: https://docs.stackstorm.com/packs.html#under-the-hood-pack-basics). Therefore, it is better to use get_pack_base_path @ /~https://github.com/StackStorm/st2/blob/master/st2common/st2common/content/utils.py#L135 to determine the pack file path.
action_metadata_file_path, | ||
e, | ||
) | ||
|
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 you create a function at /~https://github.com/StackStorm/st2/blob/master/st2common/st2common/services/packs.py to delete the action entrypoint and action metadata files? Move the path calculation that you did above into this function as well.
@@ -735,16 +736,29 @@ def __init__(self, resource, *args, **kwargs): | |||
def run(self, args, **kwargs): | |||
resource_id = getattr(args, self.pk_argument_name, None) | |||
instance = self.get_resource(resource_id, **kwargs) | |||
self.manager.delete(instance, **kwargs) | |||
if isinstance(instance, st2client.models.action.Action): |
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.
I agree, giving the option -y
or --yes
makes this scriptable.
@@ -735,16 +736,29 @@ def __init__(self, resource, *args, **kwargs): | |||
def run(self, args, **kwargs): | |||
resource_id = getattr(args, self.pk_argument_name, None) | |||
instance = self.get_resource(resource_id, **kwargs) | |||
self.manager.delete(instance, **kwargs) | |||
if isinstance(instance, st2client.models.action.Action): |
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.
Also, you should move this changes to the ActionDeleteCommand at /~https://github.com/StackStorm/st2/blob/master/st2client/st2client/commands/action.py#L280 instead of using if isinstance to check if this resource is an Action.
Moving path calculations and action file remove related code to st2common/services/packs.py
Added `--y` option for action delete command at CLI to make command scriptable
Unit test for newly added code in /st2common/services/packs.py
…pement-changed' section
…pdating message to return in case of failure in deleting action files
… path instead of string concatenation. Adding docstring for test classes to describe specificness.
… to remove duplication.
|
@amanda11 CHANGELOG for modify action delete API has moved to your suggested location. Please review. Thanks. |
@cognifloyd The try/except blocks have been placed one after another instead of nesting as per your suggestion. I had made the changes according to @m4dcoder's suggestions. Docstrings are added in test classes to clear specificness of the unit tests in st2common/tests/unit/services/test_packs.py. Please review. Thanks. |
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 for the updates - my points have all been addressed. Much appreciated.
|
||
# asserting delete_action_files_from_pack function raises exception | ||
with self.assertRaises(Exception): | ||
delete_action_files_from_pack(TEST_PACK, entry_point, metadata_file) |
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.
@mahesh-orch You missed this one I think
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.
I would make some changes, but it's nothing serious.
action_metadata_file_path, | ||
e, | ||
) | ||
if os.path.isfile(action_metadata_file_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.
This check is probably redundant, since if os.remove()
fails it will throw some sort of exception.
e, | ||
) | ||
if os.path.isfile(action_metadata_file_path): | ||
msg = 'The action file "{0}" could not be removed from disk, please check the logs or ask your StackStorm administrator to check and delete the actions files manually'.format( |
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.
I'm kind of surprised our linting is not catching this long line.
action_entrypoint_file_path, | ||
e, | ||
) | ||
msg = 'The action file "{0}" could not be removed from disk, please check the logs or ask your StackStorm administrator to check and delete the actions files manually'.format( |
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.
I'm kind of surprised that our linting is not catching this long line.
…h and fixing long line msg
…d name for error msg assertions
@blag I have done your suggested changes. Also, done similar changes in other files. Please review. |
This PR failed to provide sufficient options to remove a database entry without touching the files on disk
Going on step further, why break existing behaviour when we don't have to? Remove the --force option, and create the option |
Digging into this change a little more: I triggered a corner case that isn't handled correctly. If there is a file access error, the database entry is deleted, leaving St2 in an inconsistent state. This operation should be atomic, if the file was requested to be removed and it fails, the database entry should not be removed.
Files
However, the action
|
The opposite applies for the default stackstorm-ha install where the packs filesystem is read-only, so deletes should only affect the db. |
I assume you mean for kubernetes. I run StackStorm HA on VMs and the packs are not on read-only filesystems. Regardless of which environment St2 is being run on, the code should be able to handle the situation in a generic and coherent way. |
@mahesh-orch @m4dcoder Please open a new PR to address the issues mentioned above. As it stands, this change prevents removing just the database entry. |
Could we get an issue raised and assign it to 3.6 milestone and 3.6 release project? The idea of making it configurable in st2.conf could address most of the issues,and probably requires changes to both api and cli and doc. |
This change is to remove related files of actions/workflows from disk when API called from CLI and web UI (StackStorm/st2web#898). Currently when this delete API is invoked then this only de-register the actions from database and when user reloads the st2 then these actions get registered into database again.