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

Create and apply patch when adding labels to API objects #687

Merged
merged 3 commits into from
Jun 19, 2018

Conversation

nkubala
Copy link
Contributor

@nkubala nkubala commented Jun 15, 2018

This changes the labeling code to apply patches to kubernetes API objects instead of updating them. This should cause skaffold to correctly identify when an object has been modified, preventing it from recreating the objects on each deploy.

UPDATE: I went ahead and refactored out the unwieldy switch statement to remove most of the boilerplate. Instead, the main loop uses two maps of object types to functions that expose the necessary requirements to make the control flow generic. These maps are

  • objectMetas, used to retrieve a function that returns a metav1.ObjectMeta
  • patchers, used to retrieve a function that uses the corresponding typed client to apply a patch

Still fighting with the dynamic client, so I'll (hopefully) send that in another PR.

Fixes #681

pods := client.CoreV1().Pods(retrieveNamespace(res.Namespace, p.ObjectMeta))
_, err = pods.UpdateStatus(p)
apiObject := modifiedObj.(*corev1.Pod)
addSkaffoldLabels(labels, &apiObject.ObjectMeta)
Copy link
Contributor

Choose a reason for hiding this comment

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

can we just access the object meta directly? Even if its just assuming that its in the untyped yaml at root -> metadata

addSkaffoldLabels(labels, &apiObject.ObjectMeta)
modifiedJSON, _ := json.Marshal(modifiedObj)
p, _ := patch.CreateTwoWayMergePatch(originalJSON, modifiedJSON, apiObject)
_, err = client.AppsV1().ReplicaSets(retrieveNamespace(res.Namespace, apiObject.ObjectMeta)).Patch(apiObject.Name, types.StrategicMergePatchType, p)
Copy link
Contributor

Choose a reason for hiding this comment

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

What was the problem using the dynamic client here? I thought that was working?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

some of it works, but there are a few types that the version I'm using needs that are incompatible with other dependency versions we already have vendored. tl;dr it's a dep nightmare, I'll work through it eventually

addSkaffoldLabels(labels, &d.ObjectMeta)
deployments := client.AppsV1beta2().Deployments(retrieveNamespace(res.Namespace, d.ObjectMeta))
_, err = deployments.Update(d)
apiObject := modifiedObj.(*appsv1beta2.Deployment)
Copy link
Contributor

Choose a reason for hiding this comment

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

At this point it might make sense to reduce this switch statement to lower the boilerplate. One idea is a map (or two maps) of type (appsv1beta2.Deployment) -> functions.

One function could be "apiObjectGetter", which does the type conversion, and the other could do the Patch itself.

Then this switch statement is a lookup of type to functions, then calls those functions. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, I agree I should have addressed this before. just refactored it, I'll detail in the top-level comment

// objectMeta is responsible for returning a generic runtime.Object's metadata
type objectMeta func(runtime.Object) *metav1.ObjectMeta

var converters = map[objectType]converter{
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: could you collapse converter and objectmeta to one function that returns ok and objectmeta?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah let me try that

Copy link
Contributor

@dgageot dgageot left a comment

Choose a reason for hiding this comment

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

@nkubala I still see the warnings: Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply

Copy link
Contributor

@dgageot dgageot left a comment

Choose a reason for hiding this comment

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

No, in fact, it seems much better. Let me merge that!

@dgageot dgageot merged commit 36eacbc into GoogleContainerTools:master Jun 19, 2018
@nkubala nkubala deleted the label_fix branch June 19, 2018 17:37
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