-
Notifications
You must be signed in to change notification settings - Fork 169
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
Allow inline environments to be pruned #511
Conversation
Nice! This indeed enables the feature, but there is a bit more to it which is very subtle. Label uniqueness
tanka/pkg/spec/v1alpha1/environment.go Lines 48 to 50 in a43a839
This works fine for static environments, because they have their name generated based on their path on disk. Inline environments however permit any user-given name, and instead use the This means to generate an unique label above function would need to include information from both Update: The new label could look something like Environment uniquenessCurrently it is possible to define two inline environments of the same name in the same file. This is merely an oversight and not a guaranteed feature, but it breaks above uniqueness (again). Given this increase in complexity, let us know whether you are still interested in doing this. Of course we would be there to assist if you wanna do it yourself :) |
Thanks for the quick reply @sh0rez!
Am I right to assume you mean I want to make sure I understand the problem you go on to describe, with prune not being currently able to guarantee that it will not delete the "wrong" resources. A scenario I can think of that could cause this:
By making the path-on-disk part of the prune label, we'd avoid the scenario above. That makes sense. Whether we change the value of
I think I understand you, are you saying that this is an invalid state that we should guard against? If so, that makes sense: a tk-eval tree with 2 tanka.Environments with the same metadata.name should not be valid. This is different from the scenario I describe above. If I've indeed got the right end of the stick, I'm happy to add to this PR 👍 |
Concatenating paths on disk and environment names might commonly come close to the k8s 63 character limit on label values. Wdyt of |
I actually meant // static env at /environments/default
{
kind: "Environment",
metadata: {
name: "environments/default",
namespace: "environments/default/main.jsonnet"
}
}
// inline env at /environments/default
{
kind: "Environment",
metadata: {
name: "whateverYouChose",
namespace: "environments/default/main.jsonnet"
}
}
// inline env at /environments/default/foo.jsonnet
{
kind: "Environment",
metadata: {
name: "whateverYouChose",
namespace: "environments/default/foo.jsonnet"
}
} So namespace always holds the path to the file that was used as the entrypoint. For static envs, name also holds the path to the directory the entrypoint is enclosed in.
That scenario is exactly what I had in mind.
Totally! It wouldn't be too bad though. If newer Tanka versions would start to use different label values, the worst thing that could happen is that they would miss resources created by previous versions and not yet re-applied. Same for older versions, they would miss resources by newer versions. afaict no resources would falsely be deleted. a tk-eval tree with 2 tanka.Environments with the same metadata.name should not be valid. This is different from the scenario I describe above. Yup it's different, but it would lead to equal name+namespace, but we should disallow it anyways.
We thought of this option before, sounds reasonable. If we are going to break anyways, then yeah, let's fix both issues I hope that clarifies it enough for you to get started. Let me know if anything isn't clear yet |
Ah ha, the part I was missing was that metadata.Namespace already contains the path on disk: Lines 41 to 55 in a43a839
I think I have enough info to get started, and thanks again 👍 |
Break one thing, fix two. Sounds like a win to me. :) I did some work towards this in #433, please have look, might want to steal some ideas. |
324c4d1
to
50a412d
Compare
By adding the name field to the prune flags. This just works due to environment loading logic being shared across subcommands. Base NameLabel on both namespace and name. The namespace of inline environments includes the path on disk, and multiple environments with the same given name cannot be loaded from the same path on disk, so the tuple of these 2 fields is guaranteed to be unique. Use a truncated hash of a combination of these 2 fields to form a label that is guaranteed to fit in Kubernetes' 63 character limit for label values. This fixes a bug in which 2 inline environments with identical metadata.Name, applied separately from 2 paths on disk to the same Kubernetes namespace would create resources with identical `tanka.dev/environment` labels, and so pruning one release would delete the resources of the other. When upgrading to this tanka version, environments with spec.injectLabels=true will show diffs on the `tanka.dev/environment` label, and prune-diffs will run clean, even if prune-able resources were previously visible. After applying the label change, the previously prune-able resources should be prune-able. Add test case for the "don't load multiple envs" assertion. Signed-off-by: Craig Furman <[email protected]>
50a412d
to
2fc6af7
Compare
return strings.Replace(m.Name, "/", ".", -1) | ||
partsHash := sha256.Sum256([]byte(fmt.Sprintf("%s:%s", m.Name, m.Namespace))) | ||
chars := []rune(hex.EncodeToString(partsHash[:])) | ||
return string(chars[:48]) |
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.
there's no science at all to my choice here of 48 🤷♂️
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.
From what I see this all looks very nice! LGTM
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.
🎆 Looks great. The diff will be rather big on our internal environments and we'd need to communicate this well but it is totally worth fixing this hurdle properly. Thank you!
Nice one, thanks for reviewing this. I plan to start using this at GitLab pretty soon. |
By adding the name field to the prune flags. This just works due to
environment loading logic being shared across subcommands.
Base NameLabel on both namespace and name. The namespace of inline
environments includes the path on disk, and multiple environments with
the same given name cannot be loaded from the same path on disk, so the
tuple of these 2 fields is guaranteed to be unique.
Use a truncated hash of a combination of these 2 fields to form a label
that is guaranteed to fit in Kubernetes' 63 character limit for label
values.
This fixes a bug in which 2 inline environments with identical
metadata.Name, applied separately from 2 paths on disk to the same
Kubernetes namespace would create resources with identical
tanka.dev/environment
labels, and so pruning one release would deletethe resources of the other.
When upgrading to this tanka version, environments with
spec.injectLabels=true will show diffs on the
tanka.dev/environment
label, and prune-diffs will run clean, even if prune-able resources were
previously visible. After applying the label change, the previously
prune-able resources should be prune-able.
Add test case for the "don't load multiple envs" assertion.
Fixes #510