Skip to content
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

[k8s] Fix list merging in merge_k8s_configs #4762

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

romilbhardwaj
Copy link
Collaborator

Repro: a config.yaml with a single allowed_context would be read as multiple contexts:

# ~/.sky/config.yaml
kubernetes:
  allowed_contexts:
    - myctx
$ sky check
...
D 02-19 15:23:45 config_utils.py:146] User config: kubernetes.allowed_contexts -> ['myctx', 'myctx']
...
🎉 Enabled clouds 🎉
  GCP
  Kubernetes
  Allowed contexts:
    ├── myctx
    └── myctx

Our k8s dict merge logic would extend lists instead of adding only unique elements. This PR fixes it.

Comment on lines 202 to 211
# For other list values, merge lists and maintain uniqueness.
# Preserve the order - first list is the base_config list, and
# the second list is the override list. This is required for
# order sensitive lists like allowed_contexts.
seen = set(base_config[key])
# Append new items from override in-place while preserving order
for item in value:
if item not in seen:
seen.add(item)
base_config[key].append(item)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would there a case that same values are expected in the list?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No such cases that I could think of - most list fields in k8s are designed to hold unique items (e.g.,, container definitions, imagePullSecrets, volume names, etc.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, some list like commands and args should be considered as atomic value

# Preserve the order - first list is the base_config list, and
# the second list is the override list. This is required for
# order sensitive lists like allowed_contexts.
seen = set(base_config[key])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that the list items are dicts (unhashable)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yeah good point - I was thinking they'd be covered in the special casing above (e.g., volumes), but realized there may be other keys and it's good to be general. Simplified the logic here to also work with dicts.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also added relevant test cases.

# new item not already present.
result = list(base_config[key])
for item in value:
if item not in result:
Copy link
Collaborator

@aylei aylei Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A list might be treated as map in kubernetes (https://kubernetes.io/docs/reference/using-api/server-side-apply/#merge-strategy), in this case the equality check should be based on the listMapKey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants