@@ -72,12 +72,12 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
7272 if req .CheckExistingDeployments {
7373 for _ , target := range req .Targets {
7474 targetPoolName := fmt .Sprintf ("%s_%s" , req .Template , target .Name )
75- isDeployed , err := cs .IsDeployed (targetPoolName )
75+ isValid , err := cs .ValidateCloneRequest (targetPoolName , target . Name )
7676 if err != nil {
77- return fmt .Errorf ("failed to check if template is deployed for %s: %w" , target .Name , err )
77+ return fmt .Errorf ("failed to validate the deployment of template for %s: %w" , target .Name , err )
7878 }
79- if isDeployed {
80- return fmt .Errorf ("template %s is already or in the process of being deployed for %s " , req .Template , target .Name )
79+ if ! isValid {
80+ return fmt .Errorf ("template %s is already deployed for %s or they have exceeded the maximum of 5 deployed pods " , req .Template , target .Name )
8181 }
8282 }
8383 }
@@ -127,9 +127,22 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
127127 return fmt .Errorf ("failed to get next pod IDs: %w" , err )
128128 }
129129
130- vmIDs , err := cs .ProxmoxService .GetNextVMIDs (len (req .Targets ) * numVMsPerTarget )
131- if err != nil {
132- return fmt .Errorf ("failed to get next VM IDs: %w" , err )
130+ // Lock the vmid allocation mutex to prevent race conditions during vmid allocation
131+ cs .vmidMutex .Lock ()
132+
133+ // Use StartingVMID from request if provided, otherwise get next available VMIDs
134+ var vmIDs []int
135+ numVMs := len (req .Targets ) * numVMsPerTarget
136+ if req .StartingVMID != 0 {
137+ log .Printf ("Starting VMID allocation from specified starting VMID: %d" , req .StartingVMID )
138+ for i := range numVMs {
139+ vmIDs = append (vmIDs , req .StartingVMID + i )
140+ }
141+ } else {
142+ vmIDs , err = cs .ProxmoxService .GetNextVMIDs (numVMs )
143+ if err != nil {
144+ return fmt .Errorf ("failed to get next VM IDs: %w" , err )
145+ }
133146 }
134147
135148 for i := range req .Targets {
@@ -169,7 +182,7 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
169182 NewVMID : target .VMIDs [0 ],
170183 TargetNode : bestNode ,
171184 }
172- err = cs .ProxmoxService .CloneVMWithConfig (routerCloneReq )
185+ err = cs .ProxmoxService .CloneVM (routerCloneReq )
173186 if err != nil {
174187 errors = append (errors , fmt .Sprintf ("failed to clone router VM for %s: %v" , target .Name , err ))
175188 } else {
@@ -191,7 +204,7 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
191204 NewVMID : target .VMIDs [i + 1 ],
192205 TargetNode : bestNode ,
193206 }
194- err := cs .ProxmoxService .CloneVMWithConfig (vmCloneReq )
207+ err := cs .ProxmoxService .CloneVM (vmCloneReq )
195208 if err != nil {
196209 errors = append (errors , fmt .Sprintf ("failed to clone VM %s for %s: %v" , vm .Name , target .Name , err ))
197210 }
@@ -223,6 +236,9 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
223236 }
224237 }
225238
239+ // Release the vmid allocation mutex now that all of the VMs are cloned on proxmox
240+ cs .vmidMutex .Unlock ()
241+
226242 // 9. Configure VNet of all VMs
227243 log .Printf ("Configuring VNets for %d targets" , len (req .Targets ))
228244 for _ , target := range req .Targets {
@@ -254,12 +270,8 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
254270 }
255271
256272 // Wait for router to be running
257- routerVM := proxmox.VM {
258- Node : routerInfo .Node ,
259- VMID : routerInfo .VMID ,
260- }
261273 log .Printf ("Waiting for router VM to be running for %s (VMID: %d)" , routerInfo .TargetName , routerInfo .VMID )
262- err = cs .ProxmoxService .WaitForRunning (routerVM )
274+ err = cs .ProxmoxService .WaitForRunning (routerInfo . Node , routerInfo . VMID )
263275 if err != nil {
264276 errors = append (errors , fmt .Sprintf ("failed to start router VM for %s: %v" , routerInfo .TargetName , err ))
265277 }
@@ -268,14 +280,8 @@ func (cs *CloningService) CloneTemplate(req CloneRequest) error {
268280 // 11. Configure all pod routers (separate step after all routers are running)
269281 log .Printf ("Configuring %d pod routers" , len (clonedRouters ))
270282 for _ , routerInfo := range clonedRouters {
271- // Only configure routers that successfully started
272- routerVM := proxmox.VM {
273- Node : routerInfo .Node ,
274- VMID : routerInfo .VMID ,
275- }
276-
277283 // Double-check that router is still running before configuration
278- err = cs .ProxmoxService .WaitForRunning (routerVM )
284+ err = cs .ProxmoxService .WaitForRunning (routerInfo . Node , routerInfo . VMID )
279285 if err != nil {
280286 errors = append (errors , fmt .Sprintf ("router not running before configuration for %s: %v" , routerInfo .TargetName , err ))
281287 continue
@@ -360,7 +366,7 @@ func (cs *CloningService) DeletePod(pod string) error {
360366 // Wait for all previously running VMs to be stopped
361367 if len (runningVMs ) > 0 {
362368 for _ , vm := range runningVMs {
363- if err := cs .ProxmoxService .WaitForStopped (vm ); err != nil {
369+ if err := cs .ProxmoxService .WaitForStopped (vm . Node , vm . VMID ); err != nil {
364370 // Continue with deletion even if we can't confirm the VM is stopped
365371 }
366372 }
0 commit comments