github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/oracle/storage.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package oracle 5 6 import ( 7 "github.com/juju/errors" 8 oci "github.com/juju/go-oracle-cloud/api" 9 10 "github.com/juju/juju/provider/oracle/common" 11 "github.com/juju/juju/storage" 12 ) 13 14 const ( 15 oracleStorageProviderType = storage.ProviderType("oracle") 16 17 // maxVolumeSizeInGB represents the maximum size in GiB for 18 // a single volume. For more information please see: 19 // https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-volume--post.html#request 20 maxVolumeSizeInGB = 2000 21 // minVolumeSizeInGB represents the minimum size in GiB for 22 // a single volume. For more information please see: 23 // https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-volume--post.html#request 24 minVolumeSizeInGB = 1 25 // maxDevices is the maximum number of volumes that can be attached to a single instance 26 // for more information, please see: 27 // https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-attachment--post.html#request 28 maxDevices = 10 29 // blockDevicePrefix is the default block storage prefix for an oracle 30 // cloud storage volume, as seen by GNU/Linux guests. For more information, please see: 31 // https://docs.oracle.com/cloud/latest/stcomputecs/STCSA/op-storage-attachment--post.html#request 32 blockDevicePrefix = "xvd" 33 34 // blockDeviceStartIndex is the base from which we start incrementing block device names 35 // start from 'a'. xvda will always be the root disk. 36 blockDeviceStartIndex = 'a' 37 ) 38 39 // storageProvider implements the storage.Provider interface 40 type storageProvider struct { 41 env *OracleEnviron 42 api StorageAPI 43 } 44 45 var _ storage.Provider = (*storageProvider)(nil) 46 47 // StorageAPI defines the storage API in the oracle cloud provider 48 // this enables the provider to talk with the storage API and make 49 // storage specific operations 50 type StorageAPI interface { 51 common.StorageVolumeAPI 52 common.StorageAttachmentAPI 53 common.Composer 54 } 55 56 func mibToGib(m uint64) uint64 { 57 return (m + 1023) / 1024 58 } 59 60 func (o *OracleEnviron) canAccessStorageAPI() (bool, error) { 61 // Check if we actually have access to the storage APIs. 62 _, err := o.client.AllStorageVolumes(nil) 63 if err != nil { 64 // The API usually returns a 405 error if we don't have access to that bit of the cloud 65 // this is something that happens for trial accounts. 66 if oci.IsMethodNotAllowed(err) { 67 return false, nil 68 } 69 return false, errors.Trace(err) 70 } 71 return true, nil 72 } 73 74 // StorageProviderTypes implements storage.ProviderRegistry. 75 func (o *OracleEnviron) StorageProviderTypes() ([]storage.ProviderType, error) { 76 if access, err := o.canAccessStorageAPI(); access { 77 return []storage.ProviderType{oracleStorageProviderType}, nil 78 } else { 79 return nil, errors.Trace(err) 80 } 81 } 82 83 // StorageProvider implements storage.ProviderRegistry. 84 func (o *OracleEnviron) StorageProvider(t storage.ProviderType) (storage.Provider, error) { 85 access, err := o.canAccessStorageAPI() 86 if err != nil { 87 return nil, errors.Trace(err) 88 } 89 if access && t == oracleStorageProviderType { 90 return &storageProvider{ 91 env: o, 92 api: o.client, 93 }, nil 94 } 95 96 return nil, errors.NotFoundf("storage provider %q", t) 97 }