runtime: Run QEMU using a non-root user/group

A random generated user/group is used to start QEMU VMM process.
The /dev/kvm group owner is also added to the QEMU process to grant it access.

Fixes #2444

Signed-off-by: Feng Wang <feng.wang@databricks.com>
This commit is contained in:
Feng Wang
2021-08-09 15:29:49 -07:00
parent fff82b4ef5
commit 1cfe59304d
17 changed files with 505 additions and 9 deletions

View File

@@ -10,6 +10,7 @@ import (
"io/ioutil"
"net/http"
"os"
"path"
"testing"
"github.com/stretchr/testify/assert"
@@ -117,3 +118,80 @@ func TestEnsureDir(t *testing.T) {
}
}
}
func TestFirstValidExecutable(t *testing.T) {
assert := assert.New(t)
tmpdir, err := ioutil.TempDir("", "TestFirstValidPath")
assert.NoError(err)
defer os.RemoveAll(tmpdir)
// nolint: govet
testCases := []struct {
before func()
paths []string
validPath string
isValid bool
msg string
}{
{
before: nil,
paths: []string{"a/b/c", "c/d"},
validPath: "",
isValid: false,
msg: "all the executables are invalid",
},
{
before: func() {
err := os.MkdirAll(path.Join(tmpdir, "a", "b"), 0755)
assert.NoError(err)
// create a non-executable file
err = ioutil.WriteFile(path.Join(tmpdir, "a", "b", "c"), []byte("test\n"), 0644)
assert.NoError(err)
},
paths: []string{path.Join(tmpdir, "a", "b", "c"), "c/d"},
validPath: "",
isValid: false,
msg: "all the executables are invalid",
},
{
before: func() {
err := os.MkdirAll(path.Join(tmpdir, "d", "e"), 0755)
assert.NoError(err)
// create an executable file
err = ioutil.WriteFile(path.Join(tmpdir, "d", "e", "f"), []byte("test\n"), 0755)
assert.NoError(err)
},
paths: []string{path.Join(tmpdir, "d", "e", "f"), "c/d"},
validPath: fmt.Sprintf("%s/d/e/f", tmpdir),
isValid: true,
msg: "",
},
{
before: func() {
err := os.MkdirAll(path.Join(tmpdir, "g", "h"), 0755)
assert.NoError(err)
// create an executable file
err = ioutil.WriteFile(path.Join(tmpdir, "g", "h", "i"), []byte("test\n"), 0755)
assert.NoError(err)
},
paths: []string{"c/d", path.Join(tmpdir, "g", "h", "i")},
validPath: path.Join(tmpdir, "g", "h", "i"),
isValid: true,
msg: "",
},
}
for _, tc := range testCases {
if tc.before != nil {
tc.before()
}
path, err := FirstValidExecutable(tc.paths)
assert.Equal(tc.isValid, err == nil)
if tc.isValid {
assert.Equal(tc.validPath, path)
} else {
assert.Equal(err.Error(), tc.msg)
assert.Equal(tc.validPath, "")
}
}
}