@@ -96,17 +96,45 @@ func newLocal(ic *plugin.InitContext) (*local, error) {
96
96
func (s * local ) CreateVM (requestCtx context.Context , req * proto.CreateVMRequest ) (* proto.CreateVMResponse , error ) {
97
97
var err error
98
98
99
- id := req .GetVMID ()
100
- if err := identifiers .Validate (id ); err != nil {
99
+ // Create shim
100
+ _ , err = s .CreateShim (requestCtx , req .GetVMID ())
101
+ if err != nil {
102
+ return nil , err
103
+ }
104
+
105
+ client , err := s .shimFirecrackerClient (requestCtx , req .GetVMID ())
106
+ if err != nil {
107
+ err = errors .Wrap (err , "failed to create firecracker shim client" )
101
108
s .logger .WithError (err ).Error ()
102
109
return nil , err
103
110
}
104
111
112
+ defer client .Close ()
113
+
114
+ resp , err := client .CreateVM (requestCtx , req )
115
+ if err != nil {
116
+ s .logger .WithError (err ).Error ("shim CreateVM returned error" )
117
+ return nil , err
118
+ }
119
+
120
+ return resp , nil
121
+ }
122
+
123
+ func (s * local ) CreateShim (requestCtx context.Context , id string ) (codes.Code , error ) {
124
+ var err error
125
+
126
+ // Validate VM id
127
+ if err := identifiers .Validate (id ); err != nil {
128
+ s .logger .WithError (err ).Error ()
129
+ return codes .Unknown , err
130
+ }
131
+
132
+ // Validate namespace
105
133
ns , err := namespaces .NamespaceRequired (requestCtx )
106
134
if err != nil {
107
135
err = errors .Wrap (err , "error retrieving namespace of request" )
108
136
s .logger .WithError (err ).Error ()
109
- return nil , err
137
+ return codes . Unknown , err
110
138
}
111
139
112
140
s .logger .Debugf ("using namespace: %s" , ns )
@@ -118,36 +146,36 @@ func (s *local) CreateVM(requestCtx context.Context, req *proto.CreateVMRequest)
118
146
if err != nil {
119
147
err = errors .Wrap (err , "failed to obtain shim socket address" )
120
148
s .logger .WithError (err ).Error ()
121
- return nil , err
149
+ return codes . Unknown , err
122
150
}
123
151
124
152
shimSocket , err := shim .NewSocket (shimSocketAddress )
125
153
if shim .SocketEaddrinuse (err ) {
126
- return nil , status .Errorf (codes .AlreadyExists , "VM with ID %q already exists (socket: %q)" , id , shimSocketAddress )
154
+ return codes . AlreadyExists , status .Errorf (codes .AlreadyExists , "VM with ID %q already exists (socket: %q)" , id , shimSocketAddress )
127
155
} else if err != nil {
128
156
err = errors .Wrapf (err , "failed to open shim socket at address %q" , shimSocketAddress )
129
157
s .logger .WithError (err ).Error ()
130
- return nil , err
158
+ return codes . Unknown , err
131
159
}
132
160
133
161
// If we're here, there is no pre-existing shim for this VMID, so we spawn a new one
134
162
if err := os .Mkdir (s .config .ShimBaseDir , 0700 ); err != nil && ! os .IsExist (err ) {
135
163
s .logger .WithError (err ).Error ()
136
- return nil , errors .Wrapf (err , "failed to make shim base directory: %s" , s .config .ShimBaseDir )
164
+ return codes . Unknown , errors .Wrapf (err , "failed to make shim base directory: %s" , s .config .ShimBaseDir )
137
165
}
138
166
139
167
shimDir , err := vm .ShimDir (s .config .ShimBaseDir , ns , id )
140
168
if err != nil {
141
169
err = errors .Wrapf (err , "failed to build shim path" )
142
170
s .logger .WithError (err ).Error ()
143
- return nil , err
171
+ return codes . Unknown , err
144
172
}
145
173
146
174
err = shimDir .Mkdir ()
147
175
if err != nil {
148
176
err = errors .Wrapf (err , "failed to create VM dir %q" , shimDir .RootPath ())
149
177
s .logger .WithError (err ).Error ()
150
- return nil , err
178
+ return codes . Unknown , err
151
179
}
152
180
153
181
defer func () {
@@ -167,19 +195,19 @@ func (s *local) CreateVM(requestCtx context.Context, req *proto.CreateVMRequest)
167
195
if err != nil {
168
196
err = errors .Wrap (err , "failed to obtain shim socket address" )
169
197
s .logger .WithError (err ).Error ()
170
- return nil , err
198
+ return codes . Unknown , err
171
199
}
172
200
173
201
fcSocket , err := shim .NewSocket (fcSocketAddress )
174
202
if err != nil {
175
203
err = errors .Wrapf (err , "failed to open fccontrol socket at address %q" , fcSocketAddress )
176
204
s .logger .WithError (err ).Error ()
177
- return nil , err
205
+ return codes . Unknown , err
178
206
}
179
207
180
208
cmd , err := s .newShim (ns , id , s .containerdAddress , shimSocket , fcSocket )
181
209
if err != nil {
182
- return nil , err
210
+ return codes . Unknown , err
183
211
}
184
212
185
213
defer func () {
@@ -188,26 +216,12 @@ func (s *local) CreateVM(requestCtx context.Context, req *proto.CreateVMRequest)
188
216
}
189
217
}()
190
218
191
- client , err := s .shimFirecrackerClient (requestCtx , id )
192
- if err != nil {
193
- err = errors .Wrap (err , "failed to create firecracker shim client" )
194
- s .logger .WithError (err ).Error ()
195
- return nil , err
196
- }
197
-
198
- defer client .Close ()
199
-
200
- resp , err := client .CreateVM (requestCtx , req )
201
- if err != nil {
202
- s .logger .WithError (err ).Error ("shim CreateVM returned error" )
203
- return nil , err
204
- }
205
-
206
219
s .addShim (shimSocketAddress , cmd )
207
220
208
- return resp , nil
221
+ return codes . OK , nil
209
222
}
210
223
224
+
211
225
func (s * local ) addShim (address string , cmd * exec.Cmd ) {
212
226
s .processesMu .Lock ()
213
227
defer s .processesMu .Unlock ()
@@ -617,6 +631,14 @@ func (s *local) CreateSnapshot(ctx context.Context, req *proto.CreateSnapshotReq
617
631
618
632
// LoadSnapshot Loads a snapshot of a VM
619
633
func (s * local ) LoadSnapshot (ctx context.Context , req * proto.LoadSnapshotRequest ) (* proto.LoadResponse , error ) {
634
+ var err error
635
+
636
+ // Create shim if not exists yet
637
+ code , err := s .CreateShim (ctx , req .GetVMID ())
638
+ if err != nil && code != codes .AlreadyExists {
639
+ return nil , err
640
+ }
641
+
620
642
client , err := s .shimFirecrackerClient (ctx , req .VMID )
621
643
if err != nil {
622
644
return nil , err
@@ -651,4 +673,4 @@ func (s *local) Offload(ctx context.Context, req *proto.OffloadRequest) (*empty.
651
673
}
652
674
653
675
return resp , nil
654
- }
676
+ }
0 commit comments