Merge pull request #902 from c3d/bug-v2/launchpad-1878234-access

Validate runtime annotations
This commit is contained in:
Peng Tao
2020-10-16 15:47:45 +08:00
committed by GitHub
13 changed files with 552 additions and 155 deletions

View File

@@ -275,12 +275,21 @@ type HypervisorConfig struct {
// HypervisorPath is the hypervisor executable host path.
HypervisorPath string
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
HypervisorPathList []string
// HypervisorCtlPathList is the list of hypervisor control paths names allowed in annotations
HypervisorCtlPathList []string
// HypervisorCtlPath is the hypervisor ctl executable host path.
HypervisorCtlPath string
// JailerPath is the jailer executable host path.
JailerPath string
// JailerPathList is the list of jailer paths names allowed in annotations
JailerPathList []string
// BlockDeviceDriver specifies the driver to be used for block device
// either VirtioSCSI or VirtioBlock with the default driver being defaultBlockDriver
BlockDeviceDriver string
@@ -309,6 +318,9 @@ type HypervisorConfig struct {
// VirtioFSDaemon is the virtio-fs vhost-user daemon path
VirtioFSDaemon string
// VirtioFSDaemonList is the list of valid virtiofs names for annotations
VirtioFSDaemonList []string
// VirtioFSCache cache mode for fs version cache or "none"
VirtioFSCache string
@@ -318,6 +330,9 @@ type HypervisorConfig struct {
// File based memory backend root directory
FileBackedMemRootDir string
// FileBackedMemRootList is the list of valid root directories values for annotations
FileBackedMemRootList []string
// customAssets is a map of assets.
// Each value in that map takes precedence over the configured assets.
// For example, if there is a value for the "kernel" key in this map,
@@ -400,6 +415,9 @@ type HypervisorConfig struct {
// related folders, sockets and device nodes should be.
VhostUserStorePath string
// VhostUserStorePathList is the list of valid values for vhost-user paths
VhostUserStorePathList []string
// GuestHookPath is the path within the VM that will be used for 'drop-in' hooks
GuestHookPath string
@@ -419,6 +437,9 @@ type HypervisorConfig struct {
// SGXEPCSize specifies the size in bytes for the EPC Section.
// Enable SGX. Hardware-based isolation and memory encryption.
SGXEPCSize int64
// Enable annotations by name
EnableAnnotations []string
}
// vcpu mapping from vcpu number to thread number

View File

@@ -212,8 +212,11 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
MachineAccelerators: sconfig.HypervisorConfig.MachineAccelerators,
CPUFeatures: sconfig.HypervisorConfig.CPUFeatures,
HypervisorPath: sconfig.HypervisorConfig.HypervisorPath,
HypervisorPathList: sconfig.HypervisorConfig.HypervisorPathList,
HypervisorCtlPath: sconfig.HypervisorConfig.HypervisorCtlPath,
HypervisorCtlPathList: sconfig.HypervisorConfig.HypervisorCtlPathList,
JailerPath: sconfig.HypervisorConfig.JailerPath,
JailerPathList: sconfig.HypervisorConfig.JailerPathList,
BlockDeviceDriver: sconfig.HypervisorConfig.BlockDeviceDriver,
HypervisorMachineType: sconfig.HypervisorConfig.HypervisorMachineType,
MemoryPath: sconfig.HypervisorConfig.MemoryPath,
@@ -221,6 +224,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
EntropySource: sconfig.HypervisorConfig.EntropySource,
SharedFS: sconfig.HypervisorConfig.SharedFS,
VirtioFSDaemon: sconfig.HypervisorConfig.VirtioFSDaemon,
VirtioFSDaemonList: sconfig.HypervisorConfig.VirtioFSDaemonList,
VirtioFSCache: sconfig.HypervisorConfig.VirtioFSCache,
VirtioFSExtraArgs: sconfig.HypervisorConfig.VirtioFSExtraArgs[:],
BlockDeviceCacheSet: sconfig.HypervisorConfig.BlockDeviceCacheSet,
@@ -232,6 +236,7 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
MemPrealloc: sconfig.HypervisorConfig.MemPrealloc,
HugePages: sconfig.HypervisorConfig.HugePages,
FileBackedMemRootDir: sconfig.HypervisorConfig.FileBackedMemRootDir,
FileBackedMemRootList: sconfig.HypervisorConfig.FileBackedMemRootList,
Realtime: sconfig.HypervisorConfig.Realtime,
Mlock: sconfig.HypervisorConfig.Mlock,
DisableNestingChecks: sconfig.HypervisorConfig.DisableNestingChecks,
@@ -243,11 +248,13 @@ func (s *Sandbox) dumpConfig(ss *persistapi.SandboxState) {
DisableVhostNet: sconfig.HypervisorConfig.DisableVhostNet,
EnableVhostUserStore: sconfig.HypervisorConfig.EnableVhostUserStore,
VhostUserStorePath: sconfig.HypervisorConfig.VhostUserStorePath,
VhostUserStorePathList: sconfig.HypervisorConfig.VhostUserStorePathList,
GuestHookPath: sconfig.HypervisorConfig.GuestHookPath,
VMid: sconfig.HypervisorConfig.VMid,
RxRateLimiterMaxRate: sconfig.HypervisorConfig.RxRateLimiterMaxRate,
TxRateLimiterMaxRate: sconfig.HypervisorConfig.TxRateLimiterMaxRate,
SGXEPCSize: sconfig.HypervisorConfig.SGXEPCSize,
EnableAnnotations: sconfig.HypervisorConfig.EnableAnnotations,
}
ss.Config.KataAgentConfig = &persistapi.KataAgentConfig{
@@ -474,8 +481,11 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
MachineAccelerators: hconf.MachineAccelerators,
CPUFeatures: hconf.CPUFeatures,
HypervisorPath: hconf.HypervisorPath,
HypervisorPathList: hconf.HypervisorPathList,
HypervisorCtlPath: hconf.HypervisorCtlPath,
HypervisorCtlPathList: hconf.HypervisorCtlPathList,
JailerPath: hconf.JailerPath,
JailerPathList: hconf.JailerPathList,
BlockDeviceDriver: hconf.BlockDeviceDriver,
HypervisorMachineType: hconf.HypervisorMachineType,
MemoryPath: hconf.MemoryPath,
@@ -483,6 +493,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
EntropySource: hconf.EntropySource,
SharedFS: hconf.SharedFS,
VirtioFSDaemon: hconf.VirtioFSDaemon,
VirtioFSDaemonList: hconf.VirtioFSDaemonList,
VirtioFSCache: hconf.VirtioFSCache,
VirtioFSExtraArgs: hconf.VirtioFSExtraArgs[:],
BlockDeviceCacheSet: hconf.BlockDeviceCacheSet,
@@ -494,6 +505,7 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
MemPrealloc: hconf.MemPrealloc,
HugePages: hconf.HugePages,
FileBackedMemRootDir: hconf.FileBackedMemRootDir,
FileBackedMemRootList: hconf.FileBackedMemRootList,
Realtime: hconf.Realtime,
Mlock: hconf.Mlock,
DisableNestingChecks: hconf.DisableNestingChecks,
@@ -505,11 +517,13 @@ func loadSandboxConfig(id string) (*SandboxConfig, error) {
DisableVhostNet: hconf.DisableVhostNet,
EnableVhostUserStore: hconf.EnableVhostUserStore,
VhostUserStorePath: hconf.VhostUserStorePath,
VhostUserStorePathList: hconf.VhostUserStorePathList,
GuestHookPath: hconf.GuestHookPath,
VMid: hconf.VMid,
RxRateLimiterMaxRate: hconf.RxRateLimiterMaxRate,
TxRateLimiterMaxRate: hconf.TxRateLimiterMaxRate,
SGXEPCSize: hconf.SGXEPCSize,
EnableAnnotations: hconf.EnableAnnotations,
}
sconfig.AgentConfig = KataAgentConfig{

View File

@@ -60,12 +60,22 @@ type HypervisorConfig struct {
// HypervisorPath is the hypervisor executable host path.
HypervisorPath string
// HypervisorPathList is the list of hypervisor paths names allowed in annotations
HypervisorPathList []string
// HypervisorCtlPath is the hypervisor ctl executable host path.
HypervisorCtlPath string
// HypervisorCtlPathList is the list of hypervisor control paths names allowed in annotations
HypervisorCtlPathList []string
// HypervisorCtlPath is the hypervisor ctl executable host path.
// JailerPath is the jailer executable host path.
JailerPath string
// JailerPathList is the list of jailer paths names allowed in annotations
JailerPathList []string
// BlockDeviceDriver specifies the driver to be used for block device
// either VirtioSCSI or VirtioBlock with the default driver being defaultBlockDriver
BlockDeviceDriver string
@@ -94,6 +104,9 @@ type HypervisorConfig struct {
// VirtioFSDaemon is the virtio-fs vhost-user daemon path
VirtioFSDaemon string
// VirtioFSDaemonList is the list of valid virtiofs names for annotations
VirtioFSDaemonList []string
// VirtioFSCache cache mode for fs version cache or "none"
VirtioFSCache string
@@ -103,6 +116,9 @@ type HypervisorConfig struct {
// File based memory backend root directory
FileBackedMemRootDir string
// FileBackedMemRootList is the list of valid root directories values for annotations
FileBackedMemRootList []string
// BlockDeviceCacheSet specifies cache-related options will be set to block devices or not.
BlockDeviceCacheSet bool
@@ -173,6 +189,9 @@ type HypervisorConfig struct {
// related folders, sockets and device nodes should be.
VhostUserStorePath string
// VhostUserStorePathList is the list of valid values for vhost-user paths
VhostUserStorePathList []string
// GuestHookPath is the path within the VM that will be used for 'drop-in' hooks
GuestHookPath string
@@ -189,6 +208,9 @@ type HypervisorConfig struct {
// SGXEPCSize specifies the size in bytes for the EPC Section.
// Enable SGX. Hardware-based isolation and memory encryption.
SGXEPCSize int64
// Enable annotations by name
EnableAnnotations []string
}
// KataAgentConfig is a structure storing information needed

View File

@@ -28,6 +28,7 @@ const (
//
// Assets
//
KataAnnotationHypervisorPrefix = kataAnnotHypervisorPrefix
// KernelPath is a sandbox annotation for passing a per container path pointing at the kernel needed to boot the container VM.
KernelPath = kataAnnotHypervisorPrefix + "kernel"
@@ -44,6 +45,9 @@ const (
// JailerPath is a sandbox annotation for passing a per container path pointing at the jailer that will constrain the container VM.
JailerPath = kataAnnotHypervisorPrefix + "jailer_path"
// CtlPath is a sandbox annotation for passing a per container path pointing at the acrn ctl binary
CtlPath = kataAnnotHypervisorPrefix + "ctlpath"
// FirmwarePath is a sandbox annotation for passing a per container path pointing at the guest firmware that will run the container VM.
FirmwarePath = kataAnnotHypervisorPrefix + "firmware"
@@ -211,7 +215,7 @@ const (
TxRateLimiterMaxRate = kataAnnotHypervisorPrefix + "tx_rate_limiter_max_rate"
)
// Agent related annotations
// Runtime related annotations
const (
kataAnnotRuntimePrefix = kataConfAnnotationsPrefix + "runtime."
@@ -235,6 +239,7 @@ const (
DisableNewNetNs = kataAnnotRuntimePrefix + "disable_new_netns"
)
// Agent related annotations
const (
kataAnnotAgentPrefix = kataConfAnnotationsPrefix + "agent."

View File

@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"path/filepath"
"regexp"
goruntime "runtime"
"strconv"
"strings"
@@ -182,15 +183,44 @@ func containerMounts(spec specs.Spec) []vc.Mount {
return mnts
}
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
func contains(strings []string, toFind string) bool {
for _, candidate := range strings {
if candidate == toFind {
return true
}
}
return false
}
func regexpContains(regexps []string, toMatch string) bool {
for _, candidate := range regexps {
if matched, _ := regexp.MatchString(candidate, toMatch); matched {
return true
}
}
return false
}
func checkPathIsInGlobs(globs []string, path string) bool {
for _, glob := range globs {
filenames, _ := filepath.Glob(glob)
for _, a := range filenames {
if path == a {
return true
}
}
}
return false
}
// Check if an annotation name either belongs to another prefix, matches regexp list
func checkAnnotationNameIsValid(list []string, name string, prefix string) bool {
if strings.HasPrefix(name, prefix) {
return regexpContains(list, strings.TrimPrefix(name, prefix))
}
return true
}
func newLinuxDeviceInfo(d specs.LinuxDevice) (*config.DeviceInfo, error) {
allowedDeviceTypes := []string{"c", "b", "u", "p"}
@@ -323,13 +353,18 @@ func SandboxID(spec specs.Spec) (string, error) {
return "", fmt.Errorf("Could not find sandbox ID")
}
func addAnnotations(ocispec specs.Spec, config *vc.SandboxConfig) error {
func addAnnotations(ocispec specs.Spec, config *vc.SandboxConfig, runtime RuntimeConfig) error {
for key := range ocispec.Annotations {
if !checkAnnotationNameIsValid(runtime.HypervisorConfig.EnableAnnotations, key, vcAnnotations.KataAnnotationHypervisorPrefix) {
return fmt.Errorf("annotation %v is not enabled", key)
}
}
addAssetAnnotations(ocispec, config)
if err := addHypervisorConfigOverrides(ocispec, config); err != nil {
if err := addHypervisorConfigOverrides(ocispec, config, runtime); err != nil {
return err
}
if err := addRuntimeConfigOverrides(ocispec, config); err != nil {
if err := addRuntimeConfigOverrides(ocispec, config, runtime); err != nil {
return err
}
@@ -354,20 +389,18 @@ func addAssetAnnotations(ocispec specs.Spec, config *vc.SandboxConfig) {
for _, a := range assetAnnotations {
value, ok := ocispec.Annotations[a]
if !ok {
continue
if ok {
config.Annotations[a] = value
}
config.Annotations[a] = value
}
}
func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig) error {
func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig, runtime RuntimeConfig) error {
if err := addHypervisorCPUOverrides(ocispec, config); err != nil {
return err
}
if err := addHypervisorMemoryOverrides(ocispec, config); err != nil {
if err := addHypervisorMemoryOverrides(ocispec, config, runtime); err != nil {
return err
}
@@ -375,7 +408,7 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig)
return err
}
if err := addHypervisporVirtioFsOverrides(ocispec, config); err != nil {
if err := addHypervisorVirtioFsOverrides(ocispec, config, runtime); err != nil {
return err
}
@@ -383,15 +416,8 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig)
return err
}
if value, ok := ocispec.Annotations[vcAnnotations.KernelParams]; ok {
if value != "" {
params := vc.DeserializeParams(strings.Fields(value))
for _, param := range params {
if err := config.HypervisorConfig.AddKernelParam(param); err != nil {
return fmt.Errorf("Error adding kernel parameters in annotation kernel_params : %v", err)
}
}
}
if err := addHypervisorPathOverrides(ocispec, config, runtime); err != nil {
return err
}
if value, ok := ocispec.Annotations[vcAnnotations.MachineType]; ok {
@@ -406,6 +432,13 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig)
}
}
if value, ok := ocispec.Annotations[vcAnnotations.VhostUserStorePath]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.VhostUserStorePathList, value) {
return fmt.Errorf("vhost store path %v required from annotation is not valid", value)
}
config.HypervisorConfig.VhostUserStorePath = value
}
if value, ok := ocispec.Annotations[vcAnnotations.GuestHookPath]; ok {
if value != "" {
config.HypervisorConfig.GuestHookPath = value
@@ -461,7 +494,42 @@ func addHypervisorConfigOverrides(ocispec specs.Spec, config *vc.SandboxConfig)
return nil
}
func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) error {
func addHypervisorPathOverrides(ocispec specs.Spec, config *vc.SandboxConfig, runtime RuntimeConfig) error {
if value, ok := ocispec.Annotations[vcAnnotations.HypervisorPath]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.HypervisorPathList, value) {
return fmt.Errorf("hypervisor %v required from annotation is not valid", value)
}
config.HypervisorConfig.HypervisorPath = value
}
if value, ok := ocispec.Annotations[vcAnnotations.JailerPath]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.JailerPathList, value) {
return fmt.Errorf("jailer %v required from annotation is not valid", value)
}
config.HypervisorConfig.JailerPath = value
}
if value, ok := ocispec.Annotations[vcAnnotations.CtlPath]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.HypervisorCtlPathList, value) {
return fmt.Errorf("hypervisor control %v required from annotation is not valid", value)
}
config.HypervisorConfig.HypervisorCtlPath = value
}
if value, ok := ocispec.Annotations[vcAnnotations.KernelParams]; ok {
if value != "" {
params := vc.DeserializeParams(strings.Fields(value))
for _, param := range params {
if err := config.HypervisorConfig.AddKernelParam(param); err != nil {
return fmt.Errorf("Error adding kernel parameters in annotation kernel_params : %v", err)
}
}
}
}
return nil
}
func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig, runtime RuntimeConfig) error {
if value, ok := ocispec.Annotations[vcAnnotations.DefaultMemory]; ok {
memorySz, err := strconv.ParseUint(value, 10, 32)
if err != nil {
@@ -525,6 +593,9 @@ func addHypervisorMemoryOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig
}
if value, ok := ocispec.Annotations[vcAnnotations.FileBackedMemRootDir]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.FileBackedMemRootList, value) {
return fmt.Errorf("file_mem_backend value %v required from annotation is not valid", value)
}
sbConfig.HypervisorConfig.FileBackedMemRootDir = value
}
@@ -661,7 +732,7 @@ func addHypervisorBlockOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig)
return nil
}
func addHypervisporVirtioFsOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) error {
func addHypervisorVirtioFsOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig, runtime RuntimeConfig) error {
if value, ok := ocispec.Annotations[vcAnnotations.SharedFS]; ok {
supportedSharedFS := []string{config.Virtio9P, config.VirtioFS}
valid := false
@@ -678,6 +749,9 @@ func addHypervisporVirtioFsOverrides(ocispec specs.Spec, sbConfig *vc.SandboxCon
}
if value, ok := ocispec.Annotations[vcAnnotations.VirtioFSDaemon]; ok {
if !checkPathIsInGlobs(runtime.HypervisorConfig.VirtioFSDaemonList, value) {
return fmt.Errorf("virtiofs daemon %v required from annotation is not valid", value)
}
sbConfig.HypervisorConfig.VirtioFSDaemon = value
}
@@ -745,7 +819,7 @@ func addHypervisporNetworkOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConf
return nil
}
func addRuntimeConfigOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig) error {
func addRuntimeConfigOverrides(ocispec specs.Spec, sbConfig *vc.SandboxConfig, runtime RuntimeConfig) error {
if value, ok := ocispec.Annotations[vcAnnotations.DisableGuestSeccomp]; ok {
disableGuestSeccomp, err := strconv.ParseBool(value)
if err != nil {
@@ -885,7 +959,7 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c
Experimental: runtime.Experimental,
}
if err := addAnnotations(ocispec, &sandboxConfig); err != nil {
if err := addAnnotations(ocispec, &sandboxConfig, runtime); err != nil {
return vc.SandboxConfig{}, err
}

View File

@@ -676,7 +676,25 @@ func TestAddAssetAnnotations(t *testing.T) {
Annotations: expectedAnnotations,
}
addAnnotations(ocispec, &config)
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
// Try annotations without enabling them first
err := addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
assert.Exactly(map[string]string{}, config.Annotations)
// Check if annotation not enabled correctly
runtimeConfig.HypervisorConfig.EnableAnnotations = []string{"nonexistent"}
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
// Check that it works if all annotation are enabled
runtimeConfig.HypervisorConfig.EnableAnnotations = []string{".*"}
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.NoError(err)
assert.Exactly(expectedAnnotations, config.Annotations)
}
@@ -700,9 +718,14 @@ func TestAddAgentAnnotations(t *testing.T) {
ContainerPipeSize: 1024,
}
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
ocispec.Annotations[vcAnnotations.KernelModules] = strings.Join(expectedAgentConfig.KernelModules, KernelModulesSeparator)
ocispec.Annotations[vcAnnotations.AgentContainerPipeSize] = "1024"
addAnnotations(ocispec, &config)
addAnnotations(ocispec, &config, runtimeConfig)
assert.Exactly(expectedAgentConfig, config.AgentConfig)
}
@@ -722,8 +745,13 @@ func TestContainerPipeSizeAnnotation(t *testing.T) {
ContainerPipeSize: 0,
}
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
ocispec.Annotations[vcAnnotations.AgentContainerPipeSize] = "foo"
err := addAnnotations(ocispec, &config)
err := addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
assert.Exactly(expectedAgentConfig, config.AgentConfig)
}
@@ -752,8 +780,16 @@ func TestAddHypervisorAnnotations(t *testing.T) {
},
}
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
runtimeConfig.HypervisorConfig.EnableAnnotations = []string{".*"}
runtimeConfig.HypervisorConfig.FileBackedMemRootList = []string{"/dev/shm*"}
runtimeConfig.HypervisorConfig.VirtioFSDaemonList = []string{"/bin/*ls*"}
ocispec.Annotations[vcAnnotations.KernelParams] = "vsyscall=emulate iommu=on"
addHypervisorConfigOverrides(ocispec, &config)
addHypervisorConfigOverrides(ocispec, &config, runtimeConfig)
assert.Exactly(expectedHyperConfig, config.HypervisorConfig)
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "1"
@@ -774,7 +810,7 @@ func TestAddHypervisorAnnotations(t *testing.T) {
ocispec.Annotations[vcAnnotations.BlockDeviceCacheDirect] = "true"
ocispec.Annotations[vcAnnotations.BlockDeviceCacheNoflush] = "true"
ocispec.Annotations[vcAnnotations.SharedFS] = "virtio-fs"
ocispec.Annotations[vcAnnotations.VirtioFSDaemon] = "/home/virtiofsd"
ocispec.Annotations[vcAnnotations.VirtioFSDaemon] = "/bin/false"
ocispec.Annotations[vcAnnotations.VirtioFSCache] = "/home/cache"
ocispec.Annotations[vcAnnotations.Msize9p] = "512"
ocispec.Annotations[vcAnnotations.MachineType] = "q35"
@@ -792,7 +828,7 @@ func TestAddHypervisorAnnotations(t *testing.T) {
ocispec.Annotations[vcAnnotations.RxRateLimiterMaxRate] = "10000000"
ocispec.Annotations[vcAnnotations.TxRateLimiterMaxRate] = "10000000"
addAnnotations(ocispec, &config)
addAnnotations(ocispec, &config, runtimeConfig)
assert.Equal(config.HypervisorConfig.NumVCPUs, uint32(1))
assert.Equal(config.HypervisorConfig.DefaultMaxVCPUs, uint32(1))
assert.Equal(config.HypervisorConfig.MemorySize, uint32(1024))
@@ -811,7 +847,7 @@ func TestAddHypervisorAnnotations(t *testing.T) {
assert.Equal(config.HypervisorConfig.BlockDeviceCacheDirect, true)
assert.Equal(config.HypervisorConfig.BlockDeviceCacheNoflush, true)
assert.Equal(config.HypervisorConfig.SharedFS, "virtio-fs")
assert.Equal(config.HypervisorConfig.VirtioFSDaemon, "/home/virtiofsd")
assert.Equal(config.HypervisorConfig.VirtioFSDaemon, "/bin/false")
assert.Equal(config.HypervisorConfig.VirtioFSCache, "/home/cache")
assert.Equal(config.HypervisorConfig.Msize9p, uint32(512))
assert.Equal(config.HypervisorConfig.HypervisorMachineType, "q35")
@@ -830,16 +866,77 @@ func TestAddHypervisorAnnotations(t *testing.T) {
// In case an absurd large value is provided, the config value if not over-ridden
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "655536"
err := addAnnotations(ocispec, &config)
err := addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "-1"
err = addAnnotations(ocispec, &config)
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "1"
ocispec.Annotations[vcAnnotations.DefaultMaxVCPUs] = "-1"
err = addAnnotations(ocispec, &config)
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultMaxVCPUs] = "1"
ocispec.Annotations[vcAnnotations.DefaultMemory] = fmt.Sprintf("%d", vc.MinHypervisorMemory+1)
assert.Error(err)
}
func TestAddProtectedHypervisorAnnotations(t *testing.T) {
assert := assert.New(t)
config := vc.SandboxConfig{
Annotations: make(map[string]string),
}
ocispec := specs.Spec{
Annotations: make(map[string]string),
}
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
ocispec.Annotations[vcAnnotations.KernelParams] = "vsyscall=emulate iommu=on"
err := addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
assert.Exactly(vc.HypervisorConfig{}, config.HypervisorConfig)
// Enable annotations
runtimeConfig.HypervisorConfig.EnableAnnotations = []string{".*"}
ocispec.Annotations[vcAnnotations.FileBackedMemRootDir] = "/dev/shm"
ocispec.Annotations[vcAnnotations.VirtioFSDaemon] = "/bin/false"
config.HypervisorConfig.FileBackedMemRootDir = "do-not-touch"
config.HypervisorConfig.VirtioFSDaemon = "dangerous-daemon"
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
assert.Equal(config.HypervisorConfig.FileBackedMemRootDir, "do-not-touch")
assert.Equal(config.HypervisorConfig.VirtioFSDaemon, "dangerous-daemon")
// Now enable them and check again
runtimeConfig.HypervisorConfig.FileBackedMemRootList = []string{"/dev/*m"}
runtimeConfig.HypervisorConfig.VirtioFSDaemonList = []string{"/bin/*ls*"}
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.NoError(err)
assert.Equal(config.HypervisorConfig.FileBackedMemRootDir, "/dev/shm")
assert.Equal(config.HypervisorConfig.VirtioFSDaemon, "/bin/false")
// In case an absurd large value is provided, the config value if not over-ridden
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "655536"
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "-1"
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultVCPUs] = "1"
ocispec.Annotations[vcAnnotations.DefaultMaxVCPUs] = "-1"
err = addAnnotations(ocispec, &config, runtimeConfig)
assert.Error(err)
ocispec.Annotations[vcAnnotations.DefaultMaxVCPUs] = "1"
@@ -858,18 +955,82 @@ func TestAddRuntimeAnnotations(t *testing.T) {
Annotations: make(map[string]string),
}
runtimeConfig := RuntimeConfig{
HypervisorType: vc.QemuHypervisor,
Console: consolePath,
}
ocispec.Annotations[vcAnnotations.DisableGuestSeccomp] = "true"
ocispec.Annotations[vcAnnotations.SandboxCgroupOnly] = "true"
ocispec.Annotations[vcAnnotations.DisableNewNetNs] = "true"
ocispec.Annotations[vcAnnotations.InterNetworkModel] = "macvtap"
addAnnotations(ocispec, &config)
addAnnotations(ocispec, &config, runtimeConfig)
assert.Equal(config.DisableGuestSeccomp, true)
assert.Equal(config.SandboxCgroupOnly, true)
assert.Equal(config.NetworkConfig.DisableNewNetNs, true)
assert.Equal(config.NetworkConfig.InterworkingModel, vc.NetXConnectMacVtapModel)
}
func TestRegexpContains(t *testing.T) {
assert := assert.New(t)
type testData struct {
regexps []string
toMatch string
expected bool
}
data := []testData{
{[]string{}, "", false},
{[]string{}, "nonempty", false},
{[]string{"simple"}, "simple", true},
{[]string{"simple"}, "some_simple_text", true},
{[]string{"simple"}, "simp", false},
{[]string{"one", "two"}, "one", true},
{[]string{"one", "two"}, "two", true},
{[]string{"o*"}, "oooo", true},
{[]string{"o*"}, "oooa", true},
{[]string{"^o*$"}, "oooa", false},
}
for _, d := range data {
matched := regexpContains(d.regexps, d.toMatch)
assert.Equal(d.expected, matched, "%+v", d)
}
}
func TestCheckPathIsInGlobs(t *testing.T) {
assert := assert.New(t)
type testData struct {
globs []string
toMatch string
expected bool
}
data := []testData{
{[]string{}, "", false},
{[]string{}, "nonempty", false},
{[]string{"simple"}, "simple", false},
{[]string{"simple"}, "some_simple_text", false},
{[]string{"/bin/ls"}, "/bin/ls", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/ls", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/false", true},
{[]string{"/bin/ls", "/bin/false"}, "/bin/bar", false},
{[]string{"/bin/*ls*"}, "/bin/ls", true},
{[]string{"/bin/*ls*"}, "/bin/false", true},
{[]string{"bin/ls"}, "/bin/ls", false},
{[]string{"./bin/ls"}, "/bin/ls", false},
{[]string{"*/bin/ls"}, "/bin/ls", false},
}
for _, d := range data {
matched := checkPathIsInGlobs(d.globs, d.toMatch)
assert.Equal(d.expected, matched, "%+v", d)
}
}
func TestIsCRIOContainerManager(t *testing.T) {
assert := assert.New(t)