mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-28 19:44:21 +01:00
Fixes #803 Simplify new store API to make the code easier to understand and use. Signed-off-by: Wei Zhang <zhangwei555@huawei.com>
288 lines
7.7 KiB
Go
288 lines
7.7 KiB
Go
// Copyright (c) 2018 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package types
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// StateString is a string representing a sandbox state.
|
|
type StateString string
|
|
|
|
const (
|
|
// StateReady represents a sandbox/container that's ready to be run
|
|
StateReady StateString = "ready"
|
|
|
|
// StateRunning represents a sandbox/container that's currently running.
|
|
StateRunning StateString = "running"
|
|
|
|
// StatePaused represents a sandbox/container that has been paused.
|
|
StatePaused StateString = "paused"
|
|
|
|
// StateStopped represents a sandbox/container that has been stopped.
|
|
StateStopped StateString = "stopped"
|
|
)
|
|
|
|
// SandboxState is a sandbox state structure
|
|
type SandboxState struct {
|
|
State StateString `json:"state"`
|
|
|
|
// Index of the block device passed to hypervisor.
|
|
BlockIndex int `json:"blockIndex"`
|
|
|
|
// GuestMemoryBlockSizeMB is the size of memory block of guestos
|
|
GuestMemoryBlockSizeMB uint32 `json:"guestMemoryBlockSize"`
|
|
|
|
// GuestMemoryHotplugProbe determines whether guest kernel supports memory hotplug probe interface
|
|
GuestMemoryHotplugProbe bool `json:"guestMemoryHotplugProbe"`
|
|
|
|
// CgroupPath is the cgroup hierarchy where sandbox's processes
|
|
// including the hypervisor are placed.
|
|
CgroupPath string `json:"cgroupPath,omitempty"`
|
|
|
|
// PersistVersion indicates current storage api version.
|
|
// It's also known as ABI version of kata-runtime.
|
|
// Note: it won't be written to disk
|
|
PersistVersion uint `json:"-"`
|
|
}
|
|
|
|
// Valid checks that the sandbox state is valid.
|
|
func (state *SandboxState) Valid() bool {
|
|
return state.State.valid()
|
|
}
|
|
|
|
// ValidTransition returns an error if we want to move to
|
|
// an unreachable state.
|
|
func (state *SandboxState) ValidTransition(oldState StateString, newState StateString) error {
|
|
return state.State.validTransition(oldState, newState)
|
|
}
|
|
|
|
func (state *StateString) valid() bool {
|
|
for _, validState := range []StateString{StateReady, StateRunning, StatePaused, StateStopped} {
|
|
if *state == validState {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func (state *StateString) validTransition(oldState StateString, newState StateString) error {
|
|
if *state != oldState {
|
|
return fmt.Errorf("Invalid state %v (Expecting %v)", state, oldState)
|
|
}
|
|
|
|
switch *state {
|
|
case StateReady:
|
|
if newState == StateRunning || newState == StateStopped {
|
|
return nil
|
|
}
|
|
|
|
case StateRunning:
|
|
if newState == StatePaused || newState == StateStopped {
|
|
return nil
|
|
}
|
|
|
|
case StatePaused:
|
|
if newState == StateRunning || newState == StateStopped {
|
|
return nil
|
|
}
|
|
|
|
case StateStopped:
|
|
if newState == StateRunning {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("Can not move from %v to %v",
|
|
state, newState)
|
|
}
|
|
|
|
// Volume is a shared volume between the host and the VM,
|
|
// defined by its mount tag and its host path.
|
|
type Volume struct {
|
|
// MountTag is a label used as a hint to the guest.
|
|
MountTag string
|
|
|
|
// HostPath is the host filesystem path for this volume.
|
|
HostPath string
|
|
}
|
|
|
|
// Volumes is a Volume list.
|
|
type Volumes []Volume
|
|
|
|
// Set assigns volume values from string to a Volume.
|
|
func (v *Volumes) Set(volStr string) error {
|
|
if volStr == "" {
|
|
return fmt.Errorf("volStr cannot be empty")
|
|
}
|
|
|
|
volSlice := strings.Split(volStr, " ")
|
|
const expectedVolLen = 2
|
|
const volDelimiter = ":"
|
|
|
|
for _, vol := range volSlice {
|
|
volArgs := strings.Split(vol, volDelimiter)
|
|
|
|
if len(volArgs) != expectedVolLen {
|
|
return fmt.Errorf("Wrong string format: %s, expecting only %v parameters separated with %q",
|
|
vol, expectedVolLen, volDelimiter)
|
|
}
|
|
|
|
if volArgs[0] == "" || volArgs[1] == "" {
|
|
return fmt.Errorf("Volume parameters cannot be empty")
|
|
}
|
|
|
|
volume := Volume{
|
|
MountTag: volArgs[0],
|
|
HostPath: volArgs[1],
|
|
}
|
|
|
|
*v = append(*v, volume)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// String converts a Volume to a string.
|
|
func (v *Volumes) String() string {
|
|
var volSlice []string
|
|
|
|
for _, volume := range *v {
|
|
volSlice = append(volSlice, fmt.Sprintf("%s:%s", volume.MountTag, volume.HostPath))
|
|
}
|
|
|
|
return strings.Join(volSlice, " ")
|
|
}
|
|
|
|
// Socket defines a socket to communicate between
|
|
// the host and any process inside the VM.
|
|
type Socket struct {
|
|
DeviceID string
|
|
ID string
|
|
HostPath string
|
|
Name string
|
|
}
|
|
|
|
// Sockets is a Socket list.
|
|
type Sockets []Socket
|
|
|
|
// Set assigns socket values from string to a Socket.
|
|
func (s *Sockets) Set(sockStr string) error {
|
|
if sockStr == "" {
|
|
return fmt.Errorf("sockStr cannot be empty")
|
|
}
|
|
|
|
sockSlice := strings.Split(sockStr, " ")
|
|
const expectedSockCount = 4
|
|
const sockDelimiter = ":"
|
|
|
|
for _, sock := range sockSlice {
|
|
sockArgs := strings.Split(sock, sockDelimiter)
|
|
|
|
if len(sockArgs) != expectedSockCount {
|
|
return fmt.Errorf("Wrong string format: %s, expecting only %v parameters separated with %q", sock, expectedSockCount, sockDelimiter)
|
|
}
|
|
|
|
for _, a := range sockArgs {
|
|
if a == "" {
|
|
return fmt.Errorf("Socket parameters cannot be empty")
|
|
}
|
|
}
|
|
|
|
socket := Socket{
|
|
DeviceID: sockArgs[0],
|
|
ID: sockArgs[1],
|
|
HostPath: sockArgs[2],
|
|
Name: sockArgs[3],
|
|
}
|
|
|
|
*s = append(*s, socket)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// String converts a Socket to a string.
|
|
func (s *Sockets) String() string {
|
|
var sockSlice []string
|
|
|
|
for _, sock := range *s {
|
|
sockSlice = append(sockSlice, fmt.Sprintf("%s:%s:%s:%s", sock.DeviceID, sock.ID, sock.HostPath, sock.Name))
|
|
}
|
|
|
|
return strings.Join(sockSlice, " ")
|
|
}
|
|
|
|
// EnvVar is a key/value structure representing a command
|
|
// environment variable.
|
|
type EnvVar struct {
|
|
Var string
|
|
Value string
|
|
}
|
|
|
|
// LinuxCapabilities specify the capabilities to keep when executing
|
|
// the process inside the container.
|
|
type LinuxCapabilities struct {
|
|
// Bounding is the set of capabilities checked by the kernel.
|
|
Bounding []string
|
|
// Effective is the set of capabilities checked by the kernel.
|
|
Effective []string
|
|
// Inheritable is the capabilities preserved across execve.
|
|
Inheritable []string
|
|
// Permitted is the limiting superset for effective capabilities.
|
|
Permitted []string
|
|
// Ambient is the ambient set of capabilities that are kept.
|
|
Ambient []string
|
|
}
|
|
|
|
// Cmd represents a command to execute in a running container.
|
|
type Cmd struct {
|
|
Args []string
|
|
Envs []EnvVar
|
|
SupplementaryGroups []string
|
|
|
|
// Note that these fields *MUST* remain as strings.
|
|
//
|
|
// The reason being that we want runtimes to be able to support CLI
|
|
// operations like "exec --user=". That option allows the
|
|
// specification of a user (either as a string username or a numeric
|
|
// UID), and may optionally also include a group (groupame or GID).
|
|
//
|
|
// Since this type is the interface to allow the runtime to specify
|
|
// the user and group the workload can run as, these user and group
|
|
// fields cannot be encoded as integer values since that would imply
|
|
// the runtime itself would need to perform a UID/GID lookup on the
|
|
// user-specified username/groupname. But that isn't practically
|
|
// possible given that to do so would require the runtime to access
|
|
// the image to allow it to interrogate the appropriate databases to
|
|
// convert the username/groupnames to UID/GID values.
|
|
//
|
|
// Note that this argument applies solely to the _runtime_ supporting
|
|
// a "--user=" option when running in a "standalone mode" - there is
|
|
// no issue when the runtime is called by a container manager since
|
|
// all the user and group mapping is handled by the container manager
|
|
// and specified to the runtime in terms of UID/GID's in the
|
|
// configuration file generated by the container manager.
|
|
User string
|
|
PrimaryGroup string
|
|
WorkDir string
|
|
Console string
|
|
Capabilities LinuxCapabilities
|
|
|
|
Interactive bool
|
|
Detach bool
|
|
NoNewPrivileges bool
|
|
}
|
|
|
|
// Resources describes VM resources configuration.
|
|
type Resources struct {
|
|
// Memory is the amount of available memory in MiB.
|
|
Memory uint
|
|
MemorySlots uint8
|
|
}
|