api

package
v0.0.0-...-3cebe5e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2018 License: Apache-2.0 Imports: 5 Imported by: 4

Documentation

Overview

Package api defines the API cc-proxy exposes to clients (processes connecting to the proxy AF_UNIX socket).

This package contains the low level definitions of the protocol, frame structure and the various payloads that can be sent and received.

The proxy protocol is composed of commands, responses and notifications. They all share the same frame structure: a header followed by an optional payload.

• Commands are always initiated by a client, never by the proxy itself.

• Responses are sent by the proxy to acknowledge commands.

• Notifications are sent by either the proxy or clients and do not generate responses.

Frame Structure

The frame format is illustrated below:

                    1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
0 1 2 3 4 5 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────────────────────────┬───────────────┬───────────────┐
│          Version          │ Header Length │   Reserved    │
├───────────────────────────┼─────┬─┬───────┼───────────────┤
│          Reserved         │ Res.│E│ Type  │    Opcode     │
├───────────────────────────┴─────┴─┴───────┴───────────────┤
│                      Payload Length                       │
├───────────────────────────────────────────────────────────┤
│                                                           │
│                         Payload                           │
│                                                           │
│      (variable length, optional and opcode-specific)      │
│                                                           │
└───────────────────────────────────────────────────────────┘

All header fields are encoded in network order (big endian).

• Version (16 bits) is the proxy protocol version. See api.Version for details about what information it encodes.

• Header Length (8 bits) is the length of the header in number of 32-bit words. Header Length is greater or equal to 3 (12 bytes).

• Type (4 bits) is the frame type: command (0x0), response (0x1), stream (0x2) or notification (0x3).

• Opcode (8 bits) specifies the kind of command, response, stream or notification this frame represents. In conjunction with Type, this field will dictate the payload content.

• E, Error. This flag is set when a response returns an error. Currently Error can ony be set in response frames.

• Payload Length (32 bits) is in bytes.

• Payload is optional data that can be sent with the various frames. Commands, responses and notifications usually encode their payloads in JSON while stream frames have raw data payloads.

• Reserved fields are reserved for future use and must be zeroed.

Frame Size and Header Length

The full size of a frame is (Header Length + Payload Length). The Payload starts at offset Header Length from the start of the frame.

It is guaranteed that future header sizes will be at least 12 bytes.

Index

Constants

View Source
const (
	// NotificationProcessExited is sent to signal a process in the VM has exited.
	NotificationProcessExited = iota
	// NotificationMax is the number of notification types.
	NotificationMax
)
View Source
const Version = 2

Version encodes the proxy protocol version.

List of changes:

  • version 2: initial version released with Clear Containers 3.0

    ⚠⚠⚠ backward incompatible with version 1 ⚠⚠⚠

    List of changes:

  • Changed the frame header to include additional fields: version, header length, type and opcode.

  • Added a log messages for clients to insert log entries to the consolidated proxy log.

  • version 1: initial version released with Clear Containers 2.1

Variables

This section is empty.

Functions

func WriteCommand

func WriteCommand(w io.Writer, op Command, payload []byte) error

WriteCommand is a convenience wrapper around WriteFrame to send commands.

func WriteFrame

func WriteFrame(w io.Writer, frame *Frame) error

WriteFrame writes a frame into w.

Note that frame.Header.PayloadLength dictates the amount of data of frame.Payload to write, so frame.Header.Payload must be less or equal to len(frame.Payload).

func WriteNotification

func WriteNotification(w io.Writer, op Notification, payload []byte) error

WriteNotification is a convenience wrapper around WriteFrame to send notifications.

func WriteResponse

func WriteResponse(w io.Writer, op Command, inError bool, payload []byte) error

WriteResponse is a convenience wrapper around WriteFrame to send responses.

func WriteStream

func WriteStream(w io.Writer, op Stream, payload []byte) error

WriteStream is a convenience wrapper around WriteFrame to send stream packets.

Types

type AttachVM

type AttachVM struct {
	ContainerID string `json:"containerId"`
	// NumIOStreams asks for a number of I/O tokens. See RegisterVM for
	// some details on I/O tokens.
	NumIOStreams int `json:"numIOStreams,omitempty"`
}

The AttachVM payload can be used to associate clients to an already known VM. AttachVM cannot be issued if a RegisterVM for this container hasn't been issued beforehand.

{
  "containerId": "756535dc6e9ab9b560f84c8...".
  "numIOStreams: 1
}

type AttachVMResponse

type AttachVMResponse struct {
	// IO contains the proxy answer when asking for I/O tokens.
	IO IOResponse `json:"io,omitempty"`
}

AttachVMResponse is the result from a successful AttachVM.

{
  "io": {
    "url": "unix:///run/clearcontainers/proxy.sock",
    "tokens": [
      "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
    ]
  }
}

type Command

type Command int

Command is the kind of command being sent. In the frame header, Opcode must have one of these values when Type is api.TypeCommand.

const (
	// CmdRegisterVM registers a new VM/POD.
	CmdRegisterVM Command = iota
	// CmdUnregisterVM unregisters a VM/POD.
	CmdUnregisterVM
	// CmdAttachVM attaches to a registered VM.
	CmdAttachVM
	// CmdHyper sends a hyperstart command through the proxy.
	CmdHyper
	// CmdConnectShim identifies the client as a shim.
	CmdConnectShim
	// CmdDisconnectShim unregisters a shim. DisconnectShim is a bit
	// special and doesn't send a Response back but closes the connection.
	CmdDisconnectShim
	// CmdSignal sends a signal to the process inside the VM. A client
	// needs to be connected as a shim before it can issue that command.
	CmdSignal
	// CmdMax is the number of commands.
	CmdMax
)

func (Command) String

func (t Command) String() string

String implements Stringer for Command.

type ConnectShim

type ConnectShim struct {
	// Token is id corresponding to the process the shim wants to handle
	// the I/O streams, signals, exit status for. Tokens are allocated with
	// a call to RegisterVM or AttachVM.
	Token string `json:"token"`
}

ConnectShim identifies a shim against the proxy. A shim process is a process running on host shadowing a container process running inside the VM. A shim will forward stdin and signals to the process inside the VM and will receive stdout, stderr and the exit status.

type DisconnectShim

type DisconnectShim struct {
}

DisconnectShim unregister a shim from the proxy.

type ErrorResponse

type ErrorResponse struct {
	Message string `json:"msg"`
}

ErrorResponse is the payload send in Responses where the Error flag is set.

type Frame

type Frame struct {
	Header  FrameHeader
	Payload []byte
}

Frame is the basic communication unit with the proxy.

func NewFrame

func NewFrame(t FrameType, op int, payload []byte) *Frame

NewFrame creates a new Frame with type t, operand op and given payload.

func NewFrameJSON

func NewFrameJSON(t FrameType, op int, payload interface{}) (*Frame, error)

NewFrameJSON creates a new Frame with type t, operand op and given payload. The payload structure is marshalled into JSON.

func ReadFrame

func ReadFrame(r io.Reader) (*Frame, error)

ReadFrame reads a full frame (header and payload) from r.

type FrameHeader

type FrameHeader struct {
	Version int
	// HeaderLength in the size of the header in bytes (the on-wire
	// HeaderLength is in number of 32-bits words tough).
	HeaderLength  int
	Type          FrameType
	Opcode        int
	PayloadLength int
	InError       bool
}

FrameHeader is the header of a Frame.

type FrameType

type FrameType int

FrameType is the type of frame and is part of the frame header.

const (
	// TypeCommand is a command from a client to the proxy.
	TypeCommand FrameType = iota
	// TypeResponse is a command response back from the proxy to a client.
	TypeResponse
	// TypeStream is a stream of data from a client to the proxy. Streams
	// are to be forwarded onto the VM agent.
	TypeStream
	// TypeNotification is a notification sent by either the proxy or
	// clients. Notifications are one way only and do not prompt a
	// response.
	TypeNotification
	// TypeMax is the number of types.
	TypeMax
)

func (FrameType) String

func (t FrameType) String() string

String implements Stringer for FrameType.

type Hyper

type Hyper struct {
	HyperName string          `json:"hyperName"`
	Tokens    []string        `json:"tokens"`
	Data      json.RawMessage `json:"data,omitempty"`
}

The Hyper payload will forward an hyperstart command to hyperstart.

Note: the newcontainer and execmd hyperstart commands start one or more processes. When sending those commands, tokens acquired through either RegisterVM or AttachVM need to be sent along in the tokens array. The number of tokens sent has to match the number of processes to be started.

{
  "hyperName": "newcontainer",
  "tokens": [
    "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
  ],
  "data": {
    "id": "756535dc6e9ab9b560f84c8...",
    "rootfs": "/foo/bar",
    ...
    }
  }
}

type IOResponse

type IOResponse struct {
	// URL is the URL a shim process should connect to in order to initiate
	// the I/O communication with the process inside the VM
	URL string
	// IOTokens is a array of I/O tokens of length NumIOStreams. See
	// RegisterVM for some details on I/O tokens.
	Tokens []string `json:"tokens"`
}

IOResponse is the response data in RegisterVMResponse and AttachVMResponse when the client is asking for I/O tokens from the proxy (NumIOStreams > 0).

type LogEntry

type LogEntry struct {
	// Source is the source of the log entry. One of "shim" or "runtime".
	Source string `json:"source"`
	// ContainerID is the ID of the container the log entry is for (optional).
	ContainerID string `json:"containerId,omitempty"`
	// Level is the verbosity level of the log entry. One of "debug", "info", "warn"
	// or "error".
	Level string `json:"level"`
	// Message is the log message
	Message string `json:"msg"`
}

LogEntry is the payload for the StreamLog data.

type Notification

type Notification int

Notification is the kind of notification being sent. In the frame header, Opcode must have one of the these values when Type is api.TypeNotification.

func (Notification) String

func (n Notification) String() string

String implements Stringer for Notification.

type RegisterVM

type RegisterVM struct {
	ContainerID string `json:"containerId"`
	CtlSerial   string `json:"ctlSerial"`
	IoSerial    string `json:"ioSerial"`
	Console     string `json:"console,omitempty"`
	// NumIOStreams asks for a number of I/O tokens. An I/O token
	// represents the communication between a container process inside
	// the VM and a shim process outside the VM. This communication
	// includes I/O streams (stdin, out, err) but also signals, exit
	// status, ...
	// The response frame will contain NumIOStreams I/O tokens.
	NumIOStreams int `json:"numIOStreams,omitempty"`
}

The RegisterVM payload is issued first after connecting to the proxy socket. It is used to let the proxy know about a new container on the system along with the paths go hyperstart's command and I/O channels (AF_UNIX sockets).

Console can be used to indicate the path of a socket linked to the VM console. The proxy can output this data when asked for verbose output.

{
  "containerId": "756535dc6e9ab9b560f84c8...",
  "ctlSerial": "/tmp/sh.hyper.channel.0.sock",
  "ioSerial": "/tmp/sh.hyper.channel.1.sock",
  "numIOStreams: 1
}

type RegisterVMResponse

type RegisterVMResponse struct {
	// IO contains the proxy answer when asking for I/O tokens.
	IO IOResponse `json:"io,omitempty"`
}

RegisterVMResponse is the result from a successful RegisterVM.

{
  "io": {
    "url": "unix:///run/clearcontainers/proxy.sock",
    "tokens": [
      "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
    ]
  }
}

type Request

type Request struct {
	ID   string          `json:"id"`
	Data json.RawMessage `json:"data,omitempty"`
}

A Request is a JSON message sent from a client to the proxy. This message embed a payload identified by "id". A payload can have data associated with it. It's useful to think of Request as an RPC call with "id" as function name and "data" as arguments.

The list of possible payloads are documented in this package.

Each Request has a corresponding Response message sent back from the proxy.

type Response

type Response struct {
	Success bool                   `json:"success"`
	Error   string                 `json:"error,omitempty"`
	Data    map[string]interface{} `json:"data,omitempty"`
}

A Response is a JSON message sent back from the proxy to a client after a Request has been issued. The Response holds the result of the Request, including its success state and optional data. It's useful to think of Response as the result of an RPC call with ("success", "error") describing if the call has been successful and "data" holding the optional results.

type Signal

type Signal struct {
	SignalNumber int `json:"signalNumber"`
	// Columns is only valid for SIGWINCH and is the new number of columns of
	// the terminal.
	Columns int `json:"columns,omitempty"`
	// Rows is only valid for SIGWINCH and is the new number of rows of the
	// terminal.
	Rows int `json:"rows,omitempty"`
}

Signal is used to send signals to the container process inside the VM. This payload is only valid after a successful ConnectShim.

type Stream

type Stream int

Stream is the kind of stream being sent. In the frame header, Opcode must have one of the these values when Type is api.TypeStream.

const (
	// StreamStdin is a stream conveying stdin data.
	StreamStdin Stream = iota
	// StreamStdout is a stream conveying stdout data.
	StreamStdout
	// StreamStderr is a stream conveying stderr data.
	StreamStderr
	// StreamLog is a stream conveying structured logs messages. Each Log frame
	// contains a JSON object which fields are the structured log. By convention
	// it would be nice to have a few common fields in log entries to ease
	// post-processing. See the LogEntry payload for details.
	StreamLog
	// StreamMax is the number of stream types.
	StreamMax
)

func (Stream) String

func (s Stream) String() string

String implements Stringer for Stream.

type UnregisterVM

type UnregisterVM struct {
	ContainerID string `json:"containerId"`
}

The UnregisterVM payload does the opposite of what RegisterVM does, indicating to the proxy it should release resources created by RegisterVM for the container identified by containerId.

{
  "containerId": "756535dc6e9ab9b560f84c8..."
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL