From: Dies Koper <[email protected]>
---
server/lib/deltacloud/drivers/fgcp/fgcp_client.rb | 44 +++++++++++++++++++++++
server/lib/deltacloud/drivers/fgcp/fgcp_driver.rb | 38 +++++++++++++++++++-
server/views/storage_volumes/show.html.haml | 2 +-
3 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
index 4d569da..fed3b70 100644
--- a/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
+++ b/server/lib/deltacloud/drivers/fgcp/fgcp_client.rb
@@ -274,6 +274,44 @@ eoidxml
request('DestroyVDiskBackup', {'vsysId' => vsys_id, 'backupId' =>
backup_id})
end
+ def get_vdisk_backup_copy_key(vsys_id, backup_id)
+ @version = '2012-07-20'
+ request('GetVDiskBackupCopyKey', {'vsysId' => vsys_id, 'backupId' =>
backup_id})
+ end
+
+ def set_vdisk_backup_copy_key(vsys_id, backup_id, contracts)
+ @version = '2012-07-20'
+ contracts_xml = <<-"eoctxml"
+<?xml version="1.0" encoding ="UTF-8"?>
+<Request>
+ <contracts>
+ <contract>
+#{contracts.collect { |c| " <number>#{c}</number>" }.join("\n")}
+ </contract>
+ </contracts>
+</Request>
+eoctxml
+ request('SetVDiskBackupCopyKey',
+ {
+ 'vsysId' => vsys_id,
+ 'backupId' => backup_id
+ },
+ contracts_xml,
+ 'contractsXMLFilePath'
+ )
+ end
+
+ def external_restore_vdisk(src_vsys_id, src_backup_id, dst_vsys_id,
dst_vdisk_id, key)
+ @version = '2012-07-20'
+ request('ExternalRestoreVDisk', {
+ 'srcVsysId' => src_vsys_id,
+ 'srcBackupId' => src_backup_id,
+ 'dstVsysId' => dst_vsys_id,
+ 'dstVdiskId' => dst_vdisk_id,
+ 'key' => key}
+ )
+ end
+
def list_public_ips(vsys_id=nil)
if vsys_id.nil?
request('ListPublicIP')
@@ -321,6 +359,12 @@ eoidxml
$1
end
+ #extract contract id from vserverId, efmId or networkId
+ def extract_contract_id(id)
+ /^(\w+)-\w+\b.*/ =~ id
+ $1
+ end
+
private
# params hash is of the form :vserverId => 'ABC123', etc.
diff --git a/server/lib/deltacloud/drivers/fgcp/fgcp_driver.rb
b/server/lib/deltacloud/drivers/fgcp/fgcp_driver.rb
index 71b53bd..8d29a8e 100644
--- a/server/lib/deltacloud/drivers/fgcp/fgcp_driver.rb
+++ b/server/lib/deltacloud/drivers/fgcp/fgcp_driver.rb
@@ -556,7 +556,43 @@ class FgcpDriver < Deltacloud::BaseDriver
opts[:realm_id] = xml[0]['vsys'][0]['vsysId'][0] if xml
end
- vdisk_id = client.create_vdisk(opts[:realm_id], opts[:name],
opts[:capacity])['vdiskId'][0]
+ if not opts[:snapshot_id]
+ vdisk_id = client.create_vdisk(opts[:realm_id], opts[:name],
opts[:capacity])['vdiskId'][0]
+ else
+ orig_vdisk_id, backup_id = split_snapshot_id(opts[:snapshot_id])
+ orig_vsys_id = client.extract_vsys_id(orig_vdisk_id)
+ # check snapshot size
+ size =
client.get_vdisk_attributes(orig_vdisk_id)['vdisk'][0]['size'][0]
+ #set and retrieve key
+ contract_id = client.extract_contract_id(opts[:realm_id])
+ client.set_vdisk_backup_copy_key(orig_vsys_id, backup_id,
[contract_id])
+ key = client.get_vdisk_backup_copy_key(opts[:realm_id],
backup_id)['keyInfo'][0]['key'][0]
+ # create vdisk with same size as snapshot
+ size =
client.get_vdisk_attributes(orig_vdisk_id)['vdisk'][0]['size'][0]
+ vdisk_id = client.create_vdisk(opts[:realm_id], opts[:name],
size)['vdiskId'][0]
+ # try a restore straight away. It will likely fail (as the vdisk
creation has not
+ # completed yet), but at least the parameters will be validated
straight away.
+ begin
+ client.external_restore_vdisk(orig_vsys_id, backup_id,
opts[:realm_id], vdisk_id, key)
+ rescue Exception => ex
+ # ignore expected error that destination vdisk is not ready yet
+ raise unless ex.message =~ /ILLEGAL_STATE_DST.*/
+ end
+ #wait until creation completes in a separate thread
+ Thread.new {
+ attempts = 0
+ begin
+ sleep 10
+ # this fails if the destination vdisk is still being deployed
+ client.external_restore_vdisk(orig_vsys_id, backup_id,
opts[:realm_id], vdisk_id, key)
+ rescue Exception => ex
+ raise unless attempts < 30 and ex.message =~ /ILLEGAL_STATE_DST.*/
+ # Deployment takes a few minutes, so keep trying for a while
+ attempts += 1
+ retry
+ end
+ }
+ end
StorageVolume.new(
:id => vdisk_id,
diff --git a/server/views/storage_volumes/show.html.haml
b/server/views/storage_volumes/show.html.haml
index eddf5a9..725bbdf 100644
--- a/server/views/storage_volumes/show.html.haml
+++ b/server/views/storage_volumes/show.html.haml
@@ -24,7 +24,7 @@
- if @storage_volume.instance_id
%a{ :href => instance_url( @storage_volume.instance_id)}
= @storage_volume.instance_id
- - elsif @storage_volume.state == "AVAILABLE"
+ - elsif @storage_volume.state and @storage_volume.state != "IN-USE"
%p{ :'data-role' => 'fieldcontain'}= 'none (detached)'
-else
%p{ :'data-role' => 'fieldcontain'}= 'unknown'
--
1.8.0.msysgit.0