Conversation
|
|
||
| [NOTE] | ||
| ==== | ||
| The uninstall command deletes the namespace the demo was installed in. Therefore it is not possible to uninstall demos in the `default` namespace. |
There was a problem hiding this comment.
I feel like this should be opt-in behaviour. Or rather, if we created the namespace, it gets deleted.
There could be existing namespaces that shouldn't be deleted.
There was a problem hiding this comment.
One such example is if we have the monitoring stack installed, and want to add and remove demos.
There was a problem hiding this comment.
According to #187 (comment) "Update after a discussion on 2025-11-26:" it was decided the first version provides no option to be less destructive. Not sure which meeting that was or if it makes sense to change the requirements now.
There was a problem hiding this comment.
There were also problems with deleting everything without deleting the namespace, see stackabletech/hdfs-operator#761 (comment). So maybe for the first version / MVP it is fine for now like this? But feel free to disagree
There was a problem hiding this comment.
I left an idea below in how we could do it: #429 (comment)
But of course, if this implements what we agreed on, that's fine.
It does feel a little dangerous though.
There was a problem hiding this comment.
Yes, I agree it feels dangerous, tried to avoid it at first but ran into the problems above, which unfortunately won't be solved by your idea I think. The manifests we would delete with that approach were also deleted with the help of the labels, so would be the same situation, unless I misunderstood something 😞
Another thing might be adding a confirmation dialogue like the one I added to the installation for the namespace. That it asks if the user really wants to uninstall since that would delete the namespace, and cancel the deletion otherwise.
There was a problem hiding this comment.
0f3cf7f (this PR) Maybe this addresses your concern a bit, let me know what you think :)
|
|
||
| [NOTE] | ||
| ==== | ||
| The uninstall command deletes the namespace the stack was installed in. Therefore it is not possible to uninstall stacks in the `default` namespace. |
There was a problem hiding this comment.
Same as my comment about demos.
NickLarsenNZ
left a comment
There was a problem hiding this comment.
Left a couple of comments about namespace deletion.
| // Delete demo namespace | ||
| client | ||
| .delete_object( | ||
| &uninstall_parameters.demo_namespace, | ||
| &ApiResource::from_gvk(&GroupVersionKind { | ||
| group: "".to_owned(), | ||
| version: "v1".to_owned(), | ||
| kind: "Namespace".to_owned(), | ||
| }), | ||
| None, | ||
| ) | ||
| .await | ||
| .context(DeleteObjectSnafu)?; |
There was a problem hiding this comment.
Here's where I think we should have a check to see if the namespace was "owned" by the demo (via labels/annotations).
There was a problem hiding this comment.
One thing we could consider is reading in the demo, get the GVKs and Helm charts, and uninstall in reverse order before uninstalling the namespace (if it was created by the demo).
Same would apply for stacks.
That could be a follow-up PR, but I think at least we should be careful with namespace deletion.
| // Delete stack namespace | ||
| client | ||
| .delete_object( | ||
| &uninstall_parameters.stack_namespace, | ||
| &ApiResource::from_gvk(&GroupVersionKind { | ||
| group: "".to_owned(), | ||
| version: "v1".to_owned(), | ||
| kind: "Namespace".to_owned(), | ||
| }), | ||
| None, | ||
| ) | ||
| .await | ||
| .context(DeleteObjectSnafu)?; |
Techassi
left a comment
There was a problem hiding this comment.
Left a few comments and questions.
| // Delete demo namespace | ||
| client | ||
| .delete_object( | ||
| &uninstall_parameters.demo_namespace, | ||
| &ApiResource::from_gvk(&GroupVersionKind { | ||
| group: "".to_owned(), | ||
| version: "v1".to_owned(), | ||
| kind: "Namespace".to_owned(), | ||
| }), | ||
| None, | ||
| ) | ||
| .await | ||
| .context(DeleteObjectSnafu)?; |
There was a problem hiding this comment.
note: I think we should abstract that away in an associated function called delete_namespace similar to what we have to create a namespace. See:
stackable-cockpit/rust/stackable-cockpit/src/utils/k8s/client.rs
Lines 443 to 460 in 32cf847
There was a problem hiding this comment.
Any particular reason why we are not using Api<Namespace> instead? I guess one upside to to doing it like currently implemented is that we don't need to clone the client for a single function call.
| parameters.insert("STACK".to_owned(), stack_name.into()); | ||
| if let Some(demo_name) = demo_name { | ||
| parameters.insert("DEMO".to_owned(), demo_name.into()); | ||
| } |
There was a problem hiding this comment.
question: Just that we are on the same track: These are now added earlier and are part of the passed parameters, right?
question: Out of curiosity, what was the reason you did that? I assume the demo and stack name are needed earlier in the call chain now?
There was a problem hiding this comment.
I didn't add them in install_manifests because it seemed like this function is "outside of the scope of demos and stacks" and might be also used for something else. Along with the comment above that templating shouldn't be a concern here in the future. Since @sbernauer pulled that parameter addition from this PR while I was gone, I don't know what his thoughts were, we didn't coordinate. But I'm fine with also moving it back into install_manifests.
rust/stackablectl/src/cmds/demo.rs
Outdated
| let demo_namespace = tracing_indicatif::suspend_tracing_indicatif( | ||
| || -> Result<String, CmdError> { | ||
| if args.namespaces.namespace == DEFAULT_NAMESPACE { | ||
| if Confirm::new() | ||
| .with_prompt( | ||
| format!( | ||
| "Demos installed in the '{DEFAULT_NAMESPACE}' namespace cannot be uninstalled with stackablectl. Install the demo in the '{demo_namespace}' namespace instead?", | ||
| demo_namespace = args.demo_name.clone()) | ||
| ) | ||
| .default(true) | ||
| .interact() | ||
| .context(ConfirmDialogSnafu)? { | ||
| // User selected to install in suggested namespace | ||
| Ok(args.demo_name.clone()) | ||
| } else { | ||
| // User selected to install in default namespace | ||
| Ok(args.namespaces.namespace.clone()) | ||
| } | ||
| } else { | ||
| Ok(args.namespaces.namespace.clone()) | ||
| } | ||
| }, | ||
| )?; |
There was a problem hiding this comment.
note: Well that's a mouthful to read. Can we somehow make this easier to grasp?
There was a problem hiding this comment.
Maybe I looked at the code too long at this point and unable to see it, but could you give me more information on what is making it hard to grasp. At least I currently don't know how to make it shorter. Or are there explanations missing somewhere? Or just the whole "formatting" of it?
There was a problem hiding this comment.
0f3cf7f (this PR) Tried rearranging it a bit, let me know if know if that makes it any better
There was a problem hiding this comment.
I don't feel like it does make it better, sorry 🙈
What might help on the other hand is to define the closure outside of the tracing_indicatif::suspend_tracing_indicatif call.
If that also doesn't help, we can leave it as is.
This reverts commit 7dfe50e.
Co-authored-by: Techassi <git@techassi.dev>
Techassi
left a comment
There was a problem hiding this comment.
Only a few small comments left, mostly looks nice!
|
|
||
| for object in object_list { | ||
| if let Some(value) = object.labels().get(&label.key().to_string()) { | ||
| if value.eq(&label.value().to_string()) { |
There was a problem hiding this comment.
note: We could potentially use deref here to save an allocation.
| if value.eq(&label.value().to_string()) { | |
| if value.eq(label.value().deref()) { |
| }; | ||
|
|
||
| for object in object_list { | ||
| if let Some(value) = object.labels().get(&label.key().to_string()) { |
There was a problem hiding this comment.
note: This is kinda cumbersome to use, but could be improved by stackabletech/operator-rs#1182 (if we decide to move forward with it).
| }, | ||
| )?; | ||
| } | ||
| ManifestSpec::PlainYaml(_) => {} |
There was a problem hiding this comment.
Ah yeah, didn't even remember this ADR. I think the current approach is fine, but slightly harder to wrap your head around, because we delete different things in different places.
If we would handle deletions of manifests here, the "source of deletion" is more focused (at least that is my current impression). We could then finalize the deletion by deleting the namespace.
If we decide to keep it as is, a comment should definitely be added here.
| capability.supports_operation(discovery::verbs::LIST) | ||
| && match namespace { | ||
| Some(_) => capability.scope == kube::discovery::Scope::Namespaced, | ||
| None => capability.scope == kube::discovery::Scope::Cluster, | ||
| } |
There was a problem hiding this comment.
What do you think about renaming scope_matching to capability_scope_matches?
Description
Part of #187
This PR adds the
uninstallsubcommands todemoandstackcommands. It implements the MVP features mentioned here #187 (comment)The flag of skipping operators and CRD deletion was optional and I wasn't sure about the naming or if needs to be one command or two. Can also be just removed, added it because it was not much additional work.
Tested with all current demos/stacks. Some demos have edge cases in the deletion, will document that in the parent issue.
This PR also contains thestripped out into #432DEMO/STACKparameter addition for stackabletech/demos#374 (comment)Definition of Done Checklist
Author
Reviewer
Acceptance