Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
virtcontainers: First types package
Browse files Browse the repository at this point in the history
The types package holds all shared virtcontainers types.
With the separation of the virtcontainers code into separate packages,
we need a types one to not create circular dependencies.

This package holds sandbox related types and structures for now. It will
grow as virtcontainers code is moved into their own internal packages.

Signed-off-by: Samuel Ortiz <[email protected]>
  • Loading branch information
Samuel Ortiz committed Jan 8, 2019
1 parent 3ab7d07 commit 701afe9
Showing 1 changed file with 275 additions and 0 deletions.
275 changes: 275 additions & 0 deletions virtcontainers/types/sandbox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
// 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"
)

// State is a sandbox state structure.
type State struct {
State stateString `json:"state"`

BlockDeviceID string
// Index of the block device passed to hypervisor.
BlockIndex int `json:"blockIndex"`

// File system of the rootfs incase it is block device
Fstype string `json:"fstype"`

// Pid is the process id of the sandbox container which is the first
// container to be started.
Pid int `json:"pid"`

// GuestMemoryBlockSizeMB is the size of memory block of guestos
GuestMemoryBlockSizeMB uint32 `json:"guestMemoryBlockSize"`
}

// valid checks that the sandbox state is valid.
func (state *State) valid() bool {
for _, validState := range []stateString{StateReady, StateRunning, StatePaused, StateStopped} {
if state.State == validState {
return true
}
}

return false
}

// validTransition returns an error if we want to move to
// an unreachable state.
func (state *State) validTransition(oldState stateString, newState stateString) error {
if state.State != oldState {
return fmt.Errorf("Invalid state %s (Expecting %s)", state.State, oldState)
}

switch state.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 %s to %s",
state.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
}

0 comments on commit 701afe9

Please sign in to comment.