@@ -19,12 +19,10 @@ import (
19
19
"errors"
20
20
"fmt"
21
21
"os"
22
- "os/exec"
23
22
"strconv"
24
23
"strings"
25
24
26
25
"github.com/firecracker-microvm/firecracker-go-sdk"
27
- "github.com/hashicorp/go-multierror"
28
26
"github.com/jessevdk/go-flags"
29
27
log "github.com/sirupsen/logrus"
30
28
)
@@ -39,6 +37,10 @@ const (
39
37
consoleFile = "file"
40
38
// consoleNone indicates that the machine's console IO should be discarded
41
39
consoleNone = "none"
40
+
41
+ // executableMask is the mask needed to check whether or not a file's
42
+ // permissions are executable.
43
+ executableMask = 0111
42
44
)
43
45
44
46
func parseBlockDevices (entries []string ) ([]firecracker.BlockDevice , error ) {
@@ -104,27 +106,24 @@ func parseVsocks(devices []string) ([]firecracker.VsockDevice, error) {
104
106
}
105
107
106
108
type options struct {
107
- FcBinary string `long:"firecracker-binary" description:"Path to firecracker binary"`
108
- FcConsole string `long:"firecracker-console" description:"Console type (stdio|file|xterm|none)" default:"stdio"`
109
- FcKernelImage string `long:"kernel" description:"Path to the kernel image" default:"./vmlinux"`
110
- FcKernelCmdLine string `long:"kernel-opts" description:"Kernel commandline" default:"ro console=ttyS0 noapic reboot=k panic=1 pci=off nomodules"`
111
- FcRootDrivePath string `long:"root-drive" description:"Path to root disk image"`
112
- FcRootPartUUID string `long:"root-partition" description:"Root partition UUID"`
113
- FcAdditionalDrives []string `long:"add-drive" description:"Path to additional drive, suffixed with :ro or :rw, can be specified multiple times"`
114
- FcNicConfig string `long:"tap-device" description:"NIC info, specified as DEVICE/MAC"`
115
- FcVsockDevices []string `long:"vsock-device" description:"Vsock interface, specified as PATH:CID. Multiple OK"`
116
- FcLogFifo string `long:"vmm-log-fifo" description:"FIFO for firecracker logs"`
117
- FcLogLevel string `long:"log-level" description:"vmm log level" default:"Debug"`
118
- FcLogStdoutFilePath string `long:"log-stdout-file" description:"Specifies where stdout logs should be placed"`
119
- FcLogStderrFilePath string `long:"log-stderr-file" description:"Specifies where stderr logs should be placed"`
120
- FcMetricsFifo string `long:"metrics-fifo" description:"FIFO for firecracker metrics"`
121
- FcDisableHt bool `long:"disable-hyperthreading" short:"t" description:"Disable CPU Hyperthreading"`
122
- FcCPUCount int64 `long:"ncpus" short:"c" description:"Number of CPUs" default:"1"`
123
- FcCPUTemplate string `long:"cpu-template" description:"Firecracker CPU Template (C3 or T2)"`
124
- FcMemSz int64 `long:"memory" short:"m" description:"VM memory, in MiB" default:"512"`
125
- FcMetadata string `long:"metadata" description:"Firecracker Meatadata for MMDS (json)"`
126
- Debug bool `long:"debug" short:"d" description:"Enable debug output"`
127
- Help bool `long:"help" short:"h" description:"Show usage"`
109
+ FcBinary string `long:"firecracker-binary" description:"Path to firecracker binary"`
110
+ FcKernelImage string `long:"kernel" description:"Path to the kernel image" default:"./vmlinux"`
111
+ FcKernelCmdLine string `long:"kernel-opts" description:"Kernel commandline" default:"ro console=ttyS0 noapic reboot=k panic=1 pci=off nomodules"`
112
+ FcRootDrivePath string `long:"root-drive" description:"Path to root disk image"`
113
+ FcRootPartUUID string `long:"root-partition" description:"Root partition UUID"`
114
+ FcAdditionalDrives []string `long:"add-drive" description:"Path to additional drive, suffixed with :ro or :rw, can be specified multiple times"`
115
+ FcNicConfig string `long:"tap-device" description:"NIC info, specified as DEVICE/MAC"`
116
+ FcVsockDevices []string `long:"vsock-device" description:"Vsock interface, specified as PATH:CID. Multiple OK"`
117
+ FcLogFifo string `long:"vmm-log-fifo" description:"FIFO for firecracker logs"`
118
+ FcLogLevel string `long:"log-level" description:"vmm log level" default:"Debug"`
119
+ FcMetricsFifo string `long:"metrics-fifo" description:"FIFO for firecracker metrics"`
120
+ FcDisableHt bool `long:"disable-hyperthreading" short:"t" description:"Disable CPU Hyperthreading"`
121
+ FcCPUCount int64 `long:"ncpus" short:"c" description:"Number of CPUs" default:"1"`
122
+ FcCPUTemplate string `long:"cpu-template" description:"Firecracker CPU Template (C3 or T2)"`
123
+ FcMemSz int64 `long:"memory" short:"m" description:"VM memory, in MiB" default:"512"`
124
+ FcMetadata string `long:"metadata" description:"Firecracker Meatadata for MMDS (json)"`
125
+ Debug bool `long:"debug" short:"d" description:"Enable debug output"`
126
+ Help bool `long:"help" short:"h" description:"Show usage"`
128
127
}
129
128
130
129
func main () {
@@ -201,7 +200,6 @@ func main() {
201
200
AdditionalDrives : blockDevices ,
202
201
NetworkInterfaces : NICs ,
203
202
VsockDevices : vsocks ,
204
- Console : opts .FcConsole ,
205
203
CPUCount : opts .FcCPUCount ,
206
204
CPUTemplate : firecracker .CPUTemplate (opts .FcCPUTemplate ),
207
205
HtEnabled : ! opts .FcDisableHt ,
@@ -218,16 +216,38 @@ func main() {
218
216
vmmCtx , vmmCancel := context .WithCancel (ctx )
219
217
defer vmmCancel ()
220
218
221
- cmd , cleanup , err := buildCommand (vmmCtx , fcCfg .SocketPath , opts )
222
- if err != nil {
223
- log .Fatalf ("Failed to build command: %v" , err )
219
+ machineOpts := []firecracker.Opt {
220
+ firecracker .WithLogger (log .NewEntry (logger )),
224
221
}
225
- defer cleanup ()
226
222
227
- m , err := firecracker .NewMachine (fcCfg ,
228
- firecracker .WithLogger (log .NewEntry (logger )),
229
- firecracker .WithProcessRunner (cmd ),
230
- )
223
+ if len (opts .FcBinary ) != 0 {
224
+ finfo , err := os .Stat (opts .FcBinary )
225
+ if os .IsNotExist (err ) {
226
+ log .Fatalf ("Binary, %q, does not exist: %v" , opts .FcBinary , err )
227
+ }
228
+
229
+ if err != nil {
230
+ log .Fatalf ("Failed to stat binary, %q: %v" , opts .FcBinary , err )
231
+ }
232
+
233
+ if finfo .IsDir () {
234
+ log .Fatalf ("Binary, %q, is a directory" , opts .FcBinary )
235
+ } else if finfo .Mode ()& executableMask == 0 {
236
+ log .Fatalf ("Binary, %q, is not executable. Check permissions of binary" , opts .FcBinary )
237
+ }
238
+
239
+ cmd := firecracker.VMCommandBuilder {}.
240
+ WithBin (opts .FcBinary ).
241
+ WithSocketPath (fcCfg .SocketPath ).
242
+ WithStdin (os .Stdin ).
243
+ WithStdout (os .Stdout ).
244
+ WithStderr (os .Stderr ).
245
+ Build (ctx )
246
+
247
+ machineOpts = append (machineOpts , firecracker .WithProcessRunner (cmd ))
248
+ }
249
+
250
+ m , err := firecracker .NewMachine (fcCfg , machineOpts ... )
231
251
if err != nil {
232
252
log .Fatalf ("Failed creating machine: %s" , err )
233
253
}
@@ -254,65 +274,3 @@ func main() {
254
274
}
255
275
log .Printf ("startVMM was happy" )
256
276
}
257
-
258
- func buildCommand (ctx context.Context , socketPath string , opts options ) (* exec.Cmd , func () error , error ) {
259
- var cmd * exec.Cmd
260
- b := firecracker.VMCommandBuilder {}
261
-
262
- fn := func () error {
263
- return nil
264
- }
265
-
266
- switch opts .FcConsole {
267
- case consoleXterm :
268
- cmd = b .WithBin (terminalProgram ).
269
- AddArgs ("-e" , opts .FcBinary , "--api-sock" , socketPath ).
270
- Build (ctx )
271
- case consoleStdio :
272
- cmd = b .WithBin (opts .FcBinary ).
273
- WithSocketPath (socketPath ).
274
- WithStdin (os .Stdin ).
275
- WithStdout (os .Stdout ).
276
- WithStderr (os .Stderr ).
277
- Build (ctx )
278
- case consoleFile :
279
- stdout , err := generateLogFile (opts .FcLogStdoutFilePath )
280
- if err != nil {
281
- return nil , nil , err
282
- }
283
-
284
- stderr , err := generateLogFile (opts .FcLogStderrFilePath )
285
- if err != nil {
286
- return nil , nil , err
287
- }
288
-
289
- fn = func () error {
290
- var merr * multierror.Error
291
- if err := stdout .Close (); err != nil {
292
- merr = multierror .Append (merr , err )
293
- }
294
-
295
- if err := stderr .Close (); err != nil {
296
- merr = multierror .Append (merr , err )
297
- }
298
-
299
- return merr .ErrorOrNil ()
300
- }
301
-
302
- cmd = b .WithBin (opts .FcBinary ).
303
- WithSocketPath (socketPath ).
304
- WithStdout (stdout ).
305
- WithStderr (stderr ).
306
- Build (ctx )
307
- default :
308
- cmd = b .WithBin (opts .FcBinary ).
309
- WithSocketPath (socketPath ).
310
- Build (ctx )
311
- }
312
-
313
- return cmd , fn , nil
314
- }
315
-
316
- func generateLogFile (filename string ) (* os.File , error ) {
317
- return os .OpenFile (filename , os .O_CREATE | os .O_APPEND | os .O_WRONLY , 0644 )
318
- }
0 commit comments