Merge pull request #2376 from Pennyzct/version_compatibility

kata-check: Add version consistency check
This commit is contained in:
Archana Shinde
2020-02-18 19:32:31 -08:00
committed by GitHub
5 changed files with 258 additions and 49 deletions

View File

@@ -63,6 +63,7 @@ const (
moduleParamDir = "parameters"
successMessageCapable = "System is capable of running " + project
successMessageCreate = "System can currently create " + project
successMessageVersion = "Version consistency of " + project + " is verified"
failMessage = "System is not capable of running " + project
kernelPropertyCorrect = "Kernel property value correct"
@@ -309,6 +310,10 @@ var kataCheckCLICommand = cli.Command{
Name: "verbose, v",
Usage: "display the list of checks performed",
},
cli.BoolFlag{
Name: "strict, s",
Usage: "perform strict checking",
},
},
Action: func(context *cli.Context) error {
@@ -357,6 +362,16 @@ var kataCheckCLICommand = cli.Command{
fmt.Println(successMessageCreate)
}
strict := context.Bool("strict")
if strict {
err = checkVersionConsistencyInComponents(runtimeConfig)
if err != nil {
return err
}
fmt.Println(successMessageVersion)
}
return nil
},
}
@@ -454,3 +469,35 @@ func genericCheckKVMExtensions(extensions map[string]kvmExtension) (map[string]i
return results, nil
}
// checkVersionConsistencyInComponents checks version consistency in Kata Components.
func checkVersionConsistencyInComponents(config oci.RuntimeConfig) error {
proxyInfo := getProxyInfo(config)
shimInfo, err := getShimInfo(config)
if err != nil {
return err
}
shimVersionInfo := shimInfo.Version
runtimeVersionInfo := constructVersionInfo(version)
// kata-proxy exists
if proxyInfo.Type != string(vc.NoProxyType) {
proxyVersionInfo := proxyInfo.Version
if !versionEqual(proxyVersionInfo, runtimeVersionInfo) || !versionEqual(shimVersionInfo, runtimeVersionInfo) {
return fmt.Errorf("there exists version inconsistency in kata components. kata-proxy: v%d.%d.%d, kata-shim: v%d.%d.%d, kata-runtime: v%d.%d.%d",
proxyVersionInfo.Major, proxyVersionInfo.Minor, proxyVersionInfo.Patch,
shimVersionInfo.Major, shimVersionInfo.Minor, shimVersionInfo.Patch,
runtimeVersionInfo.Major, runtimeVersionInfo.Minor, runtimeVersionInfo.Patch)
}
} else {
if !versionEqual(shimVersionInfo, runtimeVersionInfo) {
return fmt.Errorf("there exists version inconsistency in kata components. kata-shim: v%d.%d.%d, kata-runtime: v%d.%d.%d",
shimVersionInfo.Major, shimVersionInfo.Minor, shimVersionInfo.Patch,
runtimeVersionInfo.Major, runtimeVersionInfo.Minor, runtimeVersionInfo.Patch)
}
}
return nil
}

View File

@@ -19,6 +19,7 @@ import (
ktu "github.com/kata-containers/runtime/pkg/katatestutils"
"github.com/kata-containers/runtime/pkg/katautils"
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/urfave/cli"
@@ -905,3 +906,87 @@ func TestArchRequiredKernelModules(t *testing.T) {
assert.EqualValues(count, expectedCount)
}
func TestCheckVersionConsistencyInComponents(t *testing.T) {
type testData struct {
proxyExist bool
expectError bool
shimVersion string
proxyVersion string
runtimeVersion string
}
data := []testData{
{
true,
true,
"kata-shim version 0.2.0-rc0-xxxxxxxxxxxxx",
"kata-proxy version 0.1.0-rc0-xxxxxxxxxxxxx",
"0.2.0-rc0",
},
{
true,
true,
"kata-shim version 0.1.0-rc0-xxxxxxxxxxxxx",
"kata-proxy version 0.2.0-rc0-xxxxxxxxxxxxx",
"0.2.0-rc0",
},
{
true,
true,
"kata-shim version 0.1.0-rc0-xxxxxxxxxxxxx",
"kata-proxy version 0.1.0-rc0-xxxxxxxxxxxxx",
"0.2.0-rc0",
},
{
true,
false,
"kata-shim version 0.2.0-rc0-xxxxxxxxxxxxx",
"kata-proxy version 0.2.0-rc0-xxxxxxxxxxxxx",
"0.2.0-rc0",
},
{
false,
true,
"kata-shim version 0.1.0-rc0-xxxxxxxxxxxxx",
"",
"0.2.0-rc0",
},
{
false,
false,
"kata-shim version 0.2.0-rc0-xxxxxxxxxxxxx",
"",
"0.2.0-rc0",
},
}
origVersion := version
for _, d := range data {
tmpdir, err := ioutil.TempDir("", "")
assert.NoError(t, err)
defer os.RemoveAll(tmpdir)
testShimVersion = d.shimVersion
if d.proxyExist {
testProxyVersion = d.proxyVersion
}
_, config, err := makeRuntimeConfig(tmpdir)
assert.NoError(t, err)
if !d.proxyExist {
config.ProxyType = vc.NoProxyType
}
version = d.runtimeVersion
defer func() {
version = origVersion
}()
err = checkVersionConsistencyInComponents(config)
if d.expectError {
assert.Error(t, err, fmt.Sprintf("%+v", d))
continue
} else {
assert.NoError(t, err, fmt.Sprintf("%+v", d))
}
}
}

View File

@@ -74,11 +74,18 @@ type RuntimeInfo struct {
Path string
}
type VersionInfo struct {
Semver string
Major uint64
Minor uint64
Patch uint64
Commit string
}
// RuntimeVersionInfo stores details of the runtime version
type RuntimeVersionInfo struct {
Semver string
Commit string
OCI string
Version VersionInfo
OCI string
}
// HypervisorInfo stores hypervisor details
@@ -100,7 +107,7 @@ type HypervisorInfo struct {
// ProxyInfo stores proxy details
type ProxyInfo struct {
Type string
Version string
Version VersionInfo
Path string
Debug bool
}
@@ -108,7 +115,7 @@ type ProxyInfo struct {
// ShimInfo stores shim details
type ShimInfo struct {
Type string
Version string
Version VersionInfo
Path string
Debug bool
}
@@ -140,7 +147,7 @@ type HostInfo struct {
// NetmonInfo stores netmon details
type NetmonInfo struct {
Version string
Version VersionInfo
Path string
Debug bool
Enable bool
@@ -171,10 +178,12 @@ func getMetaInfo() MetaInfo {
}
func getRuntimeInfo(configFile string, config oci.RuntimeConfig) RuntimeInfo {
runtimeVersionInfo := constructVersionInfo(version)
runtimeVersionInfo.Commit = commit
runtimeVersion := RuntimeVersionInfo{
Semver: version,
Commit: commit,
OCI: specs.Version,
Version: runtimeVersionInfo,
OCI: specs.Version,
}
runtimeConfig := RuntimeConfigInfo{
@@ -250,43 +259,48 @@ func getHostInfo() (HostInfo, error) {
return host, nil
}
func getProxyInfo(config oci.RuntimeConfig) (ProxyInfo, error) {
func getProxyInfo(config oci.RuntimeConfig) ProxyInfo {
if config.ProxyType == vc.NoProxyType {
return ProxyInfo{Type: string(config.ProxyType)}, nil
return ProxyInfo{Type: string(config.ProxyType)}
}
proxyConfig := config.ProxyConfig
version, err := getCommandVersion(proxyConfig.Path)
if err != nil {
version = unknown
var proxyVersionInfo VersionInfo
if version, err := getCommandVersion(proxyConfig.Path); err != nil {
proxyVersionInfo = unknownVersionInfo
} else {
proxyVersionInfo = constructVersionInfo(version)
}
proxy := ProxyInfo{
Type: string(config.ProxyType),
Version: version,
Version: proxyVersionInfo,
Path: proxyConfig.Path,
Debug: proxyConfig.Debug,
}
return proxy, nil
return proxy
}
func getNetmonInfo(config oci.RuntimeConfig) (NetmonInfo, error) {
func getNetmonInfo(config oci.RuntimeConfig) NetmonInfo {
netmonConfig := config.NetmonConfig
version, err := getCommandVersion(netmonConfig.Path)
if err != nil {
version = unknown
var netmonVersionInfo VersionInfo
if version, err := getCommandVersion(netmonConfig.Path); err != nil {
netmonVersionInfo = unknownVersionInfo
} else {
netmonVersionInfo = constructVersionInfo(version)
}
netmon := NetmonInfo{
Version: version,
Version: netmonVersionInfo,
Path: netmonConfig.Path,
Debug: netmonConfig.Debug,
Enable: netmonConfig.Enable,
}
return netmon, nil
return netmon
}
func getCommandVersion(cmd string) (string, error) {
@@ -301,14 +315,16 @@ func getShimInfo(config oci.RuntimeConfig) (ShimInfo, error) {
shimPath := shimConfig.Path
version, err := getCommandVersion(shimPath)
if err != nil {
version = unknown
var shimVersionInfo VersionInfo
if version, err := getCommandVersion(shimConfig.Path); err != nil {
shimVersionInfo = unknownVersionInfo
} else {
shimVersionInfo = constructVersionInfo(version)
}
shim := ShimInfo{
Type: string(config.ShimType),
Version: version,
Version: shimVersionInfo,
Path: shimPath,
Debug: shimConfig.Debug,
}
@@ -378,9 +394,9 @@ func getEnvInfo(configFile string, config oci.RuntimeConfig) (env EnvInfo, err e
return EnvInfo{}, err
}
proxy, _ := getProxyInfo(config)
proxy := getProxyInfo(config)
netmon, _ := getNetmonInfo(config)
netmon := getNetmonInfo(config)
shim, err := getShimInfo(config)
if err != nil {

View File

@@ -30,10 +30,12 @@ import (
"github.com/stretchr/testify/assert"
)
const testProxyVersion = "proxy version 0.1"
const testShimVersion = "shim version 0.1"
const testNetmonVersion = "netmon version 0.1"
const testHypervisorVersion = "QEMU emulator version 2.7.0+git.741f430a96-6.1, Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers"
var (
testProxyVersion = "proxy version 0.1"
testShimVersion = "shim version 0.1"
testNetmonVersion = "netmon version 0.1"
testHypervisorVersion = "QEMU emulator version 2.7.0+git.741f430a96-6.1, Copyright (c) 2003-2016 Fabrice Bellard and the QEMU Project developers"
)
var (
hypervisorDebug = false
@@ -187,7 +189,7 @@ func makeRuntimeConfig(prefixDir string) (configFile string, config oci.RuntimeC
func getExpectedProxyDetails(config oci.RuntimeConfig) (ProxyInfo, error) {
return ProxyInfo{
Type: string(config.ProxyType),
Version: testProxyVersion,
Version: constructVersionInfo(testProxyVersion),
Path: config.ProxyConfig.Path,
Debug: config.ProxyConfig.Debug,
}, nil
@@ -195,7 +197,7 @@ func getExpectedProxyDetails(config oci.RuntimeConfig) (ProxyInfo, error) {
func getExpectedNetmonDetails(config oci.RuntimeConfig) (NetmonInfo, error) {
return NetmonInfo{
Version: testNetmonVersion,
Version: constructVersionInfo(testNetmonVersion),
Path: config.NetmonConfig.Path,
Debug: config.NetmonConfig.Debug,
Enable: config.NetmonConfig.Enable,
@@ -212,7 +214,7 @@ func getExpectedShimDetails(config oci.RuntimeConfig) (ShimInfo, error) {
return ShimInfo{
Type: string(config.ShimType),
Version: testShimVersion,
Version: constructVersionInfo(testShimVersion),
Path: shimPath,
Debug: shimConfig.Debug,
}, nil
@@ -353,11 +355,12 @@ func getExpectedKernel(config oci.RuntimeConfig) KernelInfo {
func getExpectedRuntimeDetails(config oci.RuntimeConfig, configFile string) RuntimeInfo {
runtimePath, _ := os.Executable()
runtimeVersionInfo := constructVersionInfo(version)
runtimeVersionInfo.Commit = commit
return RuntimeInfo{
Version: RuntimeVersionInfo{
Semver: version,
Commit: commit,
OCI: specs.Version,
Version: runtimeVersionInfo,
OCI: specs.Version,
},
Config: RuntimeConfigInfo{
Path: configFile,
@@ -678,7 +681,7 @@ func TestEnvGetProxyInfo(t *testing.T) {
expectedProxy, err := getExpectedProxyDetails(config)
assert.NoError(t, err)
proxy, err := getProxyInfo(config)
proxy := getProxyInfo(config)
assert.NoError(t, err)
assert.Equal(t, expectedProxy, proxy)
@@ -701,9 +704,9 @@ func TestEnvGetProxyInfoNoVersion(t *testing.T) {
err = os.Remove(config.ProxyConfig.Path)
assert.NoError(t, err)
expectedProxy.Version = unknown
expectedProxy.Version = unknownVersionInfo
proxy, err := getProxyInfo(config)
proxy := getProxyInfo(config)
assert.NoError(t, err)
assert.Equal(t, expectedProxy, proxy)
@@ -722,7 +725,7 @@ func TestEnvGetNetmonInfo(t *testing.T) {
expectedNetmon, err := getExpectedNetmonDetails(config)
assert.NoError(t, err)
netmon, err := getNetmonInfo(config)
netmon := getNetmonInfo(config)
assert.NoError(t, err)
assert.Equal(t, expectedNetmon, netmon)
@@ -745,9 +748,9 @@ func TestEnvGetNetmonInfoNoVersion(t *testing.T) {
err = os.Remove(config.NetmonConfig.Path)
assert.NoError(t, err)
expectedNetmon.Version = unknown
expectedNetmon.Version = unknownVersionInfo
netmon, err := getNetmonInfo(config)
netmon := getNetmonInfo(config)
assert.NoError(t, err)
assert.Equal(t, expectedNetmon, netmon)
@@ -792,7 +795,7 @@ func TestEnvGetShimInfoNoVersion(t *testing.T) {
exit 1`)
assert.NoError(t, err)
expectedShim.Version = unknown
expectedShim.Version = unknownVersionInfo
shim, err := getShimInfo(config)
assert.NoError(t, err)
@@ -880,14 +883,14 @@ func testEnvShowTOMLSettings(t *testing.T, tmpdir string, tmpfile *os.File) erro
proxy := ProxyInfo{
Type: "proxy-type",
Version: "proxy-version",
Version: constructVersionInfo(testProxyVersion),
Path: "file:///proxy-url",
Debug: false,
}
shim := ShimInfo{
Type: "shim-type",
Version: "shim-version",
Version: constructVersionInfo(testShimVersion),
Path: "/resolved/shim/path",
}
@@ -949,14 +952,14 @@ func testEnvShowJSONSettings(t *testing.T, tmpdir string, tmpfile *os.File) erro
proxy := ProxyInfo{
Type: "proxy-type",
Version: "proxy-version",
Version: constructVersionInfo(testProxyVersion),
Path: "file:///proxy-url",
Debug: false,
}
shim := ShimInfo{
Type: "shim-type",
Version: "shim-version",
Version: constructVersionInfo(testShimVersion),
Path: "/resolved/shim/path",
}

View File

@@ -12,6 +12,7 @@ import (
"strconv"
"strings"
"github.com/blang/semver"
"github.com/kata-containers/runtime/pkg/katautils"
)
@@ -26,6 +27,11 @@ var (
// Clear Linux has a different path (for stateless support)
osReleaseClr = "/usr/lib/os-release"
unknownVersionInfo = VersionInfo{
Semver: unknown,
Commit: unknown,
}
)
func getKernelVersion() (string, error) {
@@ -143,3 +149,55 @@ func parseBoolOrAuto(s string) (*bool, error) {
b, err := strconv.ParseBool(s)
return &b, err
}
// constructVersionInfo constructs VersionInfo-type value from a version string
// in the format of "Kata-Component version Major.Minor.Patch-rc_xxx-Commit".
func constructVersionInfo(version string) VersionInfo {
fields := strings.Split(version, " ")
realVersion := fields[len(fields)-1]
sv, err := semver.Make(realVersion)
if err != nil {
return unknownVersionInfo
}
pres := strings.Split(sv.Pre[0].VersionStr, "-")
// version contains Commit info.
if len(pres) > 1 {
return VersionInfo{
Semver: realVersion,
Major: sv.Major,
Minor: sv.Minor,
Patch: sv.Patch,
Commit: pres[1],
}
}
return VersionInfo{
Semver: realVersion,
Major: sv.Major,
Minor: sv.Minor,
Patch: sv.Patch,
Commit: unknown,
}
}
func versionEqual(a VersionInfo, b VersionInfo) bool {
av, err := semver.Make(a.Semver)
if err != nil {
return false
}
bv, err := semver.Make(b.Semver)
if err != nil {
return false
}
if av.Major == bv.Major && av.Minor == bv.Minor && av.Patch == bv.Patch {
return true
}
return false
}