Skip to content

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

Merged
dgageot merged 3 commits intoGoogleContainerTools:masterfrom
nkubala:label_fix
Jun 19, 2018
Merged

Create and apply patch when adding labels to API objects#687
dgageot merged 3 commits intoGoogleContainerTools:masterfrom
nkubala:label_fix

Conversation

@nkubala
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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