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

Restructure backup format for resource prioritization #132

Merged
merged 1 commit into from
Oct 17, 2017

Conversation

dgoodwin
Copy link
Contributor

@dgoodwin dgoodwin commented Oct 12, 2017

Restructure backups for resource prioritization.

Previously the directory structure separated resources depending on
whether or not they were cluster or namespace scoped. All cluster
resources were restored first, then all namespace resources. Priority
did not apply across both and you could not order any namespace
resources before any cluster resources.

This restructure sorts first on resource type.

resources/serviceaccounts/namespaces/ns1.json
resources/nodes/cluster/node1.json

This will break old backups as the format is no longer consistent as
announced on the Google group.

@heptibot
Copy link

Can one of the admins verify this patch?

@dgoodwin dgoodwin force-pushed the ordering branch 3 times, most recently from 7fcd531 to 575db48 Compare October 13, 2017 14:57
@dgoodwin dgoodwin changed the title WIP: Resource Ordering Restructure backup format for resource prioritization Oct 13, 2017
@dgoodwin
Copy link
Contributor Author

@ncdc I think this is ready to be looked at now.

@ncdc
Copy link
Contributor

ncdc commented Oct 13, 2017

@dgoodwin thanks, I'll start reviewing shortly. When we're ready to merge, you'll need to make sure your commit(s) have signoff (git commit --signoff) as per https://github.com/heptio/ark/blob/master/CONTRIBUTING.md.

@ncdc
Copy link
Contributor

ncdc commented Oct 13, 2017

ok to test

@@ -473,9 +473,9 @@ func (ib *realItemBackupper) backupItem(ctx *backupContext, item map[string]inte

var filePath string
if namespace != "" {
filePath = strings.Join([]string{api.NamespaceScopedDir, namespace, groupResource.String(), name + ".json"}, "/")
filePath = strings.Join([]string{api.ResourcesDir, groupResource.String(), api.NamespaceScopedDir, namespace, name + ".json"}, "/")
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join

} else {
filePath = strings.Join([]string{api.ClusterScopedDir, groupResource.String(), name + ".json"}, "/")
filePath = strings.Join([]string{api.ResourcesDir, groupResource.String(), api.ClusterScopedDir, name + ".json"}, "/")
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join


nses, err := ctx.fileSystem.ReadDir(namespacesPath)
resourceDirs, err := ctx.fileSystem.ReadDir(resourcesDir)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you think there's any performance advantage one way or another between reading the resources dir up front like this, and just calling DirExists on each resource from ctx.prioritizedResources?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can't come up with a theory one way or the other, would have to test but in context of restore my guess would be not significant at this point. (backup might be another story as I assume people might be running that a lot more)

If worthwhile let me know and I'll test next week.

if !namespaceFilter.ShouldInclude(ns.Name()) {
ctx.infof("Skipping namespace %s", ns.Name())
continue
resourcePath := path.Join(resourcesDir, rscDir.Name())
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join

continue
resourcePath := path.Join(resourcesDir, rscDir.Name())

clusterSubDir := path.Join(resourcePath, api.ClusterScopedDir)
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join

if clusterSubDirExists {
w, e := ctx.restoreResource(resource.String(), "", clusterSubDir)
merge(&warnings, &w)
merge(&errors, &e)
Copy link
Contributor

Choose a reason for hiding this comment

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

continue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Must be no such thing as a resource that could be cluster or namespace scoped. Will add that in.

if !nsDir.IsDir() {
continue
}
nsPath := path.Join(nsSubDir, nsDir.Name())
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join

merge(&errors, &e)
}

nsSubDir := path.Join(resourcePath, api.NamespaceScopedDir)
Copy link
Contributor

Choose a reason for hiding this comment

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

filepath.Join

nsName := nsDir.Name()

// fetch mapped NS name
// TODO: what is a mapped ns name? for renames?
Copy link
Contributor

Choose a reason for hiding this comment

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

This is when you do ark restore create --namespace-mappings foo:bar,hello:goodbye,.... Any resources in foo will be restored to bar instead, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I think we might need to make use of this at some point.

}
if _, err := kube.EnsureNamespaceExists(ns, ctx.namespaceClient); err != nil {
addArkError(&errors, err)
return warnings, errors
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't this continue the nsDirs loop on line 318 to try additional namespaces?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Whoah, yeah that's a bad artifact from the refactor, good catch. Changing to continue.

@dgoodwin
Copy link
Contributor Author

Updated and added signoff.

@dgoodwin
Copy link
Contributor Author

One potential point of consideration, should I try to detect and warn about old backup tar.gzs?

Probably a case for backup.tar.gz versioning as well here.

@ncdc
Copy link
Contributor

ncdc commented Oct 13, 2017

Let's do that in a follow-up, at least the bit about writing some metadata to the backup tarball (and let's make sure we add an issue for that). I'm less concerned right now about detecting the old backup format and bailing out early, although that's probably easy to do, once we add in the metadata.

I am in the process of restructuring pkg/backup so it'll be easier if we do this after my exec hooks land.

@dgoodwin
Copy link
Contributor Author

Works for me.

exists, err = ctx.fileSystem.DirExists(namespacesPath)
// Make sure the top level "resources" dir exists:
resourcesDir := filepath.Join(dir, api.ResourcesDir)
_, err := ctx.fileSystem.DirExists(resourcesDir)
Copy link
Member

Choose a reason for hiding this comment

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

the bool should be checked, since in the normal case, if the dir doesn't exist, this will return (false, nil).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch.

addArkError(&errors, err)
return warnings, errors
}
if nsSubDirExists {
Copy link
Member

Choose a reason for hiding this comment

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

nit: maybe flip this conditional with a continue to reduce nesting for the main block of logic?

continue
}

nsName := nsDir.Name()
Copy link
Member

Choose a reason for hiding this comment

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

may as well move this up a few lines and eliminate a few more calls to nsDir.Name()

func (ctx *context) restoreNamespace(nsName, nsPath string) (api.RestoreResult, api.RestoreResult) {
// restoreResource restores the specified cluster or namespace scoped resource. If namespace is
// empty we are restoring a cluster level resource, otherwise into the specified namespace.
func (ctx *context) restoreResource(resource string, namespace string, resourcePath string) (api.RestoreResult, api.RestoreResult) {
Copy link
Member

Choose a reason for hiding this comment

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

restoreResource(resource, namespace, resourcePath string)

@skriss
Copy link
Member

skriss commented Oct 17, 2017

This doc also needs to be updated

Previously the directory structure separated resources depending on
whether or not they were cluster or namespace scoped. All cluster
resources were restored first, then all namespace resources. Priority
did not apply across both and you could not order any namespace
resources before any cluster resources.

This restructure sorts firstly on resource type.

resources/serviceaccounts/namespaces/ns1.json
resources/nodes/cluster/node1.json

This will break old backups as the format is no longer consistent as
announced on the Google group.

Signed-off-by: Devan Goodwin <dgoodwin@redhat.com>
@dgoodwin
Copy link
Contributor Author

Comments addressed I think!

@ncdc ncdc added this to the v0.5.0 milestone Oct 17, 2017
@ncdc ncdc merged commit bb5088f into vmware-tanzu:master Oct 17, 2017
@ncdc
Copy link
Contributor

ncdc commented Oct 17, 2017

Thanks again @dgoodwin!!!

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