Skip to content

Adding the core migrator that rewrites objects of a single resource type #3

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

Merged
merged 4 commits into from
Oct 11, 2018

Conversation

caesarxuchao
Copy link
Member

@caesarxuchao caesarxuchao commented Sep 14, 2018

The core migrator lists a chunk of objects, GET&PUT each of them, then continue with the next chunk.

The code more or less resembles the oc admin migrate storage code. A small improvement is that the migrator uses the inconsistent continue token sent by the apiserver in case the original list is compacted. So the migrator doesn't have to finish migrating a resource type in the etcd compaction window (5 mins by default).

@k8s-ci-robot k8s-ci-robot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Sep 14, 2018
@caesarxuchao caesarxuchao force-pushed the init branch 2 times, most recently from 48f6c3e to bfff573 Compare September 18, 2018 00:38
@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 18, 2018
@caesarxuchao caesarxuchao reopened this Sep 19, 2018
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Sep 20, 2018
@caesarxuchao
Copy link
Member Author

/assign @yliaog for initial review

@caesarxuchao caesarxuchao changed the title [WIP] add the core migrator that rewrites objects of a single resource type Adding the core migrator that rewrites objects of a single resource type Sep 21, 2018
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 21, 2018
@krzyzacy
Copy link

/assign @yliaog

@k8s-ci-robot
Copy link
Contributor

@krzyzacy: GitHub didn't allow me to assign the following users: yliaog.

Note that only kubernetes-sigs members and repo collaborators can be assigned.
For more information please see the contributor guide

In response to this:

/assign @yliaog

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@yliaog
Copy link

yliaog commented Sep 25, 2018

/assign @yliaog

@deads2k
Copy link

deads2k commented Sep 25, 2018

I see the oc migrate command switched to using unstructured client. It saved a GET request per object. But the unstructured client only supports json, which is less efficient than proto. I'm not sure if it's a net-win, so I didn't incorporate the change.

It wasn't so much about saving a GET as it was about gaining reliability, readability, and being fully schema agnostic. By using the dynamic client, we're certain that our conversion will work for any type regardless of whether it's known. I'll also note that if we had already split client-go into k8s.io/api specific and generic, we'd prefer to use the dynamic client.

This is an infrequently run command, proto versus json isn't hugely important.

Now after having written all this, I've realized that the other thing is that if you wire up something to accept proto, you won't be able to easily get namespaces and names and if you aren't carefully it will decode and strip unknown fields.

@caesarxuchao
Copy link
Member Author

@yliaog I intentionally removed all the imports to make review easier.

// creating a working serializer.
// We don't use dynamic client because it only supports json, which
// increases the memory usage of the apiserver. When we support
// migrating CRD or aggregated apis, we need to plumb in a dynamic
Copy link

Choose a reason for hiding this comment

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

s/plumb/plug/ ?

namespaceScoped: namespaceScoped,
client: client,
progress: &dummyProgress{},
concurrency: 5,
Copy link

Choose a reason for hiding this comment

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

why hard code it here? if no plan to change it, better make it a const

@nikhita nikhita mentioned this pull request Sep 25, 2018
@caesarxuchao
Copy link
Member Author

it was about gaining reliability, readability, and being fully schema agnostic

Agree. With the current typed clients I'll have to worry about version skews.

@deads2k, I'm a little bit concerned if the roundtrip of data->unstructured->data is loss less. Are we 100% confident? If the dynamic client supports GetRaw() it's more reassuring.

return ErrNotRetriable{err}
case errors.IsConflict(err):
return ErrRetriable{err}
case errors.IsServerTimeout(err):
Copy link

Choose a reason for hiding this comment

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

what about TooManyRequests? seems to be a retriable

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

if err == nil {
break
}
if canRetry(err) {
Copy link

Choose a reason for hiding this comment

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

no backoff?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added backoff if the error suggests "retry after" seconds. General backoff is handled by the RESTClient's built-in rate limiter.

for {
list, listError := m.list(
&metav1.ListOptions{
Limit: 500,
Copy link

Choose a reason for hiding this comment

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

all const better defined at the beginning of the package

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

@deads2k
Copy link

deads2k commented Sep 26, 2018

@deads2k, I'm a little bit concerned if the roundtrip of data->unstructured->data is loss less. Are we 100% confident?

Yes. We are very sure. It decodes to map[string]interface{} and goes out the same way.

// TODO: The oc migrator tried to count if the update causes changes.
// To do so it needs to decode the PUT response and extract the
// resourceVersion.
return m.get(namespace, name)
Copy link

Choose a reason for hiding this comment

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

so if there is a conflict, this will return what's stored without retry, but it is possible what's stored there is still the old version

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bug. I fixed the logic. I'll add unit test when the dynamic client is fixed.

func newPods(num int) []v1.Pod {
var list []v1.Pod
func newPodList(num int) v1.PodList {
var pods []v1.Pod
for i := 0; i < num; i++ {
pod := newPod(fmt.Sprintf("pod%d", i), fmt.Sprintf("namespace%d", i))
Copy link

Choose a reason for hiding this comment

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

is it worthwhile to test the nil or empty namespace case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added.

@caesarxuchao caesarxuchao force-pushed the init branch 4 times, most recently from 8a0db3c to 7c075cd Compare October 1, 2018 18:07
@caesarxuchao
Copy link
Member Author

PTAL @yliaog. Thank you!


// try tries to migrate the single object by PUT. If the PUT fails due to
// conflicts, the function requests next try to GET the new object. If the GET
// failed, the function requests the next try to GET the new object.
Copy link

Choose a reason for hiding this comment

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

If the GET failed, and the error is retriable, then it requests next try to GET the new object

Copy link
Member Author

Choose a reason for hiding this comment

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

Discussed offline. Updated.

@yliaog
Copy link

yliaog commented Oct 3, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 3, 2018
@caesarxuchao
Copy link
Member Author

Thanks @yliaog.

@deads2k @lavalamp for this repository, do you want to review every changes or do you want to checkpoint from time to time?

Chao Xu added 3 commits October 3, 2018 17:15
dep doesn't parse the Godeps.json in the dependencies, so this has
potential problems. I tried glide as well, it doesn't work out-of-box,
and it hasn't been updated since the end of 2017. I'll use dep as
long as it works
@k8s-ci-robot k8s-ci-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Oct 4, 2018
@caesarxuchao
Copy link
Member Author

Let's get this one merged. We can fix issues in later iterations.

@yliaog could you re-apply the lgtm? I only added the dependencies after you lgtm'ed it last time.

@yliaog
Copy link

yliaog commented Oct 11, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 11, 2018
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 11, 2018
@caesarxuchao
Copy link
Member Author

@lavalamp @deads2k could you approve the change?

I corrected the name in the OWNER file in the last commit, so myself becomes an approver.

@lavalamp
Copy link

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: caesarxuchao, lavalamp

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 11, 2018
@yliaog
Copy link

yliaog commented Oct 11, 2018

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 11, 2018
@k8s-ci-robot k8s-ci-robot merged commit 8166c84 into kubernetes-sigs:master Oct 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants