/
lxd_operations.go
141 lines (110 loc) · 3.81 KB
/
lxd_operations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package lxd
import (
"fmt"
"net/url"
"github.com/gorilla/websocket"
"github.com/canonical/lxd/shared/api"
)
// GetOperationUUIDs returns a list of operation uuids.
func (r *ProtocolLXD) GetOperationUUIDs() ([]string, error) {
// Fetch the raw URL values.
urls := []string{}
baseURL := "/operations"
_, err := r.queryStruct("GET", baseURL, nil, "", &urls)
if err != nil {
return nil, err
}
// Parse it.
return urlsToResourceNames(baseURL, urls...)
}
// GetOperations returns a list of Operation struct.
func (r *ProtocolLXD) GetOperations() ([]api.Operation, error) {
apiOperations := map[string][]api.Operation{}
// Fetch the raw value.
_, err := r.queryStruct("GET", "/operations?recursion=1", nil, "", &apiOperations)
if err != nil {
return nil, err
}
// Turn it into a list of operations.
operations := []api.Operation{}
for _, v := range apiOperations {
operations = append(operations, v...)
}
return operations, nil
}
// GetOperationsAllProjects returns a list of operations from all projects.
func (r *ProtocolLXD) GetOperationsAllProjects() ([]api.Operation, error) {
err := r.CheckExtension("operations_get_query_all_projects")
if err != nil {
return nil, err
}
apiOperations := map[string][]api.Operation{}
path := "/operations"
v := url.Values{}
v.Set("recursion", "1")
v.Set("all-projects", "true")
// Fetch the raw value.
_, err = r.queryStruct("GET", fmt.Sprintf("%s?%s", path, v.Encode()), nil, "", &apiOperations)
if err != nil {
return nil, err
}
// Turn it into a list of operations.
operations := []api.Operation{}
for _, v := range apiOperations {
operations = append(operations, v...)
}
return operations, nil
}
// GetOperation returns an Operation entry for the provided uuid.
func (r *ProtocolLXD) GetOperation(uuid string) (*api.Operation, string, error) {
op := api.Operation{}
// Fetch the raw value
etag, err := r.queryStruct("GET", fmt.Sprintf("/operations/%s", url.PathEscape(uuid)), nil, "", &op)
if err != nil {
return nil, "", err
}
return &op, etag, nil
}
// GetOperationWait returns an Operation entry for the provided uuid once it's complete or hits the timeout.
func (r *ProtocolLXD) GetOperationWait(uuid string, timeout int) (*api.Operation, string, error) {
op := api.Operation{}
// Unset the response header timeout so that the request does not time out.
transport, err := r.getUnderlyingHTTPTransport()
if err != nil {
return nil, "", err
}
transport.ResponseHeaderTimeout = 0
// Fetch the raw value
etag, err := r.queryStruct("GET", fmt.Sprintf("/operations/%s/wait?timeout=%d", url.PathEscape(uuid), timeout), nil, "", &op)
if err != nil {
return nil, "", err
}
return &op, etag, nil
}
// GetOperationWaitSecret returns an Operation entry for the provided uuid and secret once it's complete or hits the timeout.
func (r *ProtocolLXD) GetOperationWaitSecret(uuid string, secret string, timeout int) (*api.Operation, string, error) {
op := api.Operation{}
// Fetch the raw value
etag, err := r.queryStruct("GET", fmt.Sprintf("/operations/%s/wait?secret=%s&timeout=%d", url.PathEscape(uuid), url.PathEscape(secret), timeout), nil, "", &op)
if err != nil {
return nil, "", err
}
return &op, etag, nil
}
// GetOperationWebsocket returns a websocket connection for the provided operation.
func (r *ProtocolLXD) GetOperationWebsocket(uuid string, secret string) (*websocket.Conn, error) {
path := fmt.Sprintf("/operations/%s/websocket", url.PathEscape(uuid))
if secret != "" {
path = fmt.Sprintf("%s?secret=%s", path, url.QueryEscape(secret))
}
return r.websocket(path)
}
// DeleteOperation deletes (cancels) a running operation.
func (r *ProtocolLXD) DeleteOperation(uuid string) error {
// Send the request
_, _, err := r.query("DELETE", fmt.Sprintf("/operations/%s", url.PathEscape(uuid)), nil, "")
if err != nil {
return err
}
return nil
}