Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

annotations: Improve asset annotation handling #3031

Merged
merged 4 commits into from
Nov 5, 2020

Conversation

jodh-intel
Copy link
Contributor

@jodh-intel jodh-intel commented Oct 28, 2020

Make asset.go the arbiter of asset annotations by removing all asset
annotations lists from other parts of the codebase.

This makes the code simpler, easier to maintain, and more robust.

Specifically, the previous behaviour was inconsistent as the following
ways:

  • createAssets() in sandbox.go was not handling the following asset
    annotations:

    • firmware:

      • io.katacontainers.config.hypervisor.firmware
      • io.katacontainers.config.hypervisor.firmware_hash
    • hypervisor:

      • io.katacontainers.config.hypervisor.path
      • io.katacontainers.config.hypervisor.hypervisor_hash
    • hypervisor control binary:

      • io.katacontainers.config.hypervisor.ctlpath
      • io.katacontainers.config.hypervisor.hypervisorctl_hash
    • jailer:

      • io.katacontainers.config.hypervisor.jailer_path
      • io.katacontainers.config.hypervisor.jailer_hash
  • addAssetAnnotations() in the oci package was not handling the
    following asset annotations:

    • hypervisor:

      • io.katacontainers.config.hypervisor.path
      • io.katacontainers.config.hypervisor.hypervisor_hash
    • hypervisor control binary:

      • io.katacontainers.config.hypervisor.ctlpath
      • io.katacontainers.config.hypervisor.hypervisorctl_hash
    • jailer:

      • io.katacontainers.config.hypervisor.jailer_path
      • io.katacontainers.config.hypervisor.jailer_hash

This change fixes the bug where specifying a custom hypervisor path via an
asset annotation was having no effect.

Fixes: #3030.

Signed-off-by: James O. D. Hunt [email protected]

@jodh-intel
Copy link
Contributor Author

/test

@jodh-intel jodh-intel added needs-forward-port Changes need to be applied to a newer branch / repository needs-backport Changes need to be applied to an older branch / repository labels Oct 28, 2020
@jodh-intel
Copy link
Contributor Author

Minimal manual test (based on https://github.com/kata-containers/documentation/blob/master/Developer-Guide.md#running-standalone):

$ bundle="/tmp/bundle"
$ rootfs="$bundle/rootfs"
$ mkdir -p "$rootfs" && (cd "$bundle" && kata-runtime spec)
$ sudo docker export $(sudo docker create busybox) | tar -C "$rootfs" -xvf -
$ (cd $bundle && jq '. |= . + {"annotations": {"io.katacontainers.config.hypervisor.path": "/does/not/exist"}}' < config.json > tmp && mv tmp config.json)
$ sudo kata-runtime --log=/dev/stdout run --bundle "$bundle" foo

The above will work (incorrectly) with current releases, but will fail with this PR (assuming /does/not/exist really doesn't exist ;)

/cc @gkunz

@gkunz
Copy link

gkunz commented Oct 28, 2020

@jodh-intel thanks for the quick fix! I'll test this PR as well in my lab.

@codecov
Copy link

codecov bot commented Oct 28, 2020

Codecov Report

Merging #3031 into master will increase coverage by 0.05%.
The diff coverage is 60.60%.

@@            Coverage Diff             @@
##           master    #3031      +/-   ##
==========================================
+ Coverage   50.25%   50.30%   +0.05%     
==========================================
  Files         120      120              
  Lines       15844    15840       -4     
==========================================
+ Hits         7963     7969       +6     
+ Misses       6799     6786      -13     
- Partials     1082     1085       +3     

@jodh-intel
Copy link
Contributor Author

@GabyCT - jenkins-ci-podman-clh-fedora-31 is failing with:

16:08:18 ./scripts/dev_cli.sh: line 122: docker: command not found

@GabyCT
Copy link
Contributor

GabyCT commented Oct 28, 2020

vcAnnotations.KernelPath,
vcAnnotations.ImagePath,
vcAnnotations.InitrdPath,
vcAnnotations.AssetHashType,
Copy link

Choose a reason for hiding this comment

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

are you not missing vcAnnotations.HypervisorPath here? In my local test of this PR, the hypervisor annotations still gets ignored. Upon including vcAnnotations.HypervisorPath here, it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gkunz - apologies - git stash fail :) I've actually found a way to make the code more robust, so marking as do-not-merge for now. I'll push an update tomorrow...

Copy link

Choose a reason for hiding this comment

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

@jodh-intel no problem. Thanks again for addressing the issue so quickly!

@jodh-intel jodh-intel added the do-not-merge PR has problems or depends on another label Oct 28, 2020
Copy link

@devimc devimc left a comment

Choose a reason for hiding this comment

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

thanks @jodh-intel

Improve formatting, grammar and whitespace.

Signed-off-by: James O. D. Hunt <[email protected]>
Add missing annotation definitions for a hypervisor control binary:

- `io.katacontainers.config.hypervisor.ctlpath`
- `io.katacontainers.config.hypervisor.hypervisorctl_hash`

Signed-off-by: James O. D. Hunt <[email protected]>
@jodh-intel jodh-intel removed the do-not-merge PR has problems or depends on another label Oct 29, 2020
@jodh-intel
Copy link
Contributor Author

/test

@jodh-intel jodh-intel changed the title annotations: Add missing asset annotations annotations: Improve asset annotation handling Oct 29, 2020
@jodh-intel
Copy link
Contributor Author

/test

Comment on lines 523 to 528
// We could not find a custom asset for the given type, let's
// fall back to the configured ones.
switch t {
case types.KernelAsset:
return conf.KernelPath, nil
case types.ImageAsset:
return conf.ImagePath, nil
case types.InitrdAsset:
return conf.InitrdPath, nil
case types.HypervisorAsset:
return conf.HypervisorPath, nil
case types.HypervisorCtlAsset:
return conf.HypervisorCtlPath, nil
case types.JailerAsset:
return conf.JailerPath, nil
case types.FirmwareAsset:
return conf.FirmwarePath, nil
default:
return "", fmt.Errorf("Unknown asset type %v", t)
assetPath, _, err := t.Annotations()
if err != nil {
return "", err
}

return assetPath, 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.

This is incorrect as it changes the function to return the asset annotation name, not the config value. I'm about to push a fix and a new TestAssetPath() test to assert the expected behaviour. However, I'm going to have to revert this change meaning we will still have a "list of asset annotations" outside of asset.go. This is annoying as I'd like to totally encapsulate that list in asset.go.

One possible improvement would be to annotate HypervisorConfig with custom struct tags like this:

type HypervisorConfig struct {
    FirmwarePath      string `annotation:"io.katacontainers.config.hypervisor.firmware"`
    HypervisorCtlPath string `annotation:"io.katacontainers.config.hypervisor.ctlpath"`
    HypervisorPath    string `annotation:"io.katacontainers.config.hypervisor.path"`
    ImagePath         string `annotation:"io.katacontainers.config.hypervisor.image"`
    InitrdPath        string `annotation:"io.katacontainers.config.hypervisor.initrd"`
    JailerPath        string `annotation:"io.katacontainers.config.hypervisor.jailer_path"`
    KernelPath        string `annotation:"io.katacontainers.config.hypervisor.kernel"`
}

That may make the code clearer and less error prone. However, there would be a runtime impact as we'd need to use reflect to map the struct tag (annotation) back to the config value.

Copy link
Member

Choose a reason for hiding this comment

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

@jodh-intel I like the idea of encapsulating all the assets constants and logic in assets.go, feel that it is all over the place right now. Maybe using reflection is not such a bad idea if we can cleanup the code and make sure that we do this once in the CreateSandbox code path.
We can address that in a separate PR.

What I did see is that the hypervisor.go has a lot of functions CustomFirmwareAsset, CustomJailerAsset etc which are not being called at all.
We need to assess if these functions should be called from getHypervisorDetails or we can just get rid of them.

@jodh-intel
Copy link
Contributor Author

/test

@jodh-intel
Copy link
Contributor Author

HI @gkunz - I've updated the branch now if you'd like to give the latest a try?

@gkunz
Copy link

gkunz commented Oct 29, 2020

@jodh-intel works nicely for me!

@jodh-intel
Copy link
Contributor Author

Thanks for confirming @gkunz !

@jodh-intel jodh-intel added the do-not-merge PR has problems or depends on another label Oct 29, 2020
@jodh-intel
Copy link
Contributor Author

Added dnm label to allow for a few more eyes to review before this lands.

@jodh-intel
Copy link
Contributor Author

@amshinde - any further thoughts on this? I've updated since you approved I think.

}

// Add the odd one out; it isn't part of a (path+hash) pair.
result = append(result, annotations.AssetHashType)
Copy link
Member

Choose a reason for hiding this comment

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

We dont need to address this in this PR.
But raising my concern about value of supporting this. Maybe we should just support sha512 hash and document it so, rather than providing this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

// AssetTypes returns a list of all known asset types.
//
// XXX: New asset types *MUST* be added here.
func AssetTypes() []AssetType {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Suggestion to move all the consts for FirmwareAsset, HypervisorAsset etc to the top of the file for better readability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

JailerAsset,
KernelAsset,
}
}
Copy link
Member

Choose a reason for hiding this comment

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

In terms of cleanup, there is another function called Valid() which could make use of this list instead of comparing against individual values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

Comment on lines 523 to 528
// We could not find a custom asset for the given type, let's
// fall back to the configured ones.
switch t {
case types.KernelAsset:
return conf.KernelPath, nil
case types.ImageAsset:
return conf.ImagePath, nil
case types.InitrdAsset:
return conf.InitrdPath, nil
case types.HypervisorAsset:
return conf.HypervisorPath, nil
case types.HypervisorCtlAsset:
return conf.HypervisorCtlPath, nil
case types.JailerAsset:
return conf.JailerPath, nil
case types.FirmwareAsset:
return conf.FirmwarePath, nil
default:
return "", fmt.Errorf("Unknown asset type %v", t)
assetPath, _, err := t.Annotations()
if err != nil {
return "", err
}

return assetPath, nil
Copy link
Member

Choose a reason for hiding this comment

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

@jodh-intel I like the idea of encapsulating all the assets constants and logic in assets.go, feel that it is all over the place right now. Maybe using reflection is not such a bad idea if we can cleanup the code and make sure that we do this once in the CreateSandbox code path.
We can address that in a separate PR.

What I did see is that the hypervisor.go has a lot of functions CustomFirmwareAsset, CustomJailerAsset etc which are not being called at all.
We need to assess if these functions should be called from getHypervisorDetails or we can just get rid of them.

@jodh-intel
Copy link
Contributor Author

@amshinde - I've removed the unused functions. On reflection (:smile:), I'm not totally convinced about my reflection idea: there
is another problem of using that technique - we can't use variables in the struct tags so we'd end up with another maintenance issue as it would be easy to rename an annotation variable value, but forget to update the corresponding static struct tag annotation string. Sigh.

Let's ponder this some more and make further improvements if possible on a follow-up PR.

For now, I'd like to get this landed so it can be ported to 2.x.

@jodh-intel jodh-intel removed the do-not-merge PR has problems or depends on another label Nov 4, 2020
@jodh-intel
Copy link
Contributor Author

/test

@amshinde
Copy link
Member

amshinde commented Nov 4, 2020

Let's ponder this some more and make further improvements if possible on a follow-up PR.

For now, I'd like to get this landed so it can be ported to 2.x.

Agree. SGTM.

Make `asset.go` the arbiter of asset annotations by removing all asset
annotations lists from other parts of the codebase.

This makes the code simpler, easier to maintain, and more robust.

Specifically, the previous behaviour was inconsistent as the following
ways:

- `createAssets()` in `sandbox.go` was not handling the following asset
  annotations:

    - firmware:
      - `io.katacontainers.config.hypervisor.firmware`
      - `io.katacontainers.config.hypervisor.firmware_hash`

    - hypervisor:
      - `io.katacontainers.config.hypervisor.path`
      - `io.katacontainers.config.hypervisor.hypervisor_hash`

    - hypervisor control binary:
      - `io.katacontainers.config.hypervisor.ctlpath`
      - `io.katacontainers.config.hypervisor.hypervisorctl_hash`

    - jailer:
      - `io.katacontainers.config.hypervisor.jailer_path`
      - `io.katacontainers.config.hypervisor.jailer_hash`

- `addAssetAnnotations()` in the `oci` package was not handling the
  following asset annotations:

    - hypervisor:
      - `io.katacontainers.config.hypervisor.path`
      - `io.katacontainers.config.hypervisor.hypervisor_hash`

    - hypervisor control binary:
      - `io.katacontainers.config.hypervisor.ctlpath`
      - `io.katacontainers.config.hypervisor.hypervisorctl_hash`

    - jailer:
      - `io.katacontainers.config.hypervisor.jailer_path`
      - `io.katacontainers.config.hypervisor.jailer_hash`

This change fixes the bug where specifying a custom hypervisor path via an
asset annotation was having no effect.

Fixes: kata-containers#3030.

Signed-off-by: James O. D. Hunt <[email protected]>
Deleted `HypervisorConfig`'s unused  `CustomFirmwareAsset()` and
`JailerAssetPath()` methods.

Signed-off-by: James O. D. Hunt <[email protected]>
@jodh-intel
Copy link
Contributor Author

/test

@jodh-intel jodh-intel merged commit 3108536 into kata-containers:master Nov 5, 2020
@jodh-intel
Copy link
Contributor Author

forward port PR: kata-containers/kata-containers#1086

c3d added a commit to c3d/runtime that referenced this pull request Nov 5, 2020
The changes introduced in PR kata-containers#3031 require additional changes.
Code lifted from kata-containers/kata-containers#1086.

Fixes: kata-containers#3005

Suggested-by: James O.D. Hunt <[email protected]>
Signed-off-by: Christophe de Dinechin <[email protected]>
c3d added a commit to c3d/runtime that referenced this pull request Nov 9, 2020
The changes introduced in PR kata-containers#3031 require additional changes.
Code lifted from kata-containers/kata-containers#1086.

Fixes: kata-containers#3005

Suggested-by: James O.D. Hunt <[email protected]>
Signed-off-by: Christophe de Dinechin <[email protected]>
c3d added a commit to c3d/runtime that referenced this pull request Nov 10, 2020
The changes introduced in PR kata-containers#3031 require additional changes.
Code lifted from kata-containers/kata-containers#1086.

Fixes: kata-containers#3005

Suggested-by: James O.D. Hunt <[email protected]>
Signed-off-by: Christophe de Dinechin <[email protected]>
fidencio pushed a commit to fidencio/kata-runtime that referenced this pull request Nov 11, 2020
The changes introduced in PR kata-containers#3031 require additional changes.
Code lifted from kata-containers/kata-containers#1086.

Fixes: kata-containers#3005

Suggested-by: James O.D. Hunt <[email protected]>
Signed-off-by: Christophe de Dinechin <[email protected]>
fidencio pushed a commit to fidencio/kata-runtime that referenced this pull request Nov 11, 2020
The changes introduced in PR kata-containers#3031 require additional changes.
Code lifted from kata-containers/kata-containers#1086.

Fixes: kata-containers#3005

Suggested-by: James O.D. Hunt <[email protected]>
Signed-off-by: Christophe de Dinechin <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs-backport Changes need to be applied to an older branch / repository needs-forward-port Changes need to be applied to a newer branch / repository
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pod annotations for selecting a custom hypervisor binary not working
5 participants