This repository has been archived by the owner on May 6, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
frame.go
235 lines (212 loc) · 6.13 KB
/
frame.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
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
}