mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-18 23:04:20 +01:00
Change io/ioutil to io/os packages because io/ioutil package is deprecated from 1.16: Discard => io.Discard NopCloser => io.NopCloser ReadAll => io.ReadAll ReadDir => os.ReadDir ReadFile => os.ReadFile TempDir => os.MkdirTemp TempFile => os.CreateTemp WriteFile => os.WriteFile Details: https://go.dev/doc/go1.16#ioutil Fixes: #3265 Signed-off-by: bin <bin@hyper.sh>
159 lines
4.2 KiB
Go
159 lines
4.2 KiB
Go
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package compatoci
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
"github.com/sirupsen/logrus"
|
|
|
|
vcAnnotations "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations"
|
|
)
|
|
|
|
var ociLog = logrus.WithFields(logrus.Fields{
|
|
"source": "virtcontainers",
|
|
"subsystem": "compatoci",
|
|
})
|
|
|
|
// compatOCIProcess is a structure inheriting from specs.Process defined
|
|
// in runtime-spec/specs-go package. The goal is to be compatible with
|
|
// both v1.0.0-rc4 and v1.0.0-rc5 since the latter introduced a change
|
|
// about the type of the Capabilities field.
|
|
// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
|
|
type compatOCIProcess struct {
|
|
Capabilities interface{} `json:"capabilities,omitempty" platform:"linux"` //nolint:govet
|
|
specs.Process
|
|
}
|
|
|
|
// compatOCISpec is a structure inheriting from specs.Spec defined
|
|
// in runtime-spec/specs-go package. It relies on the compatOCIProcess
|
|
// structure declared above, in order to be compatible with both
|
|
// v1.0.0-rc4 and v1.0.0-rc5.
|
|
// Refer to: https://github.com/opencontainers/runtime-spec/commit/37391fb
|
|
type compatOCISpec struct {
|
|
specs.Spec
|
|
Process *compatOCIProcess `json:"process,omitempty"` //nolint:govet
|
|
}
|
|
|
|
func containerCapabilities(s compatOCISpec) (specs.LinuxCapabilities, error) {
|
|
capabilities := s.Process.Capabilities
|
|
var c specs.LinuxCapabilities
|
|
|
|
// In spec v1.0.0-rc4, capabilities was a list of strings. This was changed
|
|
// to an object with v1.0.0-rc5.
|
|
// Check for the interface type to support both the versions.
|
|
switch caps := capabilities.(type) {
|
|
case map[string]interface{}:
|
|
for key, value := range caps {
|
|
switch val := value.(type) {
|
|
case []interface{}:
|
|
var list []string
|
|
|
|
for _, str := range val {
|
|
list = append(list, str.(string))
|
|
}
|
|
|
|
switch key {
|
|
case "bounding":
|
|
c.Bounding = list
|
|
case "effective":
|
|
c.Effective = list
|
|
case "inheritable":
|
|
c.Inheritable = list
|
|
case "ambient":
|
|
c.Ambient = list
|
|
case "permitted":
|
|
c.Permitted = list
|
|
}
|
|
|
|
default:
|
|
return c, fmt.Errorf("Unexpected format for capabilities: %v", caps)
|
|
}
|
|
}
|
|
case []interface{}:
|
|
var list []string
|
|
for _, str := range caps {
|
|
list = append(list, str.(string))
|
|
}
|
|
|
|
c = specs.LinuxCapabilities{
|
|
Bounding: list,
|
|
Effective: list,
|
|
Inheritable: list,
|
|
Ambient: list,
|
|
Permitted: list,
|
|
}
|
|
case nil:
|
|
ociLog.Debug("Empty capabilities have been passed")
|
|
return c, nil
|
|
default:
|
|
return c, fmt.Errorf("Unexpected format for capabilities: %v", caps)
|
|
}
|
|
|
|
return c, nil
|
|
}
|
|
|
|
// SetLogger sets up a logger for this pkg
|
|
func SetLogger(logger *logrus.Entry) {
|
|
fields := ociLog.Data
|
|
|
|
ociLog = logger.WithFields(fields)
|
|
}
|
|
|
|
// ContainerCapabilities return a LinuxCapabilities for virtcontainer
|
|
func ContainerCapabilities(s compatOCISpec) (specs.LinuxCapabilities, error) {
|
|
if s.Process == nil {
|
|
return specs.LinuxCapabilities{}, fmt.Errorf("ContainerCapabilities, Process is nil")
|
|
}
|
|
return containerCapabilities(s)
|
|
}
|
|
|
|
// getConfigPath returns the full config path from the bundle
|
|
// path provided.
|
|
func getConfigPath(bundlePath string) string {
|
|
return filepath.Join(bundlePath, "config.json")
|
|
}
|
|
|
|
// ParseConfigJSON unmarshals the config.json file.
|
|
func ParseConfigJSON(bundlePath string) (specs.Spec, error) {
|
|
configPath := getConfigPath(bundlePath)
|
|
ociLog.Debugf("converting %s", configPath)
|
|
|
|
configByte, err := os.ReadFile(configPath)
|
|
if err != nil {
|
|
return specs.Spec{}, err
|
|
}
|
|
|
|
var compSpec compatOCISpec
|
|
if err := json.Unmarshal(configByte, &compSpec); err != nil {
|
|
return specs.Spec{}, err
|
|
}
|
|
|
|
caps, err := ContainerCapabilities(compSpec)
|
|
if err != nil {
|
|
return specs.Spec{}, err
|
|
}
|
|
|
|
compSpec.Spec.Process = &compSpec.Process.Process
|
|
compSpec.Spec.Process.Capabilities = &caps
|
|
|
|
return compSpec.Spec, nil
|
|
}
|
|
|
|
func GetContainerSpec(annotations map[string]string) (specs.Spec, error) {
|
|
if bundlePath, ok := annotations[vcAnnotations.BundlePathKey]; ok {
|
|
return ParseConfigJSON(bundlePath)
|
|
}
|
|
|
|
ociLog.Errorf("Annotations[%s] not found, cannot find container spec",
|
|
vcAnnotations.BundlePathKey)
|
|
return specs.Spec{}, fmt.Errorf("Could not find container spec")
|
|
}
|