...
1
2
3 package management
4
5
6
7
8 import (
9 "encoding/xml"
10 "errors"
11 "fmt"
12 "time"
13 )
14
15 var (
16
17
18 ErrOperationCancelled = errors.New("Polling for operation status cancelled")
19 )
20
21
22
23
24
25 type GetOperationStatusResponse struct {
26 XMLName xml.Name `xml:"http://schemas.microsoft.com/windowsazure Operation"`
27 ID string
28 Status OperationStatus
29 HTTPStatusCode string
30 Error *AzureError
31 }
32
33
34
35 type OperationStatus string
36
37
38 const (
39 OperationStatusInProgress OperationStatus = "InProgress"
40 OperationStatusSucceeded OperationStatus = "Succeeded"
41 OperationStatusFailed OperationStatus = "Failed"
42 )
43
44
45
46 type OperationID string
47
48 func (c client) GetOperationStatus(operationID OperationID) (GetOperationStatusResponse, error) {
49 operation := GetOperationStatusResponse{}
50 if operationID == "" {
51 return operation, fmt.Errorf(errParamNotSpecified, "operationID")
52 }
53
54 url := fmt.Sprintf("operations/%s", operationID)
55 response, azureErr := c.SendAzureGetRequest(url)
56 if azureErr != nil {
57 return operation, azureErr
58 }
59
60 err := xml.Unmarshal(response, &operation)
61 return operation, err
62 }
63
64 func (c client) WaitForOperation(operationID OperationID, cancel chan struct{}) error {
65 for {
66 done, err := c.checkOperationStatus(operationID)
67 if err != nil || done {
68 return err
69 }
70 select {
71 case <-time.After(c.config.OperationPollInterval):
72 case <-cancel:
73 return ErrOperationCancelled
74 }
75 }
76 }
77
78 func (c client) checkOperationStatus(id OperationID) (done bool, err error) {
79 op, err := c.GetOperationStatus(id)
80 if err != nil {
81 return false, fmt.Errorf("Failed to get operation status '%s': %v", id, err)
82 }
83
84 switch op.Status {
85 case OperationStatusSucceeded:
86 return true, nil
87 case OperationStatusFailed:
88 if op.Error != nil {
89 return true, op.Error
90 }
91 return true, fmt.Errorf("Azure Operation (x-ms-request-id=%s) has failed", id)
92 case OperationStatusInProgress:
93 return false, nil
94 default:
95 return false, fmt.Errorf("Unknown operation status returned from API: %s (x-ms-request-id=%s)", op.Status, id)
96 }
97 }
98
View as plain text