diff --git a/server/services/pve.go b/server/services/pve.go index c296c31..b532cc7 100644 --- a/server/services/pve.go +++ b/server/services/pve.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/cookiejar" "net/url" + "strconv" "strings" "time" @@ -81,16 +82,21 @@ func (c *PVEClient) Login() error { var result struct { Data struct { CSRFToken string `json:"CSRFPreventionToken"` - Cookie string `json:"PVEAuthCookie"` + Ticket string `json:"ticket"` } `json:"data"` } - if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { - return err + body, err := io.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("read login response failed: %v", err) + } + + if err := json.Unmarshal(body, &result); err != nil { + return fmt.Errorf("decode login response failed: %v, body: %s", err, string(body)) } c.CSRFToken = result.Data.CSRFToken - c.Cookie = result.Data.Cookie + c.Cookie = "PVEAuthCookie=" + result.Data.Ticket return nil } @@ -103,7 +109,7 @@ func (c *PVEClient) GetVMStatus(vmid string) (*models.PVEVMStatus, error) { } // 获取 node 名称(通常是 pve) - statusURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu/" + vmid + "/status" + statusURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu/" + vmid + "/status/current" req, err := http.NewRequest("GET", statusURL, nil) if err != nil { @@ -246,7 +252,7 @@ func (c *PVEClient) GetVMList() ([]struct { } } - listURL := c.baseURL() + "/api2/json/cluster/resources?type=vm" + listURL := c.baseURL() + "/api2/json/nodes/" + c.NodeName + "/qemu" req, err := http.NewRequest("GET", listURL, nil) if err != nil { @@ -262,22 +268,45 @@ func (c *PVEClient) GetVMList() ([]struct { defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("get vm list failed, status: %d", resp.StatusCode) + body, _ := io.ReadAll(resp.Body) + return nil, fmt.Errorf("get vm list failed, status: %d, body: %s", resp.StatusCode, string(body)) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("read vm list body failed: %v", err) } var result struct { Data []struct { - VMID string `json:"vmid"` + VMID int `json:"vmid"` Name string `json:"name"` Status string `json:"status"` } `json:"data"` } - if err := json.NewDecoder(resp.Body).Decode(&result); err != nil { - return nil, err + if err := json.Unmarshal(body, &result); err != nil { + return nil, fmt.Errorf("decode vm list failed: %v, body: %s", err, string(body)) } - return result.Data, nil + // vmid 是 int,转换为 string + vms := make([]struct { + VMID string `json:"vmid"` + Name string `json:"name"` + Status string `json:"status"` + }, len(result.Data)) + for i, vm := range result.Data { + vms[i] = struct { + VMID string `json:"vmid"` + Name string `json:"name"` + Status string `json:"status"` + }{ + VMID: strconv.Itoa(vm.VMID), + Name: vm.Name, + Status: vm.Status, + } + } + return vms, nil } // PVEHostService PVE 主机服务