@@ -109,9 +109,16 @@ func doRun(flags *cobra.Command, args []string) error {
109
109
return fmt .Errorf ("unable to pull container image: %w" , err )
110
110
}
111
111
112
- // create the cache directory
113
- cache := cache .NewCache (containerImage .GetId (), user )
114
- err = cache .Create ()
112
+ // create the cacheDir directory
113
+ cacheDir , err := cache .NewCache (containerImage .GetId (), user )
114
+ if err != nil {
115
+ return fmt .Errorf ("unable to create cache: %w" , err )
116
+ }
117
+ err = cacheDir .Lock (cache .Exclusive )
118
+ if err != nil {
119
+ return err
120
+ }
121
+ err = cacheDir .Create ()
115
122
if err != nil {
116
123
return fmt .Errorf ("unable to create cache: %w" , err )
117
124
}
@@ -121,13 +128,20 @@ func doRun(flags *cobra.Command, args []string) error {
121
128
ImageID : containerImage .GetId (),
122
129
User : user ,
123
130
LibvirtUri : config .LibvirtUri ,
124
- Locking : utils .Shared ,
125
131
})
126
132
127
133
if err != nil {
128
134
return fmt .Errorf ("unable to initialize VM: %w" , err )
129
135
}
130
136
137
+ defer func () {
138
+ // Let's be explicit instead of relying on the defer exec order
139
+ bootcVM .CloseConnection ()
140
+ if err := cacheDir .Unlock (); err != nil {
141
+ logrus .Warningf ("unable to unlock cache %s: %v" , cacheDir .ImageId , err )
142
+ }
143
+ }()
144
+
131
145
isRunning , err := bootcVM .IsRunning ()
132
146
if err != nil {
133
147
return fmt .Errorf ("unable to check if VM is running: %w" , err )
@@ -145,7 +159,7 @@ func doRun(flags *cobra.Command, args []string) error {
145
159
}
146
160
147
161
// create the disk image
148
- bootcDisk := bootc .NewBootcDisk (containerImage , ctx , user , cache , bustCache )
162
+ bootcDisk := bootc .NewBootcDisk (containerImage , ctx , user , cacheDir , bustCache )
149
163
err = bootcDisk .Install (vmConfig .Quiet , diskImageConfigInstance )
150
164
151
165
if err != nil {
@@ -159,14 +173,6 @@ func doRun(flags *cobra.Command, args []string) error {
159
173
return fmt .Errorf ("unable to get free port for SSH: %w" , err )
160
174
}
161
175
162
- // Let's be explicit instead of relying on the defer exec order
163
- defer func () {
164
- bootcVM .CloseConnection ()
165
- if err := bootcVM .Unlock (); err != nil {
166
- logrus .Warningf ("unable to unlock VM %s: %v" , containerImage .GetId (), err )
167
- }
168
- }()
169
-
170
176
cmd := args [1 :]
171
177
err = bootcVM .Run (vm.RunVMParameters {
172
178
Cmd : cmd ,
@@ -189,6 +195,20 @@ func doRun(flags *cobra.Command, args []string) error {
189
195
return err
190
196
}
191
197
198
+ // done modifying the cache, so remove the Exclusive lock
199
+ err = cacheDir .Unlock ()
200
+ if err != nil {
201
+ return fmt .Errorf ("unable to unlock cache: %w" , err )
202
+ }
203
+
204
+ // take a RO lock for the SSH connection
205
+ // it will be unlocked at the end of this function
206
+ // by the previous defer()
207
+ err = cacheDir .Lock (cache .Shared )
208
+ if err != nil {
209
+ return err
210
+ }
211
+
192
212
if ! vmConfig .Background {
193
213
if ! vmConfig .Quiet {
194
214
var vmConsoleWg sync.WaitGroup
@@ -230,6 +250,20 @@ func doRun(flags *cobra.Command, args []string) error {
230
250
231
251
// Always remove when executing a command
232
252
if vmConfig .RemoveVm || len (cmd ) > 0 {
253
+ // remove the RO lock
254
+ err = cacheDir .Unlock ()
255
+ if err != nil {
256
+ return err
257
+ }
258
+
259
+ // take an exclusive lock to remove the VM
260
+ // it will be unlocked at the end of this function
261
+ // by the previous defer()
262
+ err = cacheDir .Lock (cache .Exclusive )
263
+ if err != nil {
264
+ return err
265
+ }
266
+
233
267
err = bootcVM .Delete () //delete the VM, but keep the disk image
234
268
if err != nil {
235
269
return fmt .Errorf ("unable to remove VM from cache: %w" , err )
0 commit comments