Skip to content

Commit 6eb6d66

Browse files
committed
In theory, wait for task to finish before trying to start VM
1 parent 7a9c0f0 commit 6eb6d66

File tree

2 files changed

+80
-11
lines changed

2 files changed

+80
-11
lines changed

gui.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,20 @@ func buildWindow(vms ProxmoxVmList, creds ProxmoxCreds, token ProxmoxAuth) {
8686
connectingLayout.AddWidget(statusLabel.QWidget)
8787
connectingLayout.AddSpacing(statusLabel.Height())
8888

89-
clonedVm, err := cloneTemplate(creds, token, vm)
89+
clonedVm, job, err := cloneTemplate(creds, token, vm)
9090
if err != nil {
9191
statusLabel.SetText(fmt.Sprintf("Error: %v\n", err))
9292
log.Fatalf("Error while cloning VM: %v\n", err)
9393
}
9494

95+
for status, err := getJobStatus(creds, token, job); err != nil && strings.Compare(status.Status, "stopped") == 0; status, err = getJobStatus(creds, token, job) {
96+
fmt.Printf("Status: %s\n", status)
97+
statusLabel.SetText("Status: Cloning")
98+
statusLabel.Show()
99+
connectingLayout.AddWidget(statusLabel.QWidget)
100+
connectingLayout.AddSpacing(statusLabel.Height())
101+
}
102+
95103
err = startVM(creds, token, clonedVm)
96104
if err != nil {
97105
return

proxmoxInterface.go

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ import (
1515
"time"
1616
)
1717

18+
type ProxmoxJobStatus struct {
19+
Exitstatus string `json:"exitstatus,omitempty"`
20+
JobId string `json:"upid"`
21+
Status string `json:"status"`
22+
}
23+
1824
type ProxmoxCreds struct {
1925
Username string `json:"username"`
2026
Password string `json:"password"`
@@ -47,6 +53,10 @@ type rawProxmoxInterfaces struct {
4753
Data []ProxmoxInterfaces `json:"data"`
4854
}
4955

56+
type rawProxmoxJobStatus struct {
57+
Data ProxmoxJobStatus `json:"data"`
58+
}
59+
5060
type ProxmoxInterfaces struct {
5161
Address string `json:"address"`
5262
Active int `json:"active"`
@@ -307,7 +317,7 @@ func getNodeAddresses(creds ProxmoxCreds, token ProxmoxAuth) ([]ProxmoxInterface
307317
return parsedResponse.Data, nil
308318
}
309319

310-
func cloneTemplate(creds ProxmoxCreds, token ProxmoxAuth, vm ProxmoxVm) (ProxmoxVm, error) {
320+
func cloneTemplate(creds ProxmoxCreds, token ProxmoxAuth, vm ProxmoxVm) (ProxmoxVm, ProxmoxJobStatus, error) {
311321
// Boilerplate create cookie
312322
authCookie := &http.Cookie{
313323
Name: "PVEAuthCookie",
@@ -331,7 +341,7 @@ func cloneTemplate(creds ProxmoxCreds, token ProxmoxAuth, vm ProxmoxVm) (Proxmox
331341
apiUrl := fmt.Sprintf("https://%s:8006/api2/json/nodes/%s/qemu/%d/clone", creds.Address, vm.Node, vm.VmNumber)
332342
cloneVmReq, err := http.NewRequest(http.MethodPost, apiUrl, bytes.NewBufferString(data.Encode()))
333343
if err != nil {
334-
return ProxmoxVm{}, fmt.Errorf("error while creating request: %+v\nurl: %s\n", err, apiUrl)
344+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("error while creating request: %+v\nurl: %s\n", err, apiUrl)
335345
}
336346

337347
// Add the auth cookies to the request
@@ -341,26 +351,77 @@ func cloneTemplate(creds ProxmoxCreds, token ProxmoxAuth, vm ProxmoxVm) (Proxmox
341351
// Perform the request
342352
cloneVmResp, err := client.Do(cloneVmReq)
343353
if err != nil {
344-
return ProxmoxVm{}, fmt.Errorf("error while performing request: %+v\n", err)
354+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("error while performing request: %+v\n", err)
345355
}
346356

347357
if cloneVmResp.StatusCode != 200 {
348358
response, err := io.ReadAll(cloneVmResp.Body)
349359
if err != nil {
350-
return ProxmoxVm{}, fmt.Errorf("got unexpected status code %d: %s\n", cloneVmResp.StatusCode, cloneVmResp.Status)
360+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("got unexpected status code %d: %s\n", cloneVmResp.StatusCode, cloneVmResp.Status)
351361
}
352362

353363
// Bodge solution for generating an invalid VM ID
354364
if cloneVmResp.StatusCode == 400 && strings.Contains(fmt.Sprintf("%s", response), "invalid format - value does not look like a valid VM ID\\n") {
355-
generatedVm, err := cloneTemplate(creds, token, vm)
356-
return generatedVm, err
365+
generatedVm, jobStatus, err := cloneTemplate(creds, token, vm)
366+
return generatedVm, jobStatus, err
357367
} else {
358-
return ProxmoxVm{}, fmt.Errorf("got unexpected status code %d: %s: %s\n", cloneVmResp.StatusCode, cloneVmResp.Status, response)
368+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("got unexpected status code %d: %s: %s\n", cloneVmResp.StatusCode, cloneVmResp.Status, response)
359369
}
360370
}
361371

362-
fmt.Printf("Status Code: %d\n", cloneVmResp.StatusCode)
363-
fmt.Printf("Status: %s\n", cloneVmResp.Status)
372+
var resp struct {
373+
Data string `json:"data"`
374+
}
375+
376+
body, err := io.ReadAll(cloneVmResp.Body)
377+
if err != nil {
378+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("Error while reading body: %v\n", err)
379+
}
380+
381+
err = json.Unmarshal(body, &resp)
382+
if err != nil {
383+
return ProxmoxVm{}, ProxmoxJobStatus{}, fmt.Errorf("Error while unmarshalling body: %v\n", err)
384+
}
385+
386+
return newVm, ProxmoxJobStatus{JobId: resp.Data}, nil
387+
}
388+
389+
func getJobStatus(creds ProxmoxCreds, token ProxmoxAuth, job ProxmoxJobStatus) (ProxmoxJobStatus, error) {
390+
authCookie := &http.Cookie{
391+
Name: "PVEAuthCookie",
392+
Value: token.Data.Ticket,
393+
}
394+
395+
apiUrl := fmt.Sprintf("https://%s:8006/api2/json/nodes/%s/tasks/%s/status", creds.Address, creds.Server, job.JobId)
396+
397+
req, err := http.NewRequest(http.MethodPost, apiUrl, nil)
398+
if err != nil {
399+
return ProxmoxJobStatus{}, fmt.Errorf("error while creating request: %+v\nurl: %s\n", err, apiUrl)
400+
}
401+
402+
req.AddCookie(authCookie)
403+
req.Header.Add("CSRFPreventionToken", token.Data.CSRF)
404+
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
405+
406+
resp, err := client.Do(req)
407+
if err != nil {
408+
return ProxmoxJobStatus{}, fmt.Errorf("error while performing request: %+v\n", err)
409+
}
410+
411+
if resp.StatusCode != 200 {
412+
return ProxmoxJobStatus{}, fmt.Errorf("unexpected status code %d returned from server: %s\n", resp.StatusCode, resp.Status)
413+
}
414+
415+
body, err := io.ReadAll(resp.Body)
416+
if err != nil {
417+
return ProxmoxJobStatus{}, fmt.Errorf("error while reading response from server: %v\n", err)
418+
}
419+
420+
var jobStatus rawProxmoxJobStatus
421+
err = json.Unmarshal(body, &jobStatus)
422+
if err != nil {
423+
return ProxmoxJobStatus{}, fmt.Errorf("error while unmarshalling json from server: %v\n", err)
424+
}
364425

365-
return newVm, nil
426+
return jobStatus.Data, nil
366427
}

0 commit comments

Comments
 (0)