-
Notifications
You must be signed in to change notification settings - Fork 48
/
vm.go
235 lines (210 loc) · 5.01 KB
/
vm.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
// Package vm defines data types and functions define and
// share data between the runtime runq, proxy and init.
package vm
import (
"bytes"
"compress/gzip"
"encoding/base64"
"encoding/gob"
"io/ioutil"
"net"
"syscall"
"github.com/vishvananda/netlink"
)
// QemuMountPt is used to bind mount /var/lib/runq/qemu
const QemuMountPt = "/.qemu.mnt"
// Msgtype declares the type of a message.
type Msgtype uint8
// Message types
const (
_ Msgtype = iota
Signal // IPC signal such as SIGTERM
Vmdata // VM config data
)
// Msg defines the format of the data exchanged between proxy and init.
type Msg struct {
Type Msgtype
Data []byte
}
// Disktype represents a valid disk types.
type Disktype int
// known disk types
const (
DisktypeUnknown Disktype = iota // disk type is not known
BlockDevice // regular block device
Qcow2Image // Qcow2 image
RawFile // regular file used as block device
)
// AppCapabilities defines whitelists of Linux capabilities
// for the target application.
type AppCapabilities struct {
Ambient []string
Bounding []string
Effective []string
Inheritable []string
Permitted []string
}
// Network defines a network interface.
type Network struct {
Name string
MacAddress string
MTU int
Addrs []netlink.Addr
Gateway net.IP
TapDevice string
}
// Disk defines a disk.
type Disk struct {
Cache string
Dir string
Fstype string
ID string
Mount bool
Path string
Serial string
Type Disktype
}
// Mount defines a mount point.
type Mount struct {
Data string
Flags int
Fstype string
ID string
Source string
Target string
}
// User specifies user information for the VM process.
type User struct {
UID uint32
GID uint32
AdditionalGids []uint32
}
// Certificates definenes TLS certificates
type Certificates struct {
CACert []byte
Cert []byte
Key []byte
}
// Entrypoint contains information of entrypoint.
type Entrypoint struct {
User
Args []string
Capabilities AppCapabilities
Cwd string
DockerInit string
Env []string
NoNewPrivileges bool
Rlimits map[string]syscall.Rlimit
Runqenv bool
SeccompGob []byte
Systemd bool
Terminal bool
}
// Vsockd contains config data for the vsockd process.
type Vsockd struct {
Certificates
EntrypointPid int
EntrypointEnv []string
CID uint32
}
// DNS contains dns configuration.
type DNS struct {
Server []string
Options string
Search string
Preserve bool
}
// Data contains all data needed by the VM.
type Data struct {
APDevice string
Cache9p string
ContainerID string
CPU int
CPUArgs string
Disks []Disk
DNS DNS
GitCommit string
Hostname string
MachineType string
Mem int
Mounts []Mount
NestedVM bool
Networks []Network
NoExec bool
QemuVersion string
Rootdisk string
RootdiskExclude []string
Sysctl map[string]string
Entrypoint Entrypoint
Vsockd Vsockd
}
// Encode encodes a data struct into binary Gob.
func Encode(e interface{}) ([]byte, error) {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
if err := enc.Encode(e); err != nil {
return []byte{}, err
}
return buf.Bytes(), nil
}
// DecodeDataGob decodes a Gob binary buffer into a Data struct.
func DecodeDataGob(buf []byte) (*Data, error) {
dec := gob.NewDecoder(bytes.NewBuffer(buf))
v := new(Data)
if err := dec.Decode(v); err != nil {
return nil, err
}
return v, nil
}
// DecodeEntrypointGob decodes a Gob binary buffer into a Entrypoint struct.
func DecodeEntrypointGob(buf []byte) (*Entrypoint, error) {
dec := gob.NewDecoder(bytes.NewBuffer(buf))
v := new(Entrypoint)
if err := dec.Decode(v); err != nil {
return nil, err
}
return v, nil
}
// DecodeVsockdGob decodes a Gob binary buffer into a Vsockd struct.
func DecodeVsockdGob(buf []byte) (*Vsockd, error) {
dec := gob.NewDecoder(bytes.NewBuffer(buf))
v := new(Vsockd)
if err := dec.Decode(v); err != nil {
return nil, err
}
return v, nil
}
// ZipEncodeBase64 encodes arbritray data into a gziped binary Gob
// and returns it encoded as base64.
func ZipEncodeBase64(data interface{}) (string, error) {
var buf bytes.Buffer
wr := gzip.NewWriter(&buf)
enc := gob.NewEncoder(wr)
if err := enc.Encode(data); err != nil {
return "", err
}
if err := wr.Close(); err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}
// ZipDecodeBase64 decodes a base64 string, into a data struct.
func ZipDecodeBase64(str string) (*Data, error) {
s, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(s)
rd, err := gzip.NewReader(buf)
if err != nil {
return nil, err
}
res, err := ioutil.ReadAll(rd)
if err != nil {
return nil, err
}
if err := rd.Close(); err != nil {
return nil, err
}
return DecodeDataGob(res)
}