~nskaggs/+junk/juju-packaging-test

« back to all changes in this revision

Viewing changes to src/github.com/altoros/gosigma/drive.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-27 20:23:11 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161027202311-sux4jk2o73p1d6rg
Re-add src

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2014 ALTOROS
 
2
// Licensed under the AGPLv3, see LICENSE file for details.
 
3
 
 
4
package gosigma
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "time"
 
9
 
 
10
        "github.com/altoros/gosigma/data"
 
11
)
 
12
 
 
13
const (
 
14
        // DriveUnmounted defines constant for unmounted drive status
 
15
        DriveUnmounted = "unmounted"
 
16
        // DriveCreating defines constant for creating drive status
 
17
        DriveCreating = "creating"
 
18
        // DriveResizing defines constant for resizing drive status
 
19
        DriveResizing = "resizing"
 
20
        // DriveCloningDst defines constant for drive cloning status
 
21
        DriveCloningDst = "cloning_dst"
 
22
        // ... may be another values here, contact CloudSigma devs
 
23
)
 
24
 
 
25
const (
 
26
        // MediaCdrom defines media type for cdrom drives
 
27
        MediaCdrom = "cdrom"
 
28
        // MediaDisk defines media type for disk drives
 
29
        MediaDisk = "disk"
 
30
)
 
31
 
 
32
// A Drive interface represents drive instance in CloudSigma account
 
33
type Drive interface {
 
34
        // CloudSigma resource
 
35
        Resource
 
36
 
 
37
        // Affinities
 
38
        Affinities() []string
 
39
 
 
40
        // AllowMultimount
 
41
        AllowMultimount() bool
 
42
 
 
43
        // Get meta-information value stored in the drive instance
 
44
        Get(key string) (v string, ok bool)
 
45
 
 
46
        // Media of drive instance
 
47
        Media() string
 
48
 
 
49
        // Name of drive instance
 
50
        Name() string
 
51
 
 
52
        // Owner of drive instance
 
53
        Owner() Resource
 
54
 
 
55
        // Size of drive in bytes
 
56
        Size() uint64
 
57
 
 
58
        // Status of drive instance
 
59
        Status() string
 
60
 
 
61
        // StorageType of drive instance
 
62
        StorageType() string
 
63
 
 
64
        // IsLibrary returns true if this drive is CloudSigma library drive
 
65
        Library() LibrarySpec
 
66
 
 
67
        // OS returns operating system of the drive (defined for library drives)
 
68
        OS() string
 
69
 
 
70
        // Arch returns operating system bit architecture the drive (defined for library drives)
 
71
        Arch() string
 
72
 
 
73
        // Paid image or free (defined for library drives)
 
74
        Paid() bool
 
75
 
 
76
        // ImageType returns type of drive image (defined for library drives)
 
77
        ImageType() string
 
78
 
 
79
        // Clone drive instance
 
80
        Clone(params CloneParams, avoid []string) (Drive, error)
 
81
 
 
82
        // Clone drive instance, wait for operation finished
 
83
        CloneWait(params CloneParams, avoid []string) (Drive, error)
 
84
 
 
85
        // Jobs for this drive instance.
 
86
        // Every job object in resulting slice carries only UUID and URI.
 
87
        // To obtain additional information for job, one should use Job.Refresh() method
 
88
        // to query cloud for detailed job information.
 
89
        Jobs() []Job
 
90
 
 
91
        // Refresh information about drive instance
 
92
        Refresh() error
 
93
 
 
94
        // Resize drive instance
 
95
        Resize(newSize uint64) error
 
96
 
 
97
        // Resize drive instance, wait for operation finished
 
98
        ResizeWait(newSize uint64) error
 
99
 
 
100
        // Wait for user-defined event
 
101
        Wait(stop func(Drive) bool) error
 
102
 
 
103
        // Remove drive
 
104
        Remove() error
 
105
}
 
106
 
 
107
// A drive implements drive instance in CloudSigma account
 
108
type drive struct {
 
109
        client  *Client
 
110
        obj     *data.Drive
 
111
        library LibrarySpec
 
112
}
 
113
 
 
114
var _ Drive = (*drive)(nil)
 
115
 
 
116
// String method is used to print values passed as an operand to any format that
 
117
// accepts a string or to an unformatted printer such as Print.
 
118
func (d drive) String() string {
 
119
        return fmt.Sprintf("{Name: %q\nURI: %q\nStatus: %s\nUUID: %q\nSize: %d\nMedia: %s\nStorage: %s}",
 
120
                d.Name(), d.URI(), d.Status(), d.UUID(), d.Size(), d.Media(), d.StorageType())
 
121
}
 
122
 
 
123
// URI of drive instance
 
124
func (d drive) URI() string { return d.obj.URI }
 
125
 
 
126
// UUID of drive instance
 
127
func (d drive) UUID() string { return d.obj.UUID }
 
128
 
 
129
// Affinities
 
130
func (d drive) Affinities() []string { return d.obj.Affinities }
 
131
 
 
132
// AllowMultimount
 
133
func (d drive) AllowMultimount() bool { return d.obj.AllowMultimount }
 
134
 
 
135
// Get meta-information value stored in the drive instance
 
136
func (d drive) Get(key string) (v string, ok bool) {
 
137
        v, ok = d.obj.Meta[key]
 
138
        return
 
139
}
 
140
 
 
141
// Media of drive instance
 
142
func (d drive) Media() string { return d.obj.Media }
 
143
 
 
144
// Name of drive instance
 
145
func (d drive) Name() string { return d.obj.Name }
 
146
 
 
147
// Owner of drive instance
 
148
func (d drive) Owner() Resource {
 
149
        if d.obj.Owner == nil {
 
150
                return nil
 
151
        }
 
152
        return &resource{d.obj.Owner}
 
153
}
 
154
 
 
155
// Size of drive in bytes
 
156
func (d drive) Size() uint64 { return d.obj.Size }
 
157
 
 
158
// Status of drive instance
 
159
func (d drive) Status() string { return d.obj.Status }
 
160
 
 
161
// StorageType of drive instance
 
162
func (d drive) StorageType() string { return d.obj.StorageType }
 
163
 
 
164
// IsLibrary returns true if this drive is CloudSigma library drive
 
165
func (d drive) Library() LibrarySpec { return d.library }
 
166
 
 
167
// OS returns operating system of the drive (defined for library drives)
 
168
func (d drive) OS() string { return d.obj.OS }
 
169
 
 
170
// Arch returns operating system bit architecture the drive (defined for library drives)
 
171
func (d drive) Arch() string { return d.obj.Arch }
 
172
 
 
173
// Paid image or free (defined for library drives)
 
174
func (d drive) Paid() bool { return d.obj.Paid }
 
175
 
 
176
// ImageType returns type of drive image (defined for library drives)
 
177
func (d drive) ImageType() string { return d.obj.ImageType }
 
178
 
 
179
// Clone drive instance.
 
180
func (d drive) Clone(params CloneParams, avoid []string) (Drive, error) {
 
181
        obj, err := d.clone(params, avoid)
 
182
        if err != nil {
 
183
                return nil, err
 
184
        }
 
185
 
 
186
        newDrive := &drive{
 
187
                client:  d.client,
 
188
                obj:     obj,
 
189
                library: LibraryAccount,
 
190
        }
 
191
 
 
192
        return newDrive, nil
 
193
}
 
194
 
 
195
// Clone drive instance, wait for operation finished.
 
196
func (d drive) CloneWait(params CloneParams, avoid []string) (Drive, error) {
 
197
        obj, err := d.clone(params, avoid)
 
198
        if err != nil {
 
199
                return nil, err
 
200
        }
 
201
 
 
202
        newDrive := &drive{
 
203
                client:  d.client,
 
204
                obj:     obj,
 
205
                library: LibraryAccount,
 
206
        }
 
207
 
 
208
        jj := newDrive.Jobs()
 
209
        if len(jj) == 0 {
 
210
                return newDrive, nil
 
211
        }
 
212
 
 
213
        j := jj[0]
 
214
 
 
215
        if err := j.Wait(); err != nil {
 
216
                return nil, err
 
217
        }
 
218
 
 
219
        if err := newDrive.Refresh(); err != nil {
 
220
                return nil, err
 
221
        }
 
222
 
 
223
        if d.Library() == LibraryMedia {
 
224
                obj.LibraryDrive = d.obj.LibraryDrive
 
225
        }
 
226
 
 
227
        return newDrive, nil
 
228
}
 
229
 
 
230
// Jobs for this drive instance.
 
231
// Every job object in resulting slice carries only UUID and URI.
 
232
// To obtain additional information for job, one should use Job.Refresh() method
 
233
// to query cloud for detailed job information.
 
234
func (d drive) Jobs() []Job {
 
235
        r := make([]Job, 0, len(d.obj.Jobs))
 
236
        for _, j := range d.obj.Jobs {
 
237
                j := &job{d.client, &data.Job{Resource: j}}
 
238
                r = append(r, j)
 
239
        }
 
240
        return r
 
241
}
 
242
 
 
243
// Refresh information about drive instance
 
244
func (d *drive) Refresh() error {
 
245
        obj, err := d.client.getDrive(d.UUID(), d.Library())
 
246
        if err != nil {
 
247
                return err
 
248
        }
 
249
        d.obj = obj
 
250
        return nil
 
251
}
 
252
 
 
253
// Resize drive instance
 
254
func (d *drive) Resize(newSize uint64) error {
 
255
        return d.resize(newSize)
 
256
}
 
257
 
 
258
// Resize drive instance, wait for operation finished
 
259
func (d *drive) ResizeWait(newSize uint64) error {
 
260
        // try to resize drive
 
261
        if err := d.resize(newSize); err != nil {
 
262
                return err
 
263
        }
 
264
 
 
265
        // wait for status 'resizing' changes back to 'unmounted'
 
266
        return d.Wait(func(d Drive) bool {
 
267
                return d.Status() == DriveUnmounted
 
268
        })
 
269
}
 
270
 
 
271
// Wait for user-defined event
 
272
func (d *drive) Wait(stop func(Drive) bool) error {
 
273
        var timedout = false
 
274
 
 
275
        timeout := d.client.GetOperationTimeout()
 
276
        if timeout > 0 {
 
277
                timer := time.AfterFunc(timeout, func() { timedout = true })
 
278
                defer timer.Stop()
 
279
        }
 
280
 
 
281
        for !stop(d) {
 
282
                if err := d.Refresh(); err != nil {
 
283
                        return err
 
284
                }
 
285
                if timedout {
 
286
                        return ErrOperationTimeout
 
287
                }
 
288
        }
 
289
 
 
290
        return nil
 
291
}
 
292
 
 
293
// Remove drive
 
294
func (d *drive) Remove() error {
 
295
        return d.client.RemoveDrive(d.UUID(), d.Library())
 
296
}