@@ -31,15 +31,14 @@ import (
3131 volumes_v1 "github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
3232 volumes_v2 "github.com/gophercloud/gophercloud/openstack/blockstorage/v2/volumes"
3333 "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
34- "github.com/gophercloud/gophercloud/pagination"
3534 "github.com/prometheus/client_golang/prometheus"
3635
3736 "github.com/golang/glog"
3837)
3938
4039type volumeService interface {
4140 createVolume (opts VolumeCreateOpts ) (string , string , error )
42- getVolume (diskName string ) (Volume , error )
41+ getVolume (volumeID string ) (Volume , error )
4342 deleteVolume (volumeName string ) error
4443}
4544
@@ -123,107 +122,73 @@ func (volumes *VolumesV2) createVolume(opts VolumeCreateOpts) (string, string, e
123122 return vol .ID , vol .AvailabilityZone , nil
124123}
125124
126- func (volumes * VolumesV1 ) getVolume (diskName string ) (Volume , error ) {
127- var volume_v1 volumes_v1.Volume
128- var volume Volume
125+ func (volumes * VolumesV1 ) getVolume (volumeID string ) (Volume , error ) {
129126 startTime := time .Now ()
130- err := volumes_v1 .List (volumes .blockstorage , nil ).EachPage (func (page pagination.Page ) (bool , error ) {
131- vols , err := volumes_v1 .ExtractVolumes (page )
132- if err != nil {
133- glog .Errorf ("Failed to extract volumes: %v" , err )
134- return false , err
135- } else {
136- for _ , v := range vols {
137- glog .V (4 ).Infof ("%s %s %v" , v .ID , v .Name , v .Attachments )
138- if v .Name == diskName || strings .Contains (v .ID , diskName ) {
139- volume_v1 = v
140- return true , nil
141- }
142- }
143- }
144- // if it reached here then no disk with the given name was found.
145- errmsg := fmt .Sprintf ("Unable to find disk: %s" , diskName )
146- return false , errors .New (errmsg )
147- })
127+ volumeV1 , err := volumes_v1 .Get (volumes .blockstorage , volumeID ).Extract ()
148128 timeTaken := time .Since (startTime ).Seconds ()
149129 recordOpenstackOperationMetric ("get_v1_volume" , timeTaken , err )
150130 if err != nil {
151- glog .Errorf ("Error occurred getting volume: %s" , diskName )
152- return volume , err
131+ glog .Errorf ("Error occurred getting volume by ID : %s" , volumeID )
132+ return Volume {} , err
153133 }
154134
155- volume .ID = volume_v1 .ID
156- volume .Name = volume_v1 .Name
157- volume .Status = volume_v1 .Status
135+ volume := Volume {
136+ ID : volumeV1 .ID ,
137+ Name : volumeV1 .Name ,
138+ Status : volumeV1 .Status ,
139+ }
158140
159- if len (volume_v1 .Attachments ) > 0 && volume_v1 .Attachments [0 ]["server_id" ] != nil {
160- volume .AttachedServerId = volume_v1 .Attachments [0 ]["server_id" ].(string )
161- volume .AttachedDevice = volume_v1 .Attachments [0 ]["device" ].(string )
141+ if len (volumeV1 .Attachments ) > 0 && volumeV1 .Attachments [0 ]["server_id" ] != nil {
142+ volume .AttachedServerId = volumeV1 .Attachments [0 ]["server_id" ].(string )
143+ volume .AttachedDevice = volumeV1 .Attachments [0 ]["device" ].(string )
162144 }
163145
164146 return volume , nil
165147}
166148
167- func (volumes * VolumesV2 ) getVolume (diskName string ) (Volume , error ) {
168- var volume_v2 volumes_v2.Volume
169- var volume Volume
149+ func (volumes * VolumesV2 ) getVolume (volumeID string ) (Volume , error ) {
170150 startTime := time .Now ()
171- err := volumes_v2 .List (volumes .blockstorage , nil ).EachPage (func (page pagination.Page ) (bool , error ) {
172- vols , err := volumes_v2 .ExtractVolumes (page )
173- if err != nil {
174- glog .Errorf ("Failed to extract volumes: %v" , err )
175- return false , err
176- } else {
177- for _ , v := range vols {
178- glog .V (4 ).Infof ("%s %s %v" , v .ID , v .Name , v .Attachments )
179- if v .Name == diskName || strings .Contains (v .ID , diskName ) {
180- volume_v2 = v
181- return true , nil
182- }
183- }
184- }
185- // if it reached here then no disk with the given name was found.
186- errmsg := fmt .Sprintf ("Unable to find disk: %s" , diskName )
187- return false , errors .New (errmsg )
188- })
151+ volumeV2 , err := volumes_v2 .Get (volumes .blockstorage , volumeID ).Extract ()
189152 timeTaken := time .Since (startTime ).Seconds ()
190153 recordOpenstackOperationMetric ("get_v2_volume" , timeTaken , err )
191154 if err != nil {
192- glog .Errorf ("Error occurred getting volume: %s" , diskName )
193- return volume , err
155+ glog .Errorf ("Error occurred getting volume by ID : %s" , volumeID )
156+ return Volume {} , err
194157 }
195158
196- volume .ID = volume_v2 .ID
197- volume .Name = volume_v2 .Name
198- volume .Status = volume_v2 .Status
159+ volume := Volume {
160+ ID : volumeV2 .ID ,
161+ Name : volumeV2 .Name ,
162+ Status : volumeV2 .Status ,
163+ }
199164
200- if len (volume_v2 .Attachments ) > 0 {
201- volume .AttachedServerId = volume_v2 .Attachments [0 ].ServerID
202- volume .AttachedDevice = volume_v2 .Attachments [0 ].Device
165+ if len (volumeV2 .Attachments ) > 0 {
166+ volume .AttachedServerId = volumeV2 .Attachments [0 ].ServerID
167+ volume .AttachedDevice = volumeV2 .Attachments [0 ].Device
203168 }
204169
205170 return volume , nil
206171}
207172
208- func (volumes * VolumesV1 ) deleteVolume (volumeName string ) error {
173+ func (volumes * VolumesV1 ) deleteVolume (volumeID string ) error {
209174 startTime := time .Now ()
210- err := volumes_v1 .Delete (volumes .blockstorage , volumeName ).ExtractErr ()
175+ err := volumes_v1 .Delete (volumes .blockstorage , volumeID ).ExtractErr ()
211176 timeTaken := time .Since (startTime ).Seconds ()
212177 recordOpenstackOperationMetric ("delete_v1_volume" , timeTaken , err )
213178 if err != nil {
214- glog .Errorf ("Cannot delete volume %s: %v" , volumeName , err )
179+ glog .Errorf ("Cannot delete volume %s: %v" , volumeID , err )
215180 }
216181
217182 return err
218183}
219184
220- func (volumes * VolumesV2 ) deleteVolume (volumeName string ) error {
185+ func (volumes * VolumesV2 ) deleteVolume (volumeID string ) error {
221186 startTime := time .Now ()
222- err := volumes_v2 .Delete (volumes .blockstorage , volumeName ).ExtractErr ()
187+ err := volumes_v2 .Delete (volumes .blockstorage , volumeID ).ExtractErr ()
223188 timeTaken := time .Since (startTime ).Seconds ()
224189 recordOpenstackOperationMetric ("delete_v2_volume" , timeTaken , err )
225190 if err != nil {
226- glog .Errorf ("Cannot delete volume %s: %v" , volumeName , err )
191+ glog .Errorf ("Cannot delete volume %s: %v" , volumeID , err )
227192 }
228193
229194 return err
@@ -246,8 +211,8 @@ func (os *OpenStack) OperationPending(diskName string) (bool, string, error) {
246211}
247212
248213// Attaches given cinder volume to the compute running kubelet
249- func (os * OpenStack ) AttachDisk (instanceID string , diskName string ) (string , error ) {
250- volume , err := os .getVolume (diskName )
214+ func (os * OpenStack ) AttachDisk (instanceID , volumeID string ) (string , error ) {
215+ volume , err := os .getVolume (volumeID )
251216 if err != nil {
252217 return "" , err
253218 }
@@ -266,11 +231,11 @@ func (os *OpenStack) AttachDisk(instanceID string, diskName string) (string, err
266231
267232 if volume .AttachedServerId != "" {
268233 if instanceID == volume .AttachedServerId {
269- glog .V (4 ).Infof ("Disk: %q is already attached to compute: %q " , diskName , instanceID )
234+ glog .V (4 ).Infof ("Disk %s is already attached to instance %s " , volumeID , instanceID )
270235 return volume .ID , nil
271236 }
272- glog .V (2 ).Infof ("Disk %q is attached to a different compute (%q ), detaching" , diskName , volume .AttachedServerId )
273- err = os .DetachDisk (volume .AttachedServerId , diskName )
237+ glog .V (2 ).Infof ("Disk %s is attached to a different instance (%s ), detaching" , volumeID , volume .AttachedServerId )
238+ err = os .DetachDisk (volume .AttachedServerId , volumeID )
274239 if err != nil {
275240 return "" , err
276241 }
@@ -284,16 +249,16 @@ func (os *OpenStack) AttachDisk(instanceID string, diskName string) (string, err
284249 timeTaken := time .Since (startTime ).Seconds ()
285250 recordOpenstackOperationMetric ("attach_disk" , timeTaken , err )
286251 if err != nil {
287- glog .Errorf ("Failed to attach %s volume to %s compute: %v" , diskName , instanceID , err )
252+ glog .Errorf ("Failed to attach %s volume to %s compute: %v" , volumeID , instanceID , err )
288253 return "" , err
289254 }
290- glog .V (2 ).Infof ("Successfully attached %s volume to %s compute" , diskName , instanceID )
255+ glog .V (2 ).Infof ("Successfully attached %s volume to %s compute" , volumeID , instanceID )
291256 return volume .ID , nil
292257}
293258
294- // Detaches given cinder volume from the compute running kubelet
295- func (os * OpenStack ) DetachDisk (instanceID string , partialDiskId string ) error {
296- volume , err := os .getVolume (partialDiskId )
259+ // DetachDisk detaches given cinder volume from the compute running kubelet
260+ func (os * OpenStack ) DetachDisk (instanceID , volumeID string ) error {
261+ volume , err := os .getVolume (volumeID )
297262 if err != nil {
298263 return err
299264 }
@@ -330,26 +295,24 @@ func (os *OpenStack) DetachDisk(instanceID string, partialDiskId string) error {
330295 return nil
331296}
332297
333- // Takes a partial/full disk id or diskname
334- func (os * OpenStack ) getVolume (diskName string ) (Volume , error ) {
335-
298+ // Retrieves Volume by its ID.
299+ func (os * OpenStack ) getVolume (volumeID string ) (Volume , error ) {
336300 volumes , err := os .volumeService ("" )
337301 if err != nil || volumes == nil {
338302 glog .Errorf ("Unable to initialize cinder client for region: %s" , os .region )
339303 return Volume {}, err
340304 }
341-
342- return volumes .getVolume (diskName )
305+ return volumes .getVolume (volumeID )
343306}
344307
345308// Create a volume of given size (in GiB)
346309func (os * OpenStack ) CreateVolume (name string , size int , vtype , availability string , tags * map [string ]string ) (string , string , error ) {
347-
348310 volumes , err := os .volumeService ("" )
349311 if err != nil || volumes == nil {
350312 glog .Errorf ("Unable to initialize cinder client for region: %s" , os .region )
351313 return "" , "" , err
352314 }
315+
353316 opts := VolumeCreateOpts {
354317 Name : name ,
355318 Size : size ,
@@ -359,27 +322,28 @@ func (os *OpenStack) CreateVolume(name string, size int, vtype, availability str
359322 if tags != nil {
360323 opts .Metadata = * tags
361324 }
362- volumeId , volumeAZ , err := volumes .createVolume (opts )
325+
326+ volumeID , volumeAZ , err := volumes .createVolume (opts )
363327
364328 if err != nil {
365329 glog .Errorf ("Failed to create a %d GB volume: %v" , size , err )
366330 return "" , "" , err
367331 }
368332
369- glog .Infof ("Created volume %v in Availability Zone: %v" , volumeId , volumeAZ )
370- return volumeId , volumeAZ , nil
333+ glog .Infof ("Created volume %v in Availability Zone: %v" , volumeID , volumeAZ )
334+ return volumeID , volumeAZ , nil
371335}
372336
373337// GetDevicePath returns the path of an attached block storage volume, specified by its id.
374- func (os * OpenStack ) GetDevicePath (diskId string ) string {
338+ func (os * OpenStack ) GetDevicePath (volumeID string ) string {
375339 // Build a list of candidate device paths
376340 candidateDeviceNodes := []string {
377341 // KVM
378- fmt .Sprintf ("virtio-%s" , diskId [:20 ]),
342+ fmt .Sprintf ("virtio-%s" , volumeID [:20 ]),
379343 // KVM virtio-scsi
380- fmt .Sprintf ("scsi-0QEMU_QEMU_HARDDISK_%s" , diskId [:20 ]),
344+ fmt .Sprintf ("scsi-0QEMU_QEMU_HARDDISK_%s" , volumeID [:20 ]),
381345 // ESXi
382- fmt .Sprintf ("wwn-0x%s" , strings .Replace (diskId , "-" , "" , - 1 )),
346+ fmt .Sprintf ("wwn-0x%s" , strings .Replace (volumeID , "-" , "" , - 1 )),
383347 }
384348
385349 files , _ := ioutil .ReadDir ("/dev/disk/by-id/" )
@@ -393,17 +357,17 @@ func (os *OpenStack) GetDevicePath(diskId string) string {
393357 }
394358 }
395359
396- glog .Warningf ("Failed to find device for the diskid : %q\n " , diskId )
360+ glog .Warningf ("Failed to find device for the volumeID : %q\n " , volumeID )
397361 return ""
398362}
399363
400- func (os * OpenStack ) DeleteVolume (volumeName string ) error {
401- used , err := os .diskIsUsed (volumeName )
364+ func (os * OpenStack ) DeleteVolume (volumeID string ) error {
365+ used , err := os .diskIsUsed (volumeID )
402366 if err != nil {
403367 return err
404368 }
405369 if used {
406- msg := fmt .Sprintf ("Cannot delete the volume %q, it's still attached to a node" , volumeName )
370+ msg := fmt .Sprintf ("Cannot delete the volume %q, it's still attached to a node" , volumeID )
407371 return k8s_volume .NewDeletedVolumeInUseError (msg )
408372 }
409373
@@ -413,19 +377,19 @@ func (os *OpenStack) DeleteVolume(volumeName string) error {
413377 return err
414378 }
415379
416- err = volumes .deleteVolume (volumeName )
380+ err = volumes .deleteVolume (volumeID )
417381 if err != nil {
418- glog .Errorf ("Cannot delete volume %s: %v" , volumeName , err )
382+ glog .Errorf ("Cannot delete volume %s: %v" , volumeID , err )
419383 }
420384 return nil
421385
422386}
423387
424388// Get device path of attached volume to the compute running kubelet, as known by cinder
425- func (os * OpenStack ) GetAttachmentDiskPath (instanceID string , diskName string ) (string , error ) {
389+ func (os * OpenStack ) GetAttachmentDiskPath (instanceID , volumeID string ) (string , error ) {
426390 // See issue #33128 - Cinder does not always tell you the right device path, as such
427391 // we must only use this value as a last resort.
428- volume , err := os .getVolume (diskName )
392+ volume , err := os .getVolume (volumeID )
429393 if err != nil {
430394 return "" , err
431395 }
@@ -440,47 +404,41 @@ func (os *OpenStack) GetAttachmentDiskPath(instanceID string, diskName string) (
440404 // see http://developer.openstack.org/api-ref-blockstorage-v1.html
441405 return volume .AttachedDevice , nil
442406 } else {
443- errMsg := fmt .Sprintf ("Disk %q is attached to a different compute: %q, should be detached before proceeding" , diskName , volume .AttachedServerId )
407+ errMsg := fmt .Sprintf ("Disk %q is attached to a different compute: %q, should be detached before proceeding" , volumeID , volume .AttachedServerId )
444408 glog .Errorf (errMsg )
445409 return "" , errors .New (errMsg )
446410 }
447411 }
448- return "" , fmt .Errorf ("volume %s has not ServerId." , diskName )
412+ return "" , fmt .Errorf ("volume %s has no ServerId." , volumeID )
449413}
450414
451415// query if a volume is attached to a compute instance
452- func (os * OpenStack ) DiskIsAttached (diskName , instanceID string ) (bool , error ) {
453- volume , err := os .getVolume (diskName )
416+ func (os * OpenStack ) DiskIsAttached (instanceID , volumeID string ) (bool , error ) {
417+ volume , err := os .getVolume (volumeID )
454418 if err != nil {
455419 return false , err
456420 }
457421
458- if instanceID == volume .AttachedServerId {
459- return true , nil
460- }
461- return false , nil
422+ return instanceID == volume .AttachedServerId , nil
462423}
463424
464425// query if a list of volumes are attached to a compute instance
465- func (os * OpenStack ) DisksAreAttached (diskNames [] string , instanceID string ) (map [string ]bool , error ) {
426+ func (os * OpenStack ) DisksAreAttached (instanceID string , volumeIDs [] string ) (map [string ]bool , error ) {
466427 attached := make (map [string ]bool )
467- for _ , diskName := range diskNames {
468- is_attached , _ := os .DiskIsAttached (diskName , instanceID )
469- attached [diskName ] = is_attached
428+ for _ , volumeID := range volumeIDs {
429+ isAttached , _ := os .DiskIsAttached (instanceID , volumeID )
430+ attached [volumeID ] = isAttached
470431 }
471432 return attached , nil
472433}
473434
474435// diskIsUsed returns true a disk is attached to any node.
475- func (os * OpenStack ) diskIsUsed (diskName string ) (bool , error ) {
476- volume , err := os .getVolume (diskName )
436+ func (os * OpenStack ) diskIsUsed (volumeID string ) (bool , error ) {
437+ volume , err := os .getVolume (volumeID )
477438 if err != nil {
478439 return false , err
479440 }
480- if volume .AttachedServerId != "" {
481- return true , nil
482- }
483- return false , nil
441+ return volume .AttachedServerId != "" , nil
484442}
485443
486444// query if we should trust the cinder provide deviceName, See issue #33128
0 commit comments