功能:完善云管助手与GPU故障恢复核对
This commit is contained in:
1 parent
b6026f9759
commit
9f7b01e4db
42 files changed
+3576
-120
No files matched your search
@@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -123,16 +124,48 @@ func (c *Client) Action(ctx context.Context, node string, vmid int, action strin
|
||||
}
|
||||
func (c *Client) Task(ctx context.Context, node, upid string) (TaskStatus, error) {
|
||||
var status TaskStatus
|
||||
err := c.request(ctx, "GET", "/nodes/"+url.PathEscape(node)+"/tasks/"+url.PathEscape(upid)+"/status", nil, &status)
|
||||
err := c.readWithRetry(ctx, "/nodes/"+url.PathEscape(node)+"/tasks/"+url.PathEscape(upid)+"/status", &status)
|
||||
return status, err
|
||||
}
|
||||
func (c *Client) Power(ctx context.Context, node string, vmid int) (string, error) {
|
||||
var status struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
err := c.request(ctx, "GET", fmt.Sprintf("/nodes/%s/qemu/%d/status/current", url.PathEscape(node), vmid), nil, &status)
|
||||
err := c.readWithRetry(ctx, fmt.Sprintf("/nodes/%s/qemu/%d/status/current", url.PathEscape(node), vmid), &status)
|
||||
return status.Status, err
|
||||
}
|
||||
|
||||
// Retry only observations. A lost POST response may already have changed the
|
||||
// VM, so commands must never use this path.
|
||||
func (c *Client) readWithRetry(ctx context.Context, path string, out any) error {
|
||||
var err error
|
||||
for attempt := 0; attempt < 3; attempt++ {
|
||||
if err = ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.request(ctx, "GET", path, nil, out)
|
||||
if err == nil || !retryableRead(err) || attempt == 2 {
|
||||
return err
|
||||
}
|
||||
timer := time.NewTimer(time.Duration(attempt+1) * 250 * time.Millisecond)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
timer.Stop()
|
||||
return ctx.Err()
|
||||
case <-timer.C:
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func retryableRead(err error) bool {
|
||||
var response *HTTPError
|
||||
if errors.As(err, &response) {
|
||||
return response.Status == 408 || response.Status == 429 || response.Status == 500 || response.Status == 502 || response.Status == 503 || response.Status == 504
|
||||
}
|
||||
var network net.Error
|
||||
return errors.As(err, &network) && (network.Timeout() || network.Temporary()) || errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF)
|
||||
}
|
||||
func (c *Client) Wait(ctx context.Context, node, upid string, interval time.Duration) error {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
Reference in new issue
Block a user