1
+ // Copyright 2018-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License"). You may
4
+ // not use this file except in compliance with the License. A copy of the
5
+ // License is located at
6
+ //
7
+ // http://aws.amazon.com/apache2.0/
8
+ //
9
+ // or in the "license" file accompanying this file. This file is distributed
10
+ // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11
+ // express or implied. See the License for the specific language governing
12
+ // permissions and limitations under the License.
13
+
1
14
package firecracker
2
15
3
16
import (
4
17
"context"
18
+ "fmt"
5
19
)
6
20
7
21
// Handler name constants
@@ -14,10 +28,76 @@ const (
14
28
CreateNetworkInterfacesHandlerName = "fcinit.CreateNetworkInterfaces"
15
29
AddVsocksHandlerName = "fcinit.AddVsocks"
16
30
SetMetadataHandlerName = "fcinit.SetMetadata"
31
+ LinkFilesToRootFSHandlerName = "fcinit.LinkFilesToRootFS"
17
32
18
- ValidateCfgHandlerName = "validate.Cfg"
33
+ ValidateCfgHandlerName = "validate.Cfg"
34
+ ValidateJailerCfgHandlerName = "validate.JailerCfg"
19
35
)
20
36
37
+ // HandlersAdapter is an interface used to modify a given set of handlers.
38
+ type HandlersAdapter interface {
39
+ AdaptHandlers (* Handlers ) error
40
+ }
41
+
42
+ // ConfigValidationHandler is used to validate that required fields are
43
+ // present. This validator is to be used when the jailer is turned off.
44
+ var ConfigValidationHandler = Handler {
45
+ Name : ValidateCfgHandlerName ,
46
+ Fn : func (ctx context.Context , m * Machine ) error {
47
+ // ensure that the configuration is valid for the FcInit handlers.
48
+ return m .cfg .Validate ()
49
+ },
50
+ }
51
+
52
+ // JailerConfigValidationHandler is used to validate that required fields are
53
+ // present.
54
+ var JailerConfigValidationHandler = Handler {
55
+ Name : ValidateJailerCfgHandlerName ,
56
+ Fn : func (ctx context.Context , m * Machine ) error {
57
+ if ! m .cfg .EnableJailer {
58
+ return nil
59
+ }
60
+
61
+ hasRoot := false
62
+ for _ , drive := range m .cfg .Drives {
63
+ if BoolValue (drive .IsRootDevice ) {
64
+ hasRoot = true
65
+ break
66
+ }
67
+ }
68
+
69
+ if ! hasRoot {
70
+ return fmt .Errorf ("A root drive must be present in the drive list" )
71
+ }
72
+
73
+ if m .cfg .JailerCfg .ChrootStrategy == nil {
74
+ return fmt .Errorf ("ChrootStrategy cannot be nil" )
75
+ }
76
+
77
+ if len (m .cfg .JailerCfg .ExecFile ) == 0 {
78
+ return fmt .Errorf ("exec file must be specified when using jailer mode" )
79
+ }
80
+
81
+ if len (m .cfg .JailerCfg .ID ) == 0 {
82
+ return fmt .Errorf ("id must be specified when using jailer mode" )
83
+ }
84
+
85
+ if m .cfg .JailerCfg .GID == nil {
86
+ return fmt .Errorf ("GID must be specified when using jailer mode" )
87
+ }
88
+
89
+ if m .cfg .JailerCfg .UID == nil {
90
+ return fmt .Errorf ("UID must be specified when using jailer mode" )
91
+ }
92
+
93
+ if m .cfg .JailerCfg .NumaNode == nil {
94
+ return fmt .Errorf ("ID must be specified when using jailer mode" )
95
+ }
96
+
97
+ return nil
98
+ },
99
+ }
100
+
21
101
// StartVMMHandler is a named handler that will handle starting of the VMM.
22
102
// This handler will also set the exit channel on completion.
23
103
var StartVMMHandler = Handler {
@@ -98,17 +178,6 @@ func NewSetMetadataHandler(metadata interface{}) Handler {
98
178
}
99
179
}
100
180
101
- var defaultValidationHandlerList = HandlerList {}.Append (
102
- Handler {
103
- Name : ValidateCfgHandlerName ,
104
- Fn : func (ctx context.Context , m * Machine ) error {
105
- // ensure that the configuration is valid for the
106
- // FcInit handlers.
107
- return m .cfg .Validate ()
108
- },
109
- },
110
- )
111
-
112
181
var defaultFcInitHandlerList = HandlerList {}.Append (
113
182
StartVMMHandler ,
114
183
BootstrapLoggingHandler ,
@@ -120,8 +189,7 @@ var defaultFcInitHandlerList = HandlerList{}.Append(
120
189
)
121
190
122
191
var defaultHandlers = Handlers {
123
- Validation : defaultValidationHandlerList ,
124
- FcInit : defaultFcInitHandlerList ,
192
+ FcInit : defaultFcInitHandlerList ,
125
193
}
126
194
127
195
// Handler represents a named handler that contains a name and a function which
@@ -140,9 +208,12 @@ type Handlers struct {
140
208
// Run will execute all handlers in the Handlers object by flattening the lists
141
209
// into a single list and running.
142
210
func (h Handlers ) Run (ctx context.Context , m * Machine ) error {
143
- l := HandlerList {}.Append (
144
- h .Validation .list ... ,
145
- ).Append (
211
+ l := HandlerList {}
212
+ if ! m .cfg .DisableValidation {
213
+ l = l .Append (h .Validation .list ... )
214
+ }
215
+
216
+ l = l .Append (
146
217
h .FcInit .list ... ,
147
218
)
148
219
@@ -162,6 +233,21 @@ func (l HandlerList) Append(handlers ...Handler) HandlerList {
162
233
return l
163
234
}
164
235
236
+ // AppendAfter will append a given handler after the specified handler.
237
+ func (l HandlerList ) AppendAfter (name string , handler Handler ) HandlerList {
238
+ newList := HandlerList {}
239
+ for _ , h := range l .list {
240
+ if h .Name == name {
241
+ newList = newList .Append (h , handler )
242
+ continue
243
+ }
244
+
245
+ newList = newList .Append (h )
246
+ }
247
+
248
+ return newList
249
+ }
250
+
165
251
// Len return the length of the given handler list
166
252
func (l HandlerList ) Len () int {
167
253
return len (l .list )
@@ -229,6 +315,7 @@ func (l HandlerList) Run(ctx context.Context, m *Machine) error {
229
315
for _ , handler := range l .list {
230
316
m .logger .Debugf ("Running handler %s" , handler .Name )
231
317
if err := handler .Fn (ctx , m ); err != nil {
318
+ m .logger .Warnf ("Failed handler %q: %v" , handler .Name , err )
232
319
return err
233
320
}
234
321
}
0 commit comments