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

Add file assets to node user data scripts, fingerprint fileAssets and hooks content. #3323

Merged

Conversation

KashifSaadat
Copy link
Contributor

@KashifSaadat KashifSaadat commented Aug 31, 2017

Changes made:

  • Include FileAssets in the bootstrapscript (user-data for all nodes), selectively dependent on the roles specified for each asset.
  • Fingerprint the sections of the FileAssets (Content) and Hooks (Manifests, ExecContainer Commands) Specs within the bootstrap script to reduce size (otherwise this can very quickly hit the 16KB user data limit with AWS).

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Aug 31, 2017
@KashifSaadat
Copy link
Contributor Author

/assign @justinsb
ping @gambol99

PR raised based on what we discussed earlier, let me know what you think! :) I don't believe there's any associated issue raised for this yet.

Copy link
Contributor

@gambol99 gambol99 left a comment

Choose a reason for hiding this comment

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

Just left a few comments ...

spec["hooks"] = hooks
if hooksFingerprint, err := b.fingerprintSpecList(hooks); err != nil {
return "", err
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

i think the else is redundant here given the return;

hooksFingerprint, err := b.fingerprintSpecList(hooks)
if err != nil {
   return "", err   
}
spec["hooksFingerprint"] = hooksFingerprint

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleaned up


fileAssets := b.getRelevantFileAssets(cs.FileAssets, ig.Spec.Role)
if len(fileAssets) > 0 {
if fileAssetsFingerprint, err := b.fingerprintSpecList(fileAssets); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

the same

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleaned up

@@ -124,7 +139,19 @@ func (b *BootstrapScript) ResourceNodeUp(ig *kops.InstanceGroup, cs *kops.Cluste
spec["taints"] = ig.Spec.Taints
hooks := b.getRelevantHooks(ig.Spec.Hooks, ig.Spec.Role)
if len(hooks) > 0 {
spec["hooks"] = hooks
if hooksFingerprint, err := b.fingerprintSpecList(hooks); err != nil {
Copy link
Contributor

@gambol99 gambol99 Aug 31, 2017

Choose a reason for hiding this comment

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

hmmm ... thinking out loud, perhaps it's overkill; I know we lose the diff (i.e. content) but it might be useful to keep some context, rather then a large hash on the full spec, maybe a hash per item. At least then you have some clue as to what changed. @KashifSaadat @justinsb

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 like that idea, will give it a go!

spec["hooksFingerprint"] = hooksFingerprint
}
}
fileAssets := b.getRelevantFileAssets(ig.Spec.FileAssets, ig.Spec.Role)
Copy link
Contributor

Choose a reason for hiding this comment

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

same thoughts as above ... though happy to go with the majority :-)

@KashifSaadat
Copy link
Contributor Author

Following @gambol99's suggestions I've done the following:

  • Fingerprint the ExecContainer.Command & Manifest within each Hook (these could both potentially be quite large)
  • Fingerprint the Content within each File Asset
  • Drop the Roles from the processed Hooks & File Assets

I've dropped the roles (set to nil) to avoid potentially causing an instance group to have a rolling upgrade when it's not necessary. E.g. You could have a File Asset deploying to Masters & Nodes, then drop Masters from the Roles list. This would then trigger a UserData update for Nodes, causing them to require a rebuild with no functional changes.

@chrislovecnm
Copy link
Contributor

@gambol99 lgtm??

@justinsb
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 15, 2017
func (b *BootstrapScript) getRelevantHooks(hooks []kops.HookSpec, role kops.InstanceGroupRole) []kops.HookSpec {
// getRelevantHooks returns a list of hooks to be applied to the instance group,
// with the Manifest and ExecContainer Commands fingerprinted to reduce size
func (b *BootstrapScript) getRelevantHooks(allHooks []kops.HookSpec, role kops.InstanceGroupRole) ([]kops.HookSpec, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if we can reuse this selector logic in nodeup (probably by moving it to a new package). I think we have the same logic duplicated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you know where it's duplicated, or where's best to move it to? We could extract from here (taking out the fingerprinting logic so it doesn't make the spec content invalid).

if err != nil {
return nil, err
}
fileAsset.Content = contentFingerprint + " (fingerprint)"
Copy link
Member

Choose a reason for hiding this comment

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

Long term I feel like it would be safer to use a hash in a new field (ContentHash), but this is the right way to start!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure that would be better. Would you suggest updating the spec to include ContentHash (which may get confusing, as we won't expect users to be specifying this in their spec), or just add it as a new field here (might be a bit complicated as it's not a valid field on the struct)?

return "", fmt.Errorf("error computing fingerprint hash: %v", err)
}

return base64.StdEncoding.EncodeToString(hasher.Sum(nil)), nil
Copy link
Member

Choose a reason for hiding this comment

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

I like this fingerprint function - it is unique enough that we could use it to retrieve the Content using only the ContentHash (within the "safe space" of a cluster!)

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 think you wrote this one in an earlier PR, came in quite handy :D

@k8s-github-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: justinsb

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

Needs approval from an approver in each of these OWNERS Files:

You can indicate your approval by writing /approve in a comment
You can cancel your approval by writing /approve cancel in a comment

@k8s-github-robot k8s-github-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 15, 2017
@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@KashifSaadat
Copy link
Contributor Author

/test pull-kops-e2e-kubernetes-aws

@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@k8s-github-robot
Copy link

Automatic merge from submit-queue

@k8s-github-robot k8s-github-robot merged commit 70007f8 into kubernetes:master Sep 15, 2017
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/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants