Merge pull request #3774 from egernst/delinux-runtime

cleanup runtime pkgs for Darwin build, add basic Darwin build/unit test
This commit is contained in:
GabyCT 2022-02-28 15:08:09 -06:00 committed by GitHub
commit bc1733bb0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 264 additions and 117 deletions

25
.github/workflows/darwin-tests.yaml vendored Normal file
View File

@ -0,0 +1,25 @@
on:
pull_request:
types:
- opened
- edited
- reopened
- synchronize
name: Darwin tests
jobs:
test:
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
os: [macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Build utils
run: ./ci/darwin-test.sh

42
ci/darwin-test.sh Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env bash
#
# Copyright (c) 2022 Apple Inc.
#
# SPDX-License-Identifier: Apache-2.0
set -e
cidir=$(dirname "$0")
runtimedir=$cidir/../src/runtime
build_working_packages() {
# working packages:
device_api=$runtimedir/virtcontainers/device/api
device_config=$runtimedir/virtcontainers/device/config
device_drivers=$runtimedir/virtcontainers/device/drivers
device_manager=$runtimedir/virtcontainers/device/manager
rc_pkg_dir=$runtimedir/pkg/resourcecontrol/
utils_pkg_dir=$runtimedir/virtcontainers/utils
# broken packages :( :
#katautils=$runtimedir/pkg/katautils
#oci=$runtimedir/pkg/oci
#vc=$runtimedir/virtcontainers
pkgs=(
"$device_api"
"$device_config"
"$device_drivers"
"$device_manager"
"$utils_pkg_dir"
"$rc_pkg_dir")
for pkg in "${pkgs[@]}"; do
echo building "$pkg"
pushd "$pkg" &>/dev/null
go build
go test
popd &>/dev/null
done
}
build_working_packages

View File

@ -16,6 +16,7 @@ import (
"time"
"github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace"
syscallWrapper "github.com/kata-containers/kata-containers/src/runtime/pkg/syscall"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)
@ -38,7 +39,7 @@ func runHook(ctx context.Context, spec specs.Spec, hook specs.Hook, cid, bundleP
katatrace.AddTags(span, "path", hook.Path, "args", hook.Args)
state := specs.State{
Pid: syscall.Gettid(),
Pid: syscallWrapper.Gettid(),
Bundle: bundlePath,
ID: cid,
Annotations: spec.Annotations,

View File

@ -0,0 +1,22 @@
// Copyright (c) 2022 Apple Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package katautils
import (
vc "github.com/kata-containers/kata-containers/src/runtime/virtcontainers"
)
func EnterNetNS(networkID string, cb func() error) error {
return nil
}
func SetupNetworkNamespace(config *vc.NetworkConfig) error {
return nil
}
func cleanupNetNS(netNSPath string) error {
return nil
}

View File

@ -7,6 +7,7 @@ package resourcecontrol
import (
"fmt"
"strings"
"github.com/opencontainers/runc/libcontainer/devices"
"github.com/opencontainers/runtime-spec/specs-go"
@ -35,8 +36,8 @@ func DeviceToCgroupDeviceRule(device string) (*devices.Rule, error) {
return nil, fmt.Errorf("unsupported device type: %v", devType)
}
major := int64(unix.Major(st.Rdev))
minor := int64(unix.Minor(st.Rdev))
major := int64(unix.Major(uint64(st.Rdev)))
minor := int64(unix.Minor(uint64(st.Rdev)))
deviceRule.Major = major
deviceRule.Minor = minor
@ -57,3 +58,20 @@ func DeviceToLinuxDevice(device string) (specs.LinuxDeviceCgroup, error) {
Access: string(dev.Permissions),
}, nil
}
func IsSystemdCgroup(cgroupPath string) bool {
// If we are utilizing systemd to manage cgroups, we expect to receive a path
// in the format slice:scopeprefix:name. A typical example would be:
//
// system.slice:docker:6b4c4a4d0cc2a12c529dcb13a2b8e438dfb3b2a6af34d548d7d
//
// Based on this, let's split by the ':' delimiter and verify that the first
// section has .slice as a suffix.
parts := strings.Split(cgroupPath, ":")
if len(parts) == 3 && strings.HasSuffix(parts[0], ".slice") {
return true
}
return false
}

View File

@ -43,23 +43,6 @@ func ValidCgroupPath(path string, systemdCgroup bool) (string, error) {
return filepath.Join(DefaultResourceControllerID, filepath.Clean("/"+path)), nil
}
func IsSystemdCgroup(cgroupPath string) bool {
// If we are utilizing systemd to manage cgroups, we expect to receive a path
// in the format slice:scopeprefix:name. A typical example would be:
//
// system.slice:docker:6b4c4a4d0cc2a12c529dcb13a2b8e438dfb3b2a6af34d548d7d
//
// Based on this, let's split by the ':' delimiter and verify that the first
// section has .slice as a suffix.
parts := strings.Split(cgroupPath, ":")
if len(parts) == 3 && strings.HasSuffix(parts[0], ".slice") {
return true
}
return false
}
func newProperty(name string, units interface{}) systemdDbus.Property {
return systemdDbus.Property{
Name: name,

View File

@ -0,0 +1,16 @@
// Copyright (c) 2022 Apple Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package syscall
import (
"syscall"
)
func Gettid() int {
// There is no equivalent to a thread ID on Darwin.
// We use the PID instead.
return syscall.Getpid()
}

View File

@ -0,0 +1,14 @@
// Copyright (c) 2022 Apple Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package syscall
import (
"syscall"
)
func Gettid() int {
return syscall.Gettid()
}

View File

@ -1,6 +1,3 @@
//go:build linux
// +build linux
// Copyright (c) 2016 Intel Corporation
// Copyright (c) 2014,2015,2016,2017 Docker, Inc.
// SPDX-License-Identifier: Apache-2.0
@ -629,8 +626,8 @@ func (c *Container) createBlockDevices(ctx context.Context) error {
HostPath: m.Source,
ContainerPath: m.Destination,
DevType: "b",
Major: int64(unix.Major(stat.Rdev)),
Minor: int64(unix.Minor(stat.Rdev)),
Major: int64(unix.Major(uint64(stat.Rdev))),
Minor: int64(unix.Minor(uint64(stat.Rdev))),
ReadOnly: m.ReadOnly,
}
// Check whether source can be used as a pmem device
@ -1226,8 +1223,8 @@ func (c *Container) plugDevice(ctx context.Context, devicePath string) error {
HostPath: devicePath,
ContainerPath: filepath.Join(kataGuestSharedDir(), c.id),
DevType: "b",
Major: int64(unix.Major(stat.Rdev)),
Minor: int64(unix.Minor(stat.Rdev)),
Major: int64(unix.Major(uint64(stat.Rdev))),
Minor: int64(unix.Minor(uint64(stat.Rdev))),
})
if err != nil {
return fmt.Errorf("device manager failed to create rootfs device for %q: %v", devicePath, err)

View File

@ -425,8 +425,8 @@ func getVhostUserDevName(dirname string, majorNum, minorNum uint32) (string, err
return "", err
}
devMajor := unix.Major(devStat.Rdev)
devMinor := unix.Minor(devStat.Rdev)
devMajor := unix.Major(uint64(devStat.Rdev))
devMinor := unix.Minor(uint64(devStat.Rdev))
if devMajor == majorNum && devMinor == minorNum {
return file.Name(), nil
}

View File

@ -51,8 +51,8 @@ func PmemDeviceInfo(source, destination string) (*DeviceInfo, error) {
device := &DeviceInfo{
ContainerPath: destination,
DevType: "b",
Major: int64(unix.Major(stat.Dev)),
Minor: int64(unix.Minor(stat.Dev)),
Major: int64(unix.Major(uint64(stat.Dev))),
Minor: int64(unix.Minor(uint64(stat.Dev))),
Pmem: true,
DriverOptions: make(map[string]string),
}

View File

@ -0,0 +1,100 @@
// Copyright (c) 2017 Intel Corporation
// Copyright (c) 2018 Huawei Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package manager
import (
"context"
"fmt"
"os"
"path/filepath"
"testing"
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers"
"github.com/stretchr/testify/assert"
"golang.org/x/sys/unix"
)
func TestAttachVhostUserBlkDevice(t *testing.T) {
rootEnabled := true
tc := ktu.NewTestConstraint(false)
if tc.NotValid(ktu.NeedRoot()) {
rootEnabled = false
}
tmpDir, err := os.MkdirTemp("", "")
dm := &deviceManager{
blockDriver: VirtioBlock,
devices: make(map[string]api.Device),
vhostUserStoreEnabled: true,
vhostUserStorePath: tmpDir,
}
assert.Nil(t, err)
defer os.RemoveAll(tmpDir)
vhostUserDevNodePath := filepath.Join(tmpDir, "/block/devices/")
vhostUserSockPath := filepath.Join(tmpDir, "/block/sockets/")
deviceNodePath := filepath.Join(vhostUserDevNodePath, "vhostblk0")
deviceSockPath := filepath.Join(vhostUserSockPath, "vhostblk0")
err = os.MkdirAll(vhostUserDevNodePath, dirMode)
assert.Nil(t, err)
err = os.MkdirAll(vhostUserSockPath, dirMode)
assert.Nil(t, err)
_, err = os.Create(deviceSockPath)
assert.Nil(t, err)
// mknod requires root privilege, call mock function for non-root to
// get VhostUserBlk device type.
if rootEnabled == true {
err = unix.Mknod(deviceNodePath, unix.S_IFBLK, int(unix.Mkdev(config.VhostUserBlkMajor, 0)))
assert.Nil(t, err)
} else {
savedFunc := config.GetVhostUserNodeStatFunc
_, err = os.Create(deviceNodePath)
assert.Nil(t, err)
config.GetVhostUserNodeStatFunc = func(devNodePath string,
devNodeStat *unix.Stat_t) error {
if deviceNodePath != devNodePath {
return fmt.Errorf("mock GetVhostUserNodeStatFunc error")
}
devNodeStat.Rdev = unix.Mkdev(config.VhostUserBlkMajor, 0)
return nil
}
defer func() {
config.GetVhostUserNodeStatFunc = savedFunc
}()
}
path := "/dev/vda"
deviceInfo := config.DeviceInfo{
HostPath: deviceNodePath,
ContainerPath: path,
DevType: "b",
Major: config.VhostUserBlkMajor,
Minor: 0,
}
devReceiver := &api.MockDeviceReceiver{}
device, err := dm.NewDevice(deviceInfo)
assert.Nil(t, err)
_, ok := device.(*drivers.VhostUserBlkDevice)
assert.True(t, ok)
err = device.Attach(context.Background(), devReceiver)
assert.Nil(t, err)
err = device.Detach(context.Background(), devReceiver)
assert.Nil(t, err)
}

View File

@ -8,19 +8,15 @@ package manager
import (
"context"
"fmt"
"os"
"path/filepath"
"strconv"
"testing"
ktu "github.com/kata-containers/kata-containers/src/runtime/pkg/katatestutils"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/api"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/config"
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/device/drivers"
"github.com/stretchr/testify/assert"
"golang.org/x/sys/unix"
)
const fileMode0640 = os.FileMode(0640)
@ -217,83 +213,6 @@ func TestAttachBlockDevice(t *testing.T) {
assert.Nil(t, err)
}
func TestAttachVhostUserBlkDevice(t *testing.T) {
rootEnabled := true
tc := ktu.NewTestConstraint(false)
if tc.NotValid(ktu.NeedRoot()) {
rootEnabled = false
}
tmpDir, err := os.MkdirTemp("", "")
dm := &deviceManager{
blockDriver: VirtioBlock,
devices: make(map[string]api.Device),
vhostUserStoreEnabled: true,
vhostUserStorePath: tmpDir,
}
assert.Nil(t, err)
defer os.RemoveAll(tmpDir)
vhostUserDevNodePath := filepath.Join(tmpDir, "/block/devices/")
vhostUserSockPath := filepath.Join(tmpDir, "/block/sockets/")
deviceNodePath := filepath.Join(vhostUserDevNodePath, "vhostblk0")
deviceSockPath := filepath.Join(vhostUserSockPath, "vhostblk0")
err = os.MkdirAll(vhostUserDevNodePath, dirMode)
assert.Nil(t, err)
err = os.MkdirAll(vhostUserSockPath, dirMode)
assert.Nil(t, err)
_, err = os.Create(deviceSockPath)
assert.Nil(t, err)
// mknod requires root privilege, call mock function for non-root to
// get VhostUserBlk device type.
if rootEnabled == true {
err = unix.Mknod(deviceNodePath, unix.S_IFBLK, int(unix.Mkdev(config.VhostUserBlkMajor, 0)))
assert.Nil(t, err)
} else {
savedFunc := config.GetVhostUserNodeStatFunc
_, err = os.Create(deviceNodePath)
assert.Nil(t, err)
config.GetVhostUserNodeStatFunc = func(devNodePath string,
devNodeStat *unix.Stat_t) error {
if deviceNodePath != devNodePath {
return fmt.Errorf("mock GetVhostUserNodeStatFunc error")
}
devNodeStat.Rdev = unix.Mkdev(config.VhostUserBlkMajor, 0)
return nil
}
defer func() {
config.GetVhostUserNodeStatFunc = savedFunc
}()
}
path := "/dev/vda"
deviceInfo := config.DeviceInfo{
HostPath: deviceNodePath,
ContainerPath: path,
DevType: "b",
Major: config.VhostUserBlkMajor,
Minor: 0,
}
devReceiver := &api.MockDeviceReceiver{}
device, err := dm.NewDevice(deviceInfo)
assert.Nil(t, err)
_, ok := device.(*drivers.VhostUserBlkDevice)
assert.True(t, ok)
err = device.Attach(context.Background(), devReceiver)
assert.Nil(t, err)
err = device.Detach(context.Background(), devReceiver)
assert.Nil(t, err)
}
func TestAttachDetachDevice(t *testing.T) {
dm := NewDeviceManager(VirtioSCSI, false, "", nil)

View File

@ -2084,7 +2084,7 @@ func (k *kataAgent) copyFile(ctx context.Context, src, dst string) error {
cpReq := &grpc.CopyFileRequest{
Path: dst,
DirMode: uint32(DirMode),
FileMode: st.Mode,
FileMode: uint32(st.Mode),
FileSize: fileSize,
Uid: int32(st.Uid),
Gid: int32(st.Gid),

View File

@ -144,8 +144,8 @@ func getDeviceForPath(path string) (device, error) {
if isHostDevice(path) {
// stat.Rdev describes the device that this file (inode) represents.
devMajor = major(stat.Rdev)
devMinor = minor(stat.Rdev)
devMajor = major(uint64(stat.Rdev))
devMinor = minor(uint64(stat.Rdev))
return device{
major: devMajor,
@ -154,8 +154,8 @@ func getDeviceForPath(path string) (device, error) {
}, nil
}
// stat.Dev points to the underlying device containing the file
devMajor = major(stat.Dev)
devMinor = minor(stat.Dev)
devMajor = major(uint64(stat.Dev))
devMinor = minor(uint64(stat.Dev))
path, err = filepath.Abs(path)
if err != nil {

View File

@ -0,0 +1,10 @@
// Copyright (c) 2022 Apple Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
package utils
func GetDevicePathAndFsTypeOptions(mountPoint string) (devicePath, fsType string, fsOptions []string, err error) {
return
}