@@ -109,9 +109,16 @@ func doRun(flags *cobra.Command, args []string) error {
109109 return fmt .Errorf ("unable to pull container image: %w" , err )
110110 }
111111
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 ()
115122 if err != nil {
116123 return fmt .Errorf ("unable to create cache: %w" , err )
117124 }
@@ -121,13 +128,20 @@ func doRun(flags *cobra.Command, args []string) error {
121128 ImageID : containerImage .GetId (),
122129 User : user ,
123130 LibvirtUri : config .LibvirtUri ,
124- Locking : utils .Shared ,
125131 })
126132
127133 if err != nil {
128134 return fmt .Errorf ("unable to initialize VM: %w" , err )
129135 }
130136
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+
131145 isRunning , err := bootcVM .IsRunning ()
132146 if err != nil {
133147 return fmt .Errorf ("unable to check if VM is running: %w" , err )
@@ -145,7 +159,7 @@ func doRun(flags *cobra.Command, args []string) error {
145159 }
146160
147161 // create the disk image
148- bootcDisk := bootc .NewBootcDisk (containerImage , ctx , user , cache , bustCache )
162+ bootcDisk := bootc .NewBootcDisk (containerImage , ctx , user , cacheDir , bustCache )
149163 err = bootcDisk .Install (vmConfig .Quiet , diskImageConfigInstance )
150164
151165 if err != nil {
@@ -159,14 +173,6 @@ func doRun(flags *cobra.Command, args []string) error {
159173 return fmt .Errorf ("unable to get free port for SSH: %w" , err )
160174 }
161175
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-
170176 cmd := args [1 :]
171177 err = bootcVM .Run (vm.RunVMParameters {
172178 Cmd : cmd ,
@@ -189,6 +195,20 @@ func doRun(flags *cobra.Command, args []string) error {
189195 return err
190196 }
191197
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+
192212 if ! vmConfig .Background {
193213 if ! vmConfig .Quiet {
194214 var vmConsoleWg sync.WaitGroup
@@ -230,6 +250,21 @@ func doRun(flags *cobra.Command, args []string) error {
230250
231251 // Always remove when executing a command
232252 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+
260+ // take an exclusive lock to remove the VM
261+ // it will be unlocked at the end of this function
262+ // by the previous defer()
263+ err = cacheDir .Lock (cache .Exclusive )
264+ if err != nil {
265+ return err
266+ }
267+
233268 err = bootcVM .Delete () //delete the VM, but keep the disk image
234269 if err != nil {
235270 return fmt .Errorf ("unable to remove VM from cache: %w" , err )
0 commit comments