@@ -59,11 +59,12 @@ type BlobDiskController struct {
59
59
accounts map [string ]* storageAccountState
60
60
}
61
61
62
- var defaultContainerName = ""
63
- var storageAccountNamePrefix = ""
64
- var storageAccountNameMatch = ""
65
-
66
- var accountsLock = & sync.Mutex {}
62
+ var (
63
+ defaultContainerName = ""
64
+ storageAccountNamePrefix = ""
65
+ storageAccountNameMatch = ""
66
+ accountsLock = & sync.Mutex {}
67
+ )
67
68
68
69
func newBlobDiskController (common * controllerCommon ) (* BlobDiskController , error ) {
69
70
c := BlobDiskController {common : common }
@@ -80,52 +81,49 @@ func newBlobDiskController(common *controllerCommon) (*BlobDiskController, error
80
81
return & c , nil
81
82
}
82
83
83
- // CreateVolume creates a VHD blob in a given storage account, will create the given storage account if it does not exist in current resource group
84
- func (c * BlobDiskController ) CreateVolume (name , storageAccount string , storageAccountType storage.SkuName , location string , requestGB int ) (string , string , int , error ) {
85
- key , err := c .common .cloud .getStorageAccesskey (storageAccount )
86
- if err != nil {
87
- glog .V (2 ).Infof ("azureDisk - no key found for storage account %s in resource group %s, begin to create a new storage account" , storageAccount , c .common .resourceGroup )
88
-
89
- cp := storage.AccountCreateParameters {
90
- Sku : & storage.Sku {Name : storageAccountType },
91
- Tags : & map [string ]* string {"created-by" : to .StringPtr ("azure-dd" )},
92
- Location : & location }
93
- cancel := make (chan struct {})
94
-
95
- _ , errchan := c .common .cloud .StorageAccountClient .Create (c .common .resourceGroup , storageAccount , cp , cancel )
96
- err = <- errchan
97
- if err != nil {
98
- return "" , "" , 0 , fmt .Errorf (fmt .Sprintf ("Create Storage Account %s, error: %s" , storageAccount , err ))
99
- }
100
-
101
- key , err = c .common .cloud .getStorageAccesskey (storageAccount )
84
+ // CreateVolume creates a VHD blob in a storage account that has storageType and location using the given storage account.
85
+ // If no storage account is given, search all the storage accounts associated with the resource group and pick one that
86
+ // fits storage type and location.
87
+ func (c * BlobDiskController ) CreateVolume (name , storageAccount , storageAccountType , location string , requestGB int ) (string , string , int , error ) {
88
+ var err error
89
+ accounts := []accountWithLocation {}
90
+ if len (storageAccount ) > 0 {
91
+ accounts = append (accounts , accountWithLocation {Name : storageAccount })
92
+ } else {
93
+ // find a storage account
94
+ accounts , err = c .common .cloud .getStorageAccounts ()
102
95
if err != nil {
103
- return "" , "" , 0 , fmt .Errorf ("no key found for storage account %s even after creating a new storage account" , storageAccount )
96
+ // TODO: create a storage account and container
97
+ return "" , "" , 0 , err
104
98
}
105
-
106
- glog .Errorf ("no key found for storage account %s in resource group %s" , storageAccount , c .common .resourceGroup )
107
- return "" , "" , 0 , err
108
99
}
100
+ for _ , account := range accounts {
101
+ glog .V (4 ).Infof ("account %s type %s location %s" , account .Name , account .StorageType , account .Location )
102
+ if (storageAccountType == "" || account .StorageType == storageAccountType ) && (location == "" || account .Location == location ) || len (storageAccount ) > 0 {
103
+ // find the access key with this account
104
+ key , err := c .common .cloud .getStorageAccesskey (account .Name )
105
+ if err != nil {
106
+ glog .V (2 ).Infof ("no key found for storage account %s" , account .Name )
107
+ continue
108
+ }
109
109
110
- client , err := azstorage .NewBasicClientOnSovereignCloud (storageAccount , key , c .common .cloud .Environment )
111
- if err != nil {
112
- return "" , "" , 0 , err
113
- }
114
- blobClient := client .GetBlobService ()
110
+ client , err := azstorage .NewBasicClientOnSovereignCloud (account . Name , key , c .common .cloud .Environment )
111
+ if err != nil {
112
+ return "" , "" , 0 , err
113
+ }
114
+ blobClient := client .GetBlobService ()
115
115
116
- container := blobClient . GetContainerReference ( vhdContainerName )
117
- _ , err = container . CreateIfNotExists ( & azstorage. CreateContainerOptions { Access : azstorage . ContainerAccessTypePrivate } )
118
- if err != nil {
119
- return "" , "" , 0 , err
120
- }
116
+ // create a page blob in this account's vhd container
117
+ diskName , diskURI , err := c . createVHDBlobDisk ( blobClient , account . Name , name , vhdContainerName , int64 ( requestGB ) )
118
+ if err != nil {
119
+ return "" , "" , 0 , err
120
+ }
121
121
122
- diskName , diskURI , err := c . createVHDBlobDisk ( blobClient , storageAccount , name , vhdContainerName , int64 ( requestGB ) )
123
- if err != nil {
124
- return "" , "" , 0 , err
122
+ glog . V ( 4 ). Infof ( "azureDisk - created vhd blob uri: %s" , diskURI )
123
+ return diskName , diskURI , requestGB , err
124
+ }
125
125
}
126
-
127
- glog .V (4 ).Infof ("azureDisk - created vhd blob uri: %s" , diskURI )
128
- return diskName , diskURI , requestGB , err
126
+ return "" , "" , 0 , fmt .Errorf ("failed to find a matching storage account" )
129
127
}
130
128
131
129
// DeleteVolume deletes a VHD blob
@@ -173,11 +171,6 @@ func (c *BlobDiskController) getBlobNameAndAccountFromURI(diskURI string) (strin
173
171
174
172
func (c * BlobDiskController ) createVHDBlobDisk (blobClient azstorage.BlobStorageClient , accountName , vhdName , containerName string , sizeGB int64 ) (string , string , error ) {
175
173
container := blobClient .GetContainerReference (containerName )
176
- _ , err := container .CreateIfNotExists (& azstorage.CreateContainerOptions {Access : azstorage .ContainerAccessTypePrivate })
177
- if err != nil {
178
- return "" , "" , err
179
- }
180
-
181
174
size := 1024 * 1024 * 1024 * sizeGB
182
175
vhdSize := size + vhd .VHD_HEADER_SIZE /* header size */
183
176
// Blob name in URL must end with '.vhd' extension.
@@ -190,7 +183,17 @@ func (c *BlobDiskController) createVHDBlobDisk(blobClient azstorage.BlobStorageC
190
183
blob := container .GetBlobReference (vhdName )
191
184
blob .Properties .ContentLength = vhdSize
192
185
blob .Metadata = tags
193
- err = blob .PutPageBlob (nil )
186
+ err := blob .PutPageBlob (nil )
187
+ if err != nil {
188
+ // if container doesn't exist, create one and retry PutPageBlob
189
+ detail := err .Error ()
190
+ if strings .Contains (detail , errContainerNotFound ) {
191
+ err = container .Create (& azstorage.CreateContainerOptions {Access : azstorage .ContainerAccessTypePrivate })
192
+ if err == nil {
193
+ err = blob .PutPageBlob (nil )
194
+ }
195
+ }
196
+ }
194
197
if err != nil {
195
198
return "" , "" , fmt .Errorf ("failed to put page blob %s in container %s: %v" , vhdName , containerName , err )
196
199
}
@@ -236,24 +239,12 @@ func (c *BlobDiskController) deleteVhdBlob(accountName, accountKey, blobName str
236
239
}
237
240
238
241
//CreateBlobDisk : create a blob disk in a node
239
- func (c * BlobDiskController ) CreateBlobDisk (dataDiskName string , storageAccountType storage.SkuName , sizeGB int , forceStandAlone bool ) (string , error ) {
240
- glog .V (4 ).Infof ("azureDisk - creating blob data disk named:%s on StorageAccountType:%s StandAlone:%v " , dataDiskName , storageAccountType , forceStandAlone )
242
+ func (c * BlobDiskController ) CreateBlobDisk (dataDiskName string , storageAccountType storage.SkuName , sizeGB int ) (string , error ) {
243
+ glog .V (4 ).Infof ("azureDisk - creating blob data disk named:%s on StorageAccountType:%s" , dataDiskName , storageAccountType )
241
244
242
- var storageAccountName = ""
243
- var err error
244
-
245
- if forceStandAlone {
246
- // we have to wait until the storage account is is created
247
- storageAccountName = "p" + MakeCRC32 (c .common .subscriptionID + c .common .resourceGroup + dataDiskName )
248
- err = c .createStorageAccount (storageAccountName , storageAccountType , c .common .location , false )
249
- if err != nil {
250
- return "" , err
251
- }
252
- } else {
253
- storageAccountName , err = c .findSANameForDisk (storageAccountType )
254
- if err != nil {
255
- return "" , err
256
- }
245
+ storageAccountName , err := c .findSANameForDisk (storageAccountType )
246
+ if err != nil {
247
+ return "" , err
257
248
}
258
249
259
250
blobClient , err := c .getBlobSvcClient (storageAccountName )
@@ -266,15 +257,13 @@ func (c *BlobDiskController) CreateBlobDisk(dataDiskName string, storageAccountT
266
257
return "" , err
267
258
}
268
259
269
- if ! forceStandAlone {
270
- atomic .AddInt32 (& c .accounts [storageAccountName ].diskCount , 1 )
271
- }
260
+ atomic .AddInt32 (& c .accounts [storageAccountName ].diskCount , 1 )
272
261
273
262
return diskURI , nil
274
263
}
275
264
276
265
//DeleteBlobDisk : delete a blob disk from a node
277
- func (c * BlobDiskController ) DeleteBlobDisk (diskURI string , wasForced bool ) error {
266
+ func (c * BlobDiskController ) DeleteBlobDisk (diskURI string ) error {
278
267
storageAccountName , vhdName , err := diskNameandSANameFromURI (diskURI )
279
268
if err != nil {
280
269
return err
@@ -286,11 +275,6 @@ func (c *BlobDiskController) DeleteBlobDisk(diskURI string, wasForced bool) erro
286
275
glog .V (4 ).Infof ("azureDisk - deleting volume %s" , diskURI )
287
276
return c .DeleteVolume (diskURI )
288
277
}
289
- // if forced (as in one disk = one storage account)
290
- // delete the account completely
291
- if wasForced {
292
- return c .deleteStorageAccount (storageAccountName )
293
- }
294
278
295
279
blobSvc , err := c .getBlobSvcClient (storageAccountName )
296
280
if err != nil {
0 commit comments