mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-25 18:53:44 +00:00
Merge pull request #2376 from Pennyzct/version_compatibility
kata-check: Add version consistency check
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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",
|
||||
}
|
||||
|
||||
|
58
cli/utils.go
58
cli/utils.go
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user