1
// Copyright 2014 ALTOROS
2
// Licensed under the AGPLv3, see LICENSE file for details.
17
"github.com/altoros/gosigma/data"
20
func (c Client) getServers(rqspec RequestSpec) ([]data.Server, error) {
21
u := c.endpoint + "servers"
22
if rqspec == RequestDetail {
26
r, err := c.https.Get(u, url.Values{"limit": {"0"}})
32
if err := r.VerifyJSON(200); err != nil {
33
return nil, NewError(r, err)
36
return data.ReadServers(r.Body)
39
func (c Client) getServer(uuid string) (*data.Server, error) {
40
uuid = strings.TrimSpace(uuid)
42
return nil, errEmptyUUID
45
u := c.endpoint + "servers/" + uuid + "/"
47
r, err := c.https.Get(u, nil)
53
if err := r.VerifyJSON(200); err != nil {
54
return nil, NewError(r, err)
57
return data.ReadServer(r.Body)
60
func (c Client) startServer(uuid string, avoid []string) error {
61
uuid = strings.TrimSpace(uuid)
66
u := c.endpoint + "servers/" + uuid + "/action/"
68
var qq = make(url.Values)
69
qq["do"] = []string{"start"}
72
qq["avoid"] = []string{strings.Join(avoid, ",")}
75
r, err := c.https.Post(u, qq, nil)
81
if err := r.VerifyJSON(202); err != nil {
82
return NewError(r, err)
88
func (c Client) stopServer(uuid string) error {
89
uuid = strings.TrimSpace(uuid)
94
u := c.endpoint + "servers/" + uuid + "/action/"
96
var qq = make(url.Values)
97
qq["do"] = []string{"stop"}
99
r, err := c.https.Post(u, qq, nil)
105
if err := r.VerifyJSON(202); err != nil {
106
return NewError(r, err)
112
func (c Client) removeServer(uuid, recurse string) error {
113
uuid = strings.TrimSpace(uuid)
118
u := c.endpoint + "servers/" + uuid + "/"
121
recurse = strings.TrimSpace(recurse)
123
qq = make(url.Values)
124
qq["recurse"] = []string{recurse}
127
r, err := c.https.Delete(u, qq, nil)
133
if err := r.VerifyCode(204); err != nil {
134
return NewError(r, err)
140
func (c Client) createServer(components Components) ([]data.Server, error) {
142
rr, err := components.marshal()
148
u := c.endpoint + "servers/"
149
r, err := c.https.Post(u, nil, rr)
155
if err := r.VerifyJSON(201); err != nil {
156
return nil, NewError(r, err)
159
return data.ReadServers(r.Body)
162
func (c Client) getDrives(rqspec RequestSpec, libspec LibrarySpec) ([]data.Drive, error) {
164
if libspec == LibraryMedia {
169
if rqspec == RequestDetail {
173
r, err := c.https.Get(u, url.Values{"limit": {"0"}})
179
if err := r.VerifyJSON(200); err != nil {
180
return nil, NewError(r, err)
183
return data.ReadDrives(r.Body)
186
func (c Client) getDrive(uuid string, libspec LibrarySpec) (*data.Drive, error) {
187
uuid = strings.TrimSpace(uuid)
189
return nil, errEmptyUUID
193
if libspec == LibraryMedia {
200
r, err := c.https.Get(u, nil)
206
if err := r.VerifyJSON(200); err != nil {
207
return nil, NewError(r, err)
210
return data.ReadDrive(r.Body)
213
func (c Client) cloneDrive(uuid string, libspec LibrarySpec, params CloneParams, avoid []string) (*data.Drive, error) {
214
uuid = strings.TrimSpace(uuid)
216
return nil, errEmptyUUID
220
if libspec == LibraryMedia {
225
u += uuid + "/action/"
227
var qq = make(url.Values)
228
qq["do"] = []string{"clone"}
231
qq["avoid"] = []string{strings.Join(avoid, ",")}
234
rr, err := params.makeJSONReader()
239
r, err := c.https.Post(u, qq, rr)
245
if err := r.VerifyJSON(202); err != nil {
246
return nil, NewError(r, err)
249
objs, err := data.ReadDrives(r.Body)
256
return nil, errors.New("no object was returned from server")
259
if libspec == LibraryMedia {
260
// fix CloudSigma API result, disk has URI pointed to libdrive - must be drives
261
uuid := objs[0].Resource.UUID
262
objs[0].Resource = *data.MakeDriveResource(uuid)
268
func (c *Client) removeDrive(uuid string, libspec LibrarySpec) error {
269
uuid = strings.TrimSpace(uuid)
275
if libspec == LibraryMedia {
282
r, err := c.https.Delete(u, nil, nil)
288
if err := r.VerifyCode(204); err != nil {
289
return NewError(r, err)
295
func (c Client) getJob(uuid string) (*data.Job, error) {
296
uuid = strings.TrimSpace(uuid)
298
return nil, errEmptyUUID
301
u := c.endpoint + "jobs/" + uuid + "/"
303
r, err := c.https.Get(u, nil)
309
if err := r.VerifyJSON(200); err != nil {
310
return nil, NewError(r, err)
313
return data.ReadJob(r.Body)
316
func (c Client) readContext() (*data.Context, error) {
319
DEVICE = "/dev/ttyS1"
326
// open server ctx device
327
f, err := os.OpenFile(DEVICE, os.O_RDWR, 0)
329
return nil, fmt.Errorf("error OpenFile: %s", err)
333
// schedule timeout, if defined
334
readWriteTimeout := c.GetReadWriteTimeout()
335
if readWriteTimeout > 0 {
336
timer := time.AfterFunc(readWriteTimeout, func() {
342
// writing request to service
343
n, err := f.WriteString(REQUEST)
345
return nil, fmt.Errorf("error WriteString: %s", err)
348
// check the request was written
349
if n != len(REQUEST) {
350
return nil, fmt.Errorf("invalid write length %d, wants %d", n, len(REQUEST))
353
// prepare buffered I/O object
354
r := bufio.NewReader(f)
356
// read until End-Of-Transfer (EOT) symbol or EOF
357
bb, err := r.ReadBytes(EOT)
358
if err != nil && err != io.EOF {
359
return nil, fmt.Errorf("error ReadBytes: %s", err)
362
// if EOT was read, truncate it
364
if last := len(bb) - 1; bb[last] == EOT {
369
// log server context as raw content
372
logger.Logf("server context:\n%s", string(bb))
376
// prepare reader around raw content
377
rr := bytes.NewReader(bb)
379
// parse server context JSON to the data.Context object
380
return data.ReadContext(rr)
383
func (c Client) resizeDrive(obj data.Drive, newSize uint64) (*data.Drive, error) {
385
// prepare endpoint URL
386
u := c.endpoint + "drives/" + obj.UUID + "/action/"
388
// prepare request query params
389
var qq = make(url.Values)
390
qq["do"] = []string{"resize"}
392
// prepare request body
394
rr, err := data.WriteDrive(&obj)
400
r, err := c.https.Post(u, qq, rr)
407
if err := r.VerifyJSON(202); err != nil {
408
return nil, NewError(r, err)
411
// read and parse reply body
412
objs, err := data.ReadDrives(r.Body)
418
// verify reply body content
420
return nil, errors.New("no object was returned from server")