Update pool handler to improve unloading & deleting pools#168
Update pool handler to improve unloading & deleting pools#168rc4 wants to merge 5 commits intostrongswan:masterfrom
Conversation
1. Try to unload the pool, 2. If vici unloaded the pool successfully, delete it from the DB 3. If the delete from DB failed, reload the pool with vici, and throw an error 4. Name/number of connections using the pool added to error message.
|
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @rc4 on file. In order for us to review and merge your code, please contact the project maintainers via info@strongswan.org to get yourself added. |
|
@cla-bot check Thanks.
Not sure that's a good idea as we probably want to remove the pool from the database (it's what the user requested) even if the daemon currently doesn't have it loaded.
Hm, isn't it the opposite? Or maybe the description is a bit unclear.
As mentioned above, the deletion from the database should probably be performed regardless of whether the daemon has the pool currently loaded or not. Actually, I think the behavior in diff --git a/strongMan/apps/pools/views/EditHandler.py b/strongMan/apps/pools/views/EditHandler.py
index 34560d16d3ab..7d27a26d6607 100644
--- a/strongMan/apps/pools/views/EditHandler.py
+++ b/strongMan/apps/pools/views/EditHandler.py
@@ -64,13 +64,13 @@ class EditHandler(object):
def delete_pool(self, vici):
vici_poolname = {'name': self.poolname}
try:
- vici.unload_pool(vici_poolname)
self.pool.delete()
+ vici.unload_pool(vici_poolname)
messages.add_message(self.request, messages.SUCCESS, "Pool deletion successful.")
except ViciException as e:
messages.add_message(self.request, messages.ERROR,
- 'Unload pool failed: ' + str(e))
+ 'Pool deleted but unload failed: ' + str(e))
except ProtectedError:
messages.add_message(self.request, messages.ERROR,
'Pool not deleted. Pool is in use by a connection.')
|
|
The cla-bot has been summoned, and re-checked this pull request! |
This just prevents the exception when trying to unload an already-unloaded pool. It will still be deleted from the DB if this happens (as there is no exception now).
Previously it passed
I was under the (perhaps mistaken!) impression that the DB should reflect the state of the pools - so, if the pool is already unloaded, or was unloaded successfully - delete from the DB. If the pool can't be unloaded, then keep it in the DB (i.e. it's in-use still and needs to not be in use to be unloaded). Then, if unloading succeeded, but the deletion from the DB failed, it should be re-loaded so we don't end up with an inconsistent state - but this perhaps okay? Basically my thought was that there should only be 2 possible outcomes:
|
Ah, right, that code is in the actual VICI wrapper. But that might not be the best location for it (it's mostly intended as simple wrapper around the VICI socket, and this adds overhead and might not be what a caller expects - there is only one caller I suppose, but still). I guess the check could be moved to
Right, I somehow saw this as the entrypoint into the whole thing.
I had another look and there are actually two "in-use" states that can prevent deleting/unloading a pool. In the database, pools can't be deleted if they are still referenced by a connection. However, that's something the daemon doesn't know about (there is no hard link between configs and pools, this happens dynamically at runtime). So it's possible that unloading a pool works, while connections are still referencing it (that's what I based my suggestion on above). On the other hand, and that's what I overlooked, in the daemon, a pool can't be unloaded if there are currently online leases assigned to established IKE SAs. That's in turn something strongMan isn't aware of. Connections can actually be unloaded/deleted even though there are currently active SAs in the daemon (that's not the case with the pools). So it's possible that the database constraint isn't in effect, because the connection is already deleted, but a pool still can't be unloaded because of online leases by still established SAs. So yes, my suggestion above is not ideal in regards to the latter case as the pool can't be unloaded later if it's already gone from the database. I guess strongMan could check for active leases itself by passing e.g. But maybe using a diff --git a/strongMan/apps/pools/views/EditHandler.py b/strongMan/apps/pools/views/EditHandler.py
index 34560d16d3ab..226212acca20 100644
--- a/strongMan/apps/pools/views/EditHandler.py
+++ b/strongMan/apps/pools/views/EditHandler.py
@@ -6,6 +6,7 @@ from ..forms import AddOrEditForm
from strongMan.apps.pools.models import Pool
from strongMan.helper_apps.vici.wrapper.exception import ViciException
from strongMan.helper_apps.vici.wrapper.wrapper import ViciWrapper
+from django.db import transaction
from django.db.models import ProtectedError
@@ -64,9 +65,11 @@ class EditHandler(object):
def delete_pool(self, vici):
vici_poolname = {'name': self.poolname}
try:
- vici.unload_pool(vici_poolname)
- self.pool.delete()
- messages.add_message(self.request, messages.SUCCESS, "Pool deletion successful.")
+ with transaction.atomic():
+ self.pool.delete()
+ if self.poolname in vici.get_pools(vici_poolname):
+ vici.unload_pool(vici_poolname)
+ messages.add_message(self.request, messages.SUCCESS, "Pool deletion successful.")
except ViciException as e:
messages.add_message(self.request, messages.ERROR, |
That's a good idea - I was wondering about an approach like this but I'm admittedly pretty new to django so wasn't sure how transactions worked with it. I like this approach more. I also took the liberty of renaming the wrapper parameter from How does this look? |
tobiasbrunner
left a comment
There was a problem hiding this comment.
Looks good, thanks for the update. Could you please squash the commits. Maybe put the renaming of the argument in one and the changes in delete_pool in another (with some updated commit messages, in particular, start with an uppercase letter). I've also added some comments.
| self.request, | ||
| messages.ERROR, |
There was a problem hiding this comment.
Please put these arguments on the same line.
| messages.add_message( | ||
| self.request, messages.SUCCESS, "Pool deletion successful." | ||
| ) |
There was a problem hiding this comment.
This should still fit on a single line (we use a max line length of 109 in this project, see .flake8).
| messages.add_message( | ||
| self.request, messages.ERROR, "Unload pool failed: " + str(e) | ||
| ) |
There was a problem hiding this comment.
This should also fit on one line, or you can leave it as it was before (i.e. the message aligned with the opening bracket).
| messages.add_message( | ||
| self.request, | ||
| messages.ERROR, | ||
| f"Pool not deleted! In use by {len(names)} connection(s): {', '.join(names)}", |
There was a problem hiding this comment.
There is a stray comma at the end of this line. And to align a bit more with the rest of the code, maybe put the closing bracket on this line instead of a separate one. I'm fine with the indentation and not having arguments on the first line (seems to be what PEP 8 recommends anyway when not aligning with the opening bracket).
Updated the Vici wrapper to check if a pool is loaded with
get_pools()before attempting to unload it. Prevents error when attempting to unload an already-unloaded pool. I also updated the wrapper to just take the name of the pool to unload instead of needing a dict.Update the pool EditHandler to:
ProtectedError(i.e. in use by a connection), print the number/name of connections using said pool.