mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-10-22 12:29:49 +00:00
vendor: Move virtcontainers to project's root directory
Lets have a global vendor base on virtcontainers. Signed-off-by: Julio Montes <julio.montes@intel.com> Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com> Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
This commit is contained in:
202
vendor/github.com/clearcontainers/proxy/COPYING
generated
vendored
Normal file
202
vendor/github.com/clearcontainers/proxy/COPYING
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
84
vendor/github.com/clearcontainers/proxy/api/doc.go
generated
vendored
Normal file
84
vendor/github.com/clearcontainers/proxy/api/doc.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// 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.
|
||||
package api
|
235
vendor/github.com/clearcontainers/proxy/api/frame.go
generated
vendored
Normal file
235
vendor/github.com/clearcontainers/proxy/api/frame.go
generated
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
// Copyright (c) 2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// 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
|
||||
const Version = 2
|
||||
|
||||
// FrameType is the type of frame and is part of the frame header.
|
||||
type FrameType int
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
const unknown = "unknown"
|
||||
|
||||
// String implements Stringer for FrameType.
|
||||
func (t FrameType) String() string {
|
||||
switch t {
|
||||
case TypeCommand:
|
||||
return "command"
|
||||
case TypeResponse:
|
||||
return "response"
|
||||
case TypeStream:
|
||||
return "stream"
|
||||
case TypeNotification:
|
||||
return "notification"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// Command is the kind of command being sent. In the frame header, Opcode must
|
||||
// have one of these values when Type is api.TypeCommand.
|
||||
type Command int
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
// String implements Stringer for Command.
|
||||
func (t Command) String() string {
|
||||
switch t {
|
||||
case CmdRegisterVM:
|
||||
return "RegisterVM"
|
||||
case CmdUnregisterVM:
|
||||
return "UnregisterVM"
|
||||
case CmdAttachVM:
|
||||
return "AttachVM"
|
||||
case CmdHyper:
|
||||
return "Hyper"
|
||||
case CmdConnectShim:
|
||||
return "ConnectShim"
|
||||
case CmdDisconnectShim:
|
||||
return "DisconnectShim"
|
||||
case CmdSignal:
|
||||
return "Signal"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
type Stream int
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
// String implements Stringer for Stream.
|
||||
func (s Stream) String() string {
|
||||
switch s {
|
||||
case StreamStdin:
|
||||
return "stdin"
|
||||
case StreamStdout:
|
||||
return "stdout"
|
||||
case StreamStderr:
|
||||
return "stderr"
|
||||
case StreamLog:
|
||||
return "log"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
type Notification int
|
||||
|
||||
const (
|
||||
// NotificationProcessExited is sent to signal a process in the VM has exited.
|
||||
NotificationProcessExited = iota
|
||||
// NotificationMax is the number of notification types.
|
||||
NotificationMax
|
||||
)
|
||||
|
||||
// String implements Stringer for Notification.
|
||||
func (n Notification) String() string {
|
||||
switch n {
|
||||
case NotificationProcessExited:
|
||||
return "ProcessExited"
|
||||
default:
|
||||
return unknown
|
||||
}
|
||||
}
|
||||
|
||||
// FrameHeader is the header of a Frame.
|
||||
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
|
||||
}
|
||||
|
||||
// Frame is the basic communication unit with the proxy.
|
||||
type Frame struct {
|
||||
Header FrameHeader
|
||||
Payload []byte
|
||||
}
|
||||
|
||||
// NewFrame creates a new Frame with type t, operand op and given payload.
|
||||
func NewFrame(t FrameType, op int, payload []byte) *Frame {
|
||||
return &Frame{
|
||||
Header: FrameHeader{
|
||||
Version: Version,
|
||||
HeaderLength: minHeaderLength,
|
||||
Type: t,
|
||||
Opcode: op,
|
||||
PayloadLength: len(payload),
|
||||
},
|
||||
Payload: payload,
|
||||
}
|
||||
}
|
||||
|
||||
// NewFrameJSON creates a new Frame with type t, operand op and given payload.
|
||||
// The payload structure is marshalled into JSON.
|
||||
func NewFrameJSON(t FrameType, op int, payload interface{}) (*Frame, error) {
|
||||
var data []byte
|
||||
|
||||
if payload != nil {
|
||||
var err error
|
||||
|
||||
if data, err = json.Marshal(payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &Frame{
|
||||
Header: FrameHeader{
|
||||
Version: Version,
|
||||
HeaderLength: minHeaderLength,
|
||||
Type: t,
|
||||
Opcode: op,
|
||||
PayloadLength: len(data),
|
||||
},
|
||||
Payload: data,
|
||||
}, nil
|
||||
}
|
183
vendor/github.com/clearcontainers/proxy/api/payload.go
generated
vendored
Normal file
183
vendor/github.com/clearcontainers/proxy/api/payload.go
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
// Copyright (c) 2016,2017 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// 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 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"`
|
||||
}
|
||||
|
||||
// IOResponse is the response data in RegisterVMResponse and AttachVMResponse
|
||||
// when the client is asking for I/O tokens from the proxy (NumIOStreams > 0).
|
||||
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"`
|
||||
}
|
||||
|
||||
// RegisterVMResponse is the result from a successful RegisterVM.
|
||||
//
|
||||
// {
|
||||
// "io": {
|
||||
// "url": "unix:///run/clearcontainers/proxy.sock",
|
||||
// "tokens": [
|
||||
// "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
type RegisterVMResponse struct {
|
||||
// IO contains the proxy answer when asking for I/O tokens.
|
||||
IO IOResponse `json:"io,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 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"`
|
||||
}
|
||||
|
||||
// AttachVMResponse is the result from a successful AttachVM.
|
||||
//
|
||||
// {
|
||||
// "io": {
|
||||
// "url": "unix:///run/clearcontainers/proxy.sock",
|
||||
// "tokens": [
|
||||
// "bwgxfmQj9uG3YCsFHrvontwDw41CJJ76Y7qVt4Bi9wc="
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
type AttachVMResponse struct {
|
||||
// IO contains the proxy answer when asking for I/O tokens.
|
||||
IO IOResponse `json:"io,omitempty"`
|
||||
}
|
||||
|
||||
// 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..."
|
||||
// }
|
||||
type UnregisterVM struct {
|
||||
ContainerID string `json:"containerId"`
|
||||
}
|
||||
|
||||
// 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 Hyper struct {
|
||||
HyperName string `json:"hyperName"`
|
||||
Tokens []string `json:"tokens"`
|
||||
Data json.RawMessage `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// 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 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"`
|
||||
}
|
||||
|
||||
// DisconnectShim unregister a shim from the proxy.
|
||||
type DisconnectShim struct {
|
||||
}
|
||||
|
||||
// Signal is used to send signals to the container process inside the VM. This
|
||||
// payload is only valid after a successful ConnectShim.
|
||||
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"`
|
||||
}
|
||||
|
||||
// ErrorResponse is the payload send in Responses where the Error flag is set.
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"msg"`
|
||||
}
|
||||
|
||||
// LogEntry is the payload for the StreamLog data.
|
||||
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"`
|
||||
}
|
213
vendor/github.com/clearcontainers/proxy/api/protocol.go
generated
vendored
Normal file
213
vendor/github.com/clearcontainers/proxy/api/protocol.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// minHeaderLength is the length of the header in the version 2 of protocol.
|
||||
// It is guaranteed later versions will have a header at least that big.
|
||||
const minHeaderLength = 12 // in bytes
|
||||
|
||||
// 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 Request struct {
|
||||
ID string `json:"id"`
|
||||
Data json.RawMessage `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 Response struct {
|
||||
Success bool `json:"success"`
|
||||
Error string `json:"error,omitempty"`
|
||||
Data map[string]interface{} `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// Offsets (in bytes) of frame headers fields.
|
||||
const (
|
||||
versionOffset = 0
|
||||
headerLengthOffset = 2
|
||||
typeOffset = 6
|
||||
flagsOffset = 6
|
||||
opcodeOffset = 7
|
||||
payloadLengthOffset = 8
|
||||
)
|
||||
|
||||
// Size (in bytes) of frame header fields (when larger than 1 byte).
|
||||
const (
|
||||
versionSize = 2
|
||||
payloadLengthSize = 4
|
||||
)
|
||||
|
||||
// Masks needed to extract fields
|
||||
const (
|
||||
typeMask = 0x0f
|
||||
flagsMask = 0xf0
|
||||
)
|
||||
|
||||
func maxOpcodeForFrameType(t FrameType) int {
|
||||
switch t {
|
||||
default:
|
||||
fallthrough
|
||||
case TypeCommand:
|
||||
return int(CmdMax)
|
||||
case TypeResponse:
|
||||
return int(CmdMax)
|
||||
case TypeStream:
|
||||
return int(StreamMax)
|
||||
case TypeNotification:
|
||||
return int(NotificationMax)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadFrame reads a full frame (header and payload) from r.
|
||||
func ReadFrame(r io.Reader) (*Frame, error) {
|
||||
// Read the header.
|
||||
buf := make([]byte, minHeaderLength)
|
||||
n, err := r.Read(buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != minHeaderLength {
|
||||
return nil, errors.New("frame: couldn't read the full header")
|
||||
}
|
||||
|
||||
// Decode it.
|
||||
frame := &Frame{}
|
||||
header := &frame.Header
|
||||
header.Version = int(binary.BigEndian.Uint16(buf[versionOffset : versionOffset+versionSize]))
|
||||
if header.Version < 2 || header.Version > Version {
|
||||
return nil, fmt.Errorf("frame: bad version %d", header.Version)
|
||||
}
|
||||
header.HeaderLength = int(buf[headerLengthOffset]) * 4
|
||||
header.Type = FrameType(buf[typeOffset] & typeMask)
|
||||
flags := buf[flagsOffset] & flagsMask
|
||||
if flags&flagInError != 0 {
|
||||
header.InError = true
|
||||
}
|
||||
if header.Type >= TypeMax {
|
||||
return nil, fmt.Errorf("frame: bad type %s", header.Type)
|
||||
}
|
||||
header.Opcode = int(buf[opcodeOffset])
|
||||
if header.Opcode >= maxOpcodeForFrameType(header.Type) {
|
||||
return nil, fmt.Errorf("frame: bad opcode (%d) for type %s", header.Opcode,
|
||||
header.Type)
|
||||
}
|
||||
header.PayloadLength = int(binary.BigEndian.Uint32(buf[payloadLengthOffset : payloadLengthOffset+payloadLengthSize]))
|
||||
|
||||
// Read the payload.
|
||||
received := 0
|
||||
need := header.HeaderLength - minHeaderLength + header.PayloadLength
|
||||
payload := make([]byte, need)
|
||||
for received < need {
|
||||
n, err := r.Read(payload[received:need])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
received += n
|
||||
}
|
||||
|
||||
// Skip the bytes part of a bigger header than expected to just keep
|
||||
// the payload.
|
||||
frame.Payload = payload[header.HeaderLength-minHeaderLength : need]
|
||||
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
const (
|
||||
flagInError = 1 << (4 + iota)
|
||||
)
|
||||
|
||||
// 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 WriteFrame(w io.Writer, frame *Frame) error {
|
||||
header := &frame.Header
|
||||
|
||||
if len(frame.Payload) < header.PayloadLength {
|
||||
return fmt.Errorf("frame: bad payload length %d",
|
||||
header.PayloadLength)
|
||||
}
|
||||
|
||||
// Prepare the header.
|
||||
len := minHeaderLength + header.PayloadLength
|
||||
buf := make([]byte, len)
|
||||
binary.BigEndian.PutUint16(buf[versionOffset:versionOffset+versionSize], uint16(header.Version))
|
||||
buf[headerLengthOffset] = byte(header.HeaderLength / 4)
|
||||
flags := byte(0)
|
||||
if frame.Header.InError {
|
||||
flags |= flagInError
|
||||
}
|
||||
buf[typeOffset] = flags | byte(header.Type)&typeMask
|
||||
buf[opcodeOffset] = byte(header.Opcode)
|
||||
binary.BigEndian.PutUint32(buf[payloadLengthOffset:payloadLengthOffset+payloadLengthSize],
|
||||
uint32(header.PayloadLength))
|
||||
|
||||
// Write payload if needed
|
||||
if header.PayloadLength > 0 {
|
||||
copy(buf[minHeaderLength:], frame.Payload[0:header.PayloadLength])
|
||||
}
|
||||
|
||||
n, err := w.Write(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if n != len {
|
||||
return errors.New("frame: couldn't write frame")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteCommand is a convenience wrapper around WriteFrame to send commands.
|
||||
func WriteCommand(w io.Writer, op Command, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeCommand, int(op), payload))
|
||||
}
|
||||
|
||||
// WriteResponse is a convenience wrapper around WriteFrame to send responses.
|
||||
func WriteResponse(w io.Writer, op Command, inError bool, payload []byte) error {
|
||||
frame := NewFrame(TypeResponse, int(op), payload)
|
||||
frame.Header.InError = inError
|
||||
return WriteFrame(w, frame)
|
||||
}
|
||||
|
||||
// WriteStream is a convenience wrapper around WriteFrame to send stream packets.
|
||||
func WriteStream(w io.Writer, op Stream, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeStream, int(op), payload))
|
||||
}
|
||||
|
||||
// WriteNotification is a convenience wrapper around WriteFrame to send notifications.
|
||||
func WriteNotification(w io.Writer, op Notification, payload []byte) error {
|
||||
return WriteFrame(w, NewFrame(TypeNotification, int(op), payload))
|
||||
}
|
410
vendor/github.com/clearcontainers/proxy/client/client.go
generated
vendored
Normal file
410
vendor/github.com/clearcontainers/proxy/client/client.go
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
// Copyright (c) 2016 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
"github.com/clearcontainers/proxy/api"
|
||||
)
|
||||
|
||||
// The Client struct can be used to issue proxy API calls with a convenient
|
||||
// high level API.
|
||||
type Client struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
// NewClient creates a new client object to communicate with the proxy using
|
||||
// the connection conn. The user should call Close() once finished with the
|
||||
// client object to close conn.
|
||||
func NewClient(conn net.Conn) *Client {
|
||||
return &Client{
|
||||
conn: conn,
|
||||
}
|
||||
}
|
||||
|
||||
// Close a client, closing the underlying AF_UNIX socket.
|
||||
func (client *Client) Close() {
|
||||
client.conn.Close()
|
||||
}
|
||||
|
||||
func (client *Client) sendCommandFull(cmd api.Command, payload interface{},
|
||||
waitForResponse bool) (*api.Frame, error) {
|
||||
var data []byte
|
||||
var frame *api.Frame
|
||||
var err error
|
||||
|
||||
if payload != nil {
|
||||
if data, err = json.Marshal(payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := api.WriteCommand(client.conn, cmd, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !waitForResponse {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if frame, err = api.ReadFrame(client.conn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cmd == api.CmdSignal {
|
||||
payloadSignal, ok := payload.(*api.Signal)
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if payloadSignal.SignalNumber == int(syscall.SIGKILL) ||
|
||||
payloadSignal.SignalNumber == int(syscall.SIGTERM) {
|
||||
if frame.Header.Type != api.TypeNotification {
|
||||
return nil, fmt.Errorf("unexpected frame type %v", frame.Header.Type)
|
||||
}
|
||||
|
||||
if frame, err = api.ReadFrame(client.conn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if frame.Header.Type != api.TypeResponse {
|
||||
return nil, fmt.Errorf("unexpected frame type %v", frame.Header.Type)
|
||||
}
|
||||
|
||||
if frame.Header.Opcode != int(cmd) {
|
||||
return nil, fmt.Errorf("unexpected opcode %v", frame.Header.Opcode)
|
||||
}
|
||||
|
||||
return frame, nil
|
||||
}
|
||||
|
||||
func (client *Client) sendCommand(cmd api.Command, payload interface{}) (*api.Frame, error) {
|
||||
return client.sendCommandFull(cmd, payload, true)
|
||||
}
|
||||
|
||||
func (client *Client) sendCommandNoResponse(cmd api.Command, payload interface{}) error {
|
||||
_, err := client.sendCommandFull(cmd, payload, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func errorFromResponse(resp *api.Frame) error {
|
||||
// We should always have an error with the response, but better safe
|
||||
// than sorry.
|
||||
if !resp.Header.InError {
|
||||
return nil
|
||||
}
|
||||
|
||||
decoded := api.ErrorResponse{}
|
||||
if err := json.Unmarshal(resp.Payload, &decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if decoded.Message == "" {
|
||||
return errors.New("unknown error")
|
||||
}
|
||||
|
||||
return errors.New(decoded.Message)
|
||||
}
|
||||
|
||||
func unmarshalResponse(resp *api.Frame, decoded interface{}) error {
|
||||
if len(resp.Payload) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(resp.Payload, decoded); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterVMOptions holds extra arguments one can pass to the RegisterVM
|
||||
// function.
|
||||
//
|
||||
// See the api.RegisterVM payload for more details.
|
||||
type RegisterVMOptions struct {
|
||||
Console string
|
||||
NumIOStreams int
|
||||
}
|
||||
|
||||
// RegisterVMReturn contains the return values from RegisterVM.
|
||||
//
|
||||
// See the api.RegisterVM and api.RegisterVMResponse payloads.
|
||||
type RegisterVMReturn api.RegisterVMResponse
|
||||
|
||||
// RegisterVM wraps the api.RegisterVM payload.
|
||||
//
|
||||
// See payload description for more details.
|
||||
func (client *Client) RegisterVM(containerID, ctlSerial, ioSerial string,
|
||||
options *RegisterVMOptions) (*RegisterVMReturn, error) {
|
||||
payload := api.RegisterVM{
|
||||
ContainerID: containerID,
|
||||
CtlSerial: ctlSerial,
|
||||
IoSerial: ioSerial,
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
payload.Console = options.Console
|
||||
payload.NumIOStreams = options.NumIOStreams
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdRegisterVM, &payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded := RegisterVMReturn{}
|
||||
err = unmarshalResponse(resp, &decoded)
|
||||
return &decoded, err
|
||||
}
|
||||
|
||||
// AttachVMOptions holds extra arguments one can pass to the AttachVM function.
|
||||
//
|
||||
// See the api.AttachVM payload for more details.
|
||||
type AttachVMOptions struct {
|
||||
NumIOStreams int
|
||||
}
|
||||
|
||||
// AttachVMReturn contains the return values from AttachVM.
|
||||
//
|
||||
// See the api.AttachVM and api.AttachVMResponse payloads.
|
||||
type AttachVMReturn api.AttachVMResponse
|
||||
|
||||
// AttachVM wraps the api.AttachVM payload.
|
||||
//
|
||||
// See the api.AttachVM payload description for more details.
|
||||
func (client *Client) AttachVM(containerID string, options *AttachVMOptions) (*AttachVMReturn, error) {
|
||||
payload := api.AttachVM{
|
||||
ContainerID: containerID,
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
payload.NumIOStreams = options.NumIOStreams
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdAttachVM, &payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoded := AttachVMReturn{}
|
||||
err = unmarshalResponse(resp, &decoded)
|
||||
return &decoded, err
|
||||
}
|
||||
|
||||
// Hyper wraps the Hyper payload (see payload description for more details)
|
||||
func (client *Client) Hyper(hyperName string, hyperMessage interface{}) ([]byte, error) {
|
||||
return client.HyperWithTokens(hyperName, nil, hyperMessage)
|
||||
}
|
||||
|
||||
// HyperWithTokens is a Hyper variant where the users can specify a list of I/O tokens.
|
||||
//
|
||||
// See the api.Hyper payload description for more details.
|
||||
func (client *Client) HyperWithTokens(hyperName string, tokens []string, hyperMessage interface{}) ([]byte, error) {
|
||||
var data []byte
|
||||
|
||||
if hyperMessage != nil {
|
||||
var err error
|
||||
|
||||
data, err = json.Marshal(hyperMessage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
hyper := api.Hyper{
|
||||
HyperName: hyperName,
|
||||
Data: data,
|
||||
}
|
||||
|
||||
if tokens != nil {
|
||||
hyper.Tokens = tokens
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdHyper, &hyper)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = errorFromResponse(resp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.Payload, errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// UnregisterVM wraps the api.UnregisterVM payload.
|
||||
//
|
||||
// See the api.UnregisterVM payload description for more details.
|
||||
func (client *Client) UnregisterVM(containerID string) error {
|
||||
payload := api.UnregisterVM{
|
||||
ContainerID: containerID,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdUnregisterVM, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// ConnectShim wraps the api.CmdConnectShim command and associated
|
||||
// api.ConnectShim payload.
|
||||
func (client *Client) ConnectShim(token string) error {
|
||||
payload := api.ConnectShim{
|
||||
Token: token,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdConnectShim, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// DisconnectShim wraps the api.CmdDisconnectShim command and associated
|
||||
// api.DisconnectShim payload.
|
||||
func (client *Client) DisconnectShim() error {
|
||||
return client.sendCommandNoResponse(api.CmdDisconnectShim, nil)
|
||||
}
|
||||
|
||||
func (client *Client) signal(signal syscall.Signal, columns, rows int) error {
|
||||
payload := api.Signal{
|
||||
SignalNumber: int(signal),
|
||||
Columns: columns,
|
||||
Rows: rows,
|
||||
}
|
||||
|
||||
resp, err := client.sendCommand(api.CmdSignal, &payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return errorFromResponse(resp)
|
||||
}
|
||||
|
||||
// Kill wraps the api.CmdSignal command and can be used by a shim to send a
|
||||
// signal to the associated process.
|
||||
func (client *Client) Kill(signal syscall.Signal) error {
|
||||
return client.signal(signal, 0, 0)
|
||||
}
|
||||
|
||||
// SendTerminalSize wraps the api.CmdSignal command and can be used by a shim
|
||||
// to send a new signal to the associated process.
|
||||
func (client *Client) SendTerminalSize(columns, rows int) error {
|
||||
return client.signal(syscall.SIGWINCH, columns, rows)
|
||||
}
|
||||
|
||||
func (client *Client) sendStream(op api.Stream, data []byte) error {
|
||||
return api.WriteStream(client.conn, op, data)
|
||||
}
|
||||
|
||||
// SendStdin sends stdin data. This can only be used from shim clients.
|
||||
func (client *Client) SendStdin(data []byte) error {
|
||||
return client.sendStream(api.StreamStdin, data)
|
||||
}
|
||||
|
||||
// LogLevel is the severity of log entries.
|
||||
type LogLevel uint8
|
||||
|
||||
const (
|
||||
// LogLevelDebug is for log messages only useful debugging.
|
||||
LogLevelDebug LogLevel = iota
|
||||
// LogLevelInfo is for reporting landmark events.
|
||||
LogLevelInfo
|
||||
// LogLevelWarn is for reporting warnings.
|
||||
LogLevelWarn
|
||||
// LogLevelError is for reporting errors.
|
||||
LogLevelError
|
||||
|
||||
logLevelMax
|
||||
)
|
||||
|
||||
var levelToString = []string{"debug", "info", "warn", "error"}
|
||||
|
||||
// String implements stringer for LogLevel.
|
||||
func (l LogLevel) String() string {
|
||||
if l < logLevelMax {
|
||||
return levelToString[l]
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// LogSource is the source of log entries
|
||||
type LogSource uint8
|
||||
|
||||
const (
|
||||
// LogSourceRuntime represents a runtime.
|
||||
LogSourceRuntime LogSource = iota
|
||||
// LogSourceShim represents a shim.
|
||||
LogSourceShim
|
||||
|
||||
logSourceMax
|
||||
)
|
||||
|
||||
var sourceToString = []string{"runtime", "shim"}
|
||||
|
||||
// String implements stringer for LogSource
|
||||
func (s LogSource) String() string {
|
||||
if s < logSourceMax {
|
||||
return sourceToString[s]
|
||||
}
|
||||
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// Log sends log entries.
|
||||
func (client *Client) Log(level LogLevel, source LogSource, containerID string, args ...interface{}) {
|
||||
payload := api.LogEntry{
|
||||
Level: level.String(),
|
||||
Source: source.String(),
|
||||
ContainerID: containerID,
|
||||
Message: fmt.Sprint(args...),
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(&payload)
|
||||
_ = client.sendStream(api.StreamLog, data)
|
||||
}
|
||||
|
||||
// Logf sends log entries.
|
||||
func (client *Client) Logf(level LogLevel, source LogSource, containerID string, format string, args ...interface{}) {
|
||||
payload := api.LogEntry{
|
||||
Level: level.String(),
|
||||
Source: source.String(),
|
||||
ContainerID: containerID,
|
||||
Message: fmt.Sprintf(format, args...),
|
||||
}
|
||||
|
||||
data, _ := json.Marshal(&payload)
|
||||
_ = client.sendStream(api.StreamLog, data)
|
||||
}
|
Reference in New Issue
Block a user