cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bhais...@apache.org
Subject [19/39] git commit: updated refs/heads/master to 3e28747
Date Thu, 02 Apr 2015 18:23:00 GMT
Refactoring AttachIsoCommand, AttachVolumeCommand and UpgradeSnapshotCommand to cope with new
design
  - Basic tests added


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ea374b6a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ea374b6a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ea374b6a

Branch: refs/heads/master
Commit: ea374b6a2ffba8c5ea2222cf1cffce10dbbdff92
Parents: 6c77595
Author: wilderrodrigues <wrodrigues@schubergphilis.com>
Authored: Tue Mar 24 15:26:03 2015 +0100
Committer: wilderrodrigues <wrodrigues@schubergphilis.com>
Committed: Tue Mar 31 10:38:28 2015 +0200

----------------------------------------------------------------------
 .../xenserver/resource/CitrixResourceBase.java  |  22 +--
 .../wrapper/CitrixAttachIsoCommandWrapper.java  | 134 +++++++++++++++++
 .../CitrixAttachVolumeCommandWrapper.java       | 144 +++++++++++++++++++
 .../resource/wrapper/CitrixRequestWrapper.java  |   6 +
 .../CitrixUpgradeSnapshotCommandWrapper.java    |  64 +++++++++
 .../wrapper/CitrixRequestWrapperTest.java       |  70 ++++++++-
 6 files changed, 424 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
index ec67ee8..3c55a88 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java
@@ -441,14 +441,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
         if (cmd instanceof NetworkElementCommand) {
             return _vrResource.executeRequest((NetworkElementCommand)cmd);
-        } else if (clazz == CreateStoragePoolCommand.class) {
-            return execute((CreateStoragePoolCommand)cmd);
-        } else if (clazz == ModifyStoragePoolCommand.class) {
-            return execute((ModifyStoragePoolCommand)cmd);
-        } else if (clazz == DeleteStoragePoolCommand.class) {
-            return execute((DeleteStoragePoolCommand) cmd);
-        }else if (clazz == ResizeVolumeCommand.class) {
-            return execute((ResizeVolumeCommand) cmd);
         } else if (clazz == AttachVolumeCommand.class) {
             return execute((AttachVolumeCommand)cmd);
         } else if (clazz == AttachIsoCommand.class) {
@@ -2679,7 +2671,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         }
     }
 
-    String upgradeSnapshot(final Connection conn, final String templatePath, final String
snapshotPath) {
+    public String upgradeSnapshot(final Connection conn, final String templatePath, final
String snapshotPath) {
         final String results = callHostPluginAsync(conn, "vmopspremium", "upgrade_snapshot",
2 * 60 * 60, "templatePath", templatePath, "snapshotPath", snapshotPath);
 
         if (results == null || results.isEmpty()) {
@@ -3620,7 +3612,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         return connect(conn, vmname, ipAddress, 3922);
     }
 
-    protected boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId)
{
+    public boolean isDeviceUsed(final Connection conn, final VM vm, final Long deviceId)
{
         // Figure out the disk number to attach the VM to
 
         String msg = null;
@@ -3640,7 +3632,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         throw new CloudRuntimeException("When check deviceId " + msg);
     }
 
-    protected String getUnusedDeviceNum(final Connection conn, final VM vm) {
+    public String getUnusedDeviceNum(final Connection conn, final VM vm) {
         // Figure out the disk number to attach the VM to
         try {
             final Set<String> allowedVBDDevices = vm.getAllowedVBDDevices(conn);
@@ -5841,7 +5833,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         return getVDIbyUuid(conn, uuid, true);
     }
 
-    protected VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound)
{
+    public VDI getVDIbyUuid(final Connection conn, final String uuid, final boolean throwExceptionIfNotFound)
{
         try {
             return VDI.getByUuid(conn, uuid);
         } catch (final Exception e) {
@@ -6099,7 +6091,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         return new Answer(cmd, true, "Success");
     }
 
-    protected VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize)
throws Types.XenAPIException, XmlRpcException {
+    public VDI createVdi(final SR sr, final String vdiNameLabel, final Long volumeSize) throws
Types.XenAPIException, XmlRpcException {
         final Connection conn = getConnection();
 
         final VDI.Record vdir = new VDI.Record();
@@ -6121,7 +6113,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         return VDI.create(conn, vdir);
     }
 
-    protected void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception
{
+    public void handleSrAndVdiDetach(final String iqn, final Connection conn) throws Exception
{
         final SR sr = getStorageRepository(conn, iqn);
 
         removeSR(conn, sr);
@@ -6685,7 +6677,7 @@ public abstract class CitrixResourceBase implements ServerResource,
HypervisorRe
         return vms.iterator().next();
     }
 
-    protected VDI getIsoVDIByURL(final Connection conn, final String vmName, final String
isoURL) {
+    public VDI getIsoVDIByURL(final Connection conn, final String vmName, final String isoURL)
{
         SR isoSR = null;
         String mountpoint = null;
         if (isoURL.startsWith("xs-tools")) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java
new file mode 100644
index 0000000..cc444c5
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachIsoCommandWrapper.java
@@ -0,0 +1,134 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.hypervisor.xenserver.resource.wrapper;
+
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.resource.CommandWrapper;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VM;
+
+public final class CitrixAttachIsoCommandWrapper extends CommandWrapper<AttachIsoCommand,
Answer, CitrixResourceBase> {
+
+    private static final Logger s_logger = Logger.getLogger(CitrixAttachIsoCommandWrapper.class);
+
+    @Override
+    public Answer execute(final AttachIsoCommand command, final CitrixResourceBase citrixResourceBase)
{
+        final Connection conn = citrixResourceBase.getConnection();
+        final boolean attach = command.isAttach();
+        final String vmName = command.getVmName();
+        final String isoURL = command.getIsoPath();
+
+        String errorMsg;
+        if (attach) {
+            errorMsg = "Failed to attach ISO";
+        } else {
+            errorMsg = "Failed to detach ISO";
+        }
+        try {
+            if (attach) {
+                VBD isoVBD = null;
+
+                // Find the VM
+                final VM vm = citrixResourceBase.getVM(conn, vmName);
+
+                // Find the ISO VDI
+                final VDI isoVDI = citrixResourceBase.getIsoVDIByURL(conn, vmName, isoURL);
+
+                // Find the VM's CD-ROM VBD
+                final Set<VBD> vbds = vm.getVBDs(conn);
+                for (final VBD vbd : vbds) {
+                    final String userDevice = vbd.getUserdevice(conn);
+                    final Types.VbdType type = vbd.getType(conn);
+
+                    if (userDevice.equals("3") && type == Types.VbdType.CD) {
+                        isoVBD = vbd;
+                        break;
+                    }
+                }
+
+                if (isoVBD == null) {
+                    throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: "
+ vmName);
+                } else {
+                    // If an ISO is already inserted, eject it
+                    if (isoVBD.getEmpty(conn) == false) {
+                        isoVBD.eject(conn);
+                    }
+
+                    // Insert the new ISO
+                    isoVBD.insert(conn, isoVDI);
+                }
+
+                return new Answer(command);
+            } else {
+                // Find the VM
+                final VM vm = citrixResourceBase.getVM(conn, vmName);
+                final String vmUUID = vm.getUuid(conn);
+
+                // Find the ISO VDI
+                final VDI isoVDI = citrixResourceBase.getIsoVDIByURL(conn, vmName, isoURL);
+
+                final SR sr = isoVDI.getSR(conn);
+
+                // Look up all VBDs for this VDI
+                final Set<VBD> vbds = isoVDI.getVBDs(conn);
+
+                // Iterate through VBDs, and if the VBD belongs the VM, eject
+                // the ISO from it
+                for (final VBD vbd : vbds) {
+                    final VM vbdVM = vbd.getVM(conn);
+                    final String vbdVmUUID = vbdVM.getUuid(conn);
+
+                    if (vbdVmUUID.equals(vmUUID)) {
+                        // If an ISO is already inserted, eject it
+                        if (!vbd.getEmpty(conn)) {
+                            vbd.eject(conn);
+                        }
+
+                        break;
+                    }
+                }
+
+                if (!sr.getNameLabel(conn).startsWith("XenServer Tools")) {
+                    citrixResourceBase.removeSR(conn, sr);
+                }
+
+                return new Answer(command);
+            }
+        } catch (final XenAPIException e) {
+            s_logger.warn(errorMsg + ": " + e.toString(), e);
+            return new Answer(command, false, e.toString());
+        } catch (final Exception e) {
+            s_logger.warn(errorMsg + ": " + e.toString(), e);
+            return new Answer(command, false, e.getMessage());
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java
new file mode 100644
index 0000000..01fd874
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixAttachVolumeCommandWrapper.java
@@ -0,0 +1,144 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.hypervisor.xenserver.resource.wrapper;
+
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.resource.CommandWrapper;
+import com.xensource.xenapi.Connection;
+import com.xensource.xenapi.SR;
+import com.xensource.xenapi.Types;
+import com.xensource.xenapi.Types.XenAPIException;
+import com.xensource.xenapi.VBD;
+import com.xensource.xenapi.VDI;
+import com.xensource.xenapi.VM;
+
+public final class CitrixAttachVolumeCommandWrapper extends CommandWrapper<AttachVolumeCommand,
Answer, CitrixResourceBase> {
+
+    private static final Logger s_logger = Logger.getLogger(CitrixAttachVolumeCommandWrapper.class);
+
+    @Override
+    public Answer execute(final AttachVolumeCommand command, final CitrixResourceBase citrixResourceBase)
{
+        final Connection conn = citrixResourceBase.getConnection();
+        final boolean attach = command.getAttach();
+        final String vmName = command.getVmName();
+        final String vdiNameLabel = vmName + "-DATA";
+        final Long deviceId = command.getDeviceId();
+
+        String errorMsg;
+        if (attach) {
+            errorMsg = "Failed to attach volume";
+        } else {
+            errorMsg = "Failed to detach volume";
+        }
+
+        try {
+            VDI vdi = null;
+
+            if (command.getAttach() && command.isManaged()) {
+                final SR sr = citrixResourceBase.getIscsiSR(conn, command.get_iScsiName(),
command.getStorageHost(), command.get_iScsiName(), command.getChapInitiatorUsername(),
+                        command.getChapInitiatorPassword(), true);
+
+                vdi = citrixResourceBase.getVDIbyUuid(conn, command.getVolumePath(), false);
+
+                if (vdi == null) {
+                    vdi = citrixResourceBase.createVdi(sr, vdiNameLabel, command.getVolumeSize());
+                }
+            } else {
+                vdi = citrixResourceBase.getVDIbyUuid(conn, command.getVolumePath());
+            }
+
+            // Look up the VM
+            final VM vm = citrixResourceBase.getVM(conn, vmName);
+            if (attach) {
+                // Figure out the disk number to attach the VM to
+                String diskNumber = null;
+                if (deviceId != null) {
+                    if (deviceId.longValue() == 3) {
+                        final String msg = "Device 3 is reserved for CD-ROM, choose other
device";
+                        return new AttachVolumeAnswer(command, msg);
+                    }
+                    if (citrixResourceBase.isDeviceUsed(conn, vm, deviceId)) {
+                        final String msg = "Device " + deviceId + " is used in VM " + vmName;
+                        return new AttachVolumeAnswer(command, msg);
+                    }
+                    diskNumber = deviceId.toString();
+                } else {
+                    diskNumber = citrixResourceBase.getUnusedDeviceNum(conn, vm);
+                }
+                // Create a new VBD
+                final VBD.Record vbdr = new VBD.Record();
+                vbdr.VM = vm;
+                vbdr.VDI = vdi;
+                vbdr.bootable = false;
+                vbdr.userdevice = diskNumber;
+                vbdr.mode = Types.VbdMode.RW;
+                vbdr.type = Types.VbdType.DISK;
+                vbdr.unpluggable = true;
+                final VBD vbd = VBD.create(conn, vbdr);
+
+                // Attach the VBD to the VM
+                vbd.plug(conn);
+
+                // Update the VDI's label to include the VM name
+                vdi.setNameLabel(conn, vdiNameLabel);
+
+                return new AttachVolumeAnswer(command, Long.parseLong(diskNumber), vdi.getUuid(conn));
+            } else {
+                // Look up all VBDs for this VDI
+                final Set<VBD> vbds = vdi.getVBDs(conn);
+
+                // Detach each VBD from its VM, and then destroy it
+                for (final VBD vbd : vbds) {
+                    final VBD.Record vbdr = vbd.getRecord(conn);
+
+                    if (vbdr.currentlyAttached) {
+                        vbd.unplug(conn);
+                    }
+
+                    vbd.destroy(conn);
+                }
+
+                // Update the VDI's label to be "detached"
+                vdi.setNameLabel(conn, "detached");
+
+                if (command.isManaged()) {
+                    citrixResourceBase.handleSrAndVdiDetach(command.get_iScsiName(), conn);
+                }
+
+                return new AttachVolumeAnswer(command);
+            }
+        } catch (final XenAPIException e) {
+            final String msg = errorMsg + " for uuid: " + command.getVolumePath() + "  due
to " + e.toString();
+            s_logger.warn(msg, e);
+            return new AttachVolumeAnswer(command, msg);
+        } catch (final Exception e) {
+            final String msg = errorMsg + " for uuid: " + command.getVolumePath() + "  due
to " + e.getMessage();
+            s_logger.warn(msg, e);
+            return new AttachVolumeAnswer(command, msg);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java
index 5451601..1deefea 100644
--- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapper.java
@@ -22,6 +22,8 @@ package com.cloud.hypervisor.xenserver.resource.wrapper;
 import java.util.Hashtable;
 
 import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeCommand;
 import com.cloud.agent.api.CheckHealthCommand;
 import com.cloud.agent.api.CheckVirtualMachineCommand;
 import com.cloud.agent.api.Command;
@@ -37,6 +39,7 @@ import com.cloud.agent.api.ReadyCommand;
 import com.cloud.agent.api.RebootCommand;
 import com.cloud.agent.api.RebootRouterCommand;
 import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
 import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
 import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
 import com.cloud.agent.api.storage.CreateCommand;
@@ -83,6 +86,9 @@ public class CitrixRequestWrapper extends RequestWrapper {
         map.put(ModifyStoragePoolCommand.class, new CitrixModifyStoragePoolCommandWrapper());
         map.put(DeleteStoragePoolCommand.class, new CitrixDeleteStoragePoolCommandWrapper());
         map.put(ResizeVolumeCommand.class, new CitrixResizeVolumeCommandWrapper());
+        map.put(AttachVolumeCommand.class, new CitrixAttachVolumeCommandWrapper());
+        map.put(AttachIsoCommand.class, new CitrixAttachIsoCommandWrapper());
+        map.put(UpgradeSnapshotCommand.class, new CitrixUpgradeSnapshotCommandWrapper());
     }
 
     public static CitrixRequestWrapper getInstance() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java
b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java
new file mode 100644
index 0000000..a7f3a50
--- /dev/null
+++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixUpgradeSnapshotCommandWrapper.java
@@ -0,0 +1,64 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.hypervisor.xenserver.resource.wrapper;
+
+import java.net.URI;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
+import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
+import com.cloud.resource.CommandWrapper;
+import com.xensource.xenapi.Connection;
+
+public final class CitrixUpgradeSnapshotCommandWrapper extends CommandWrapper<UpgradeSnapshotCommand,
Answer, CitrixResourceBase> {
+
+    private static final Logger s_logger = Logger.getLogger(CitrixUpgradeSnapshotCommandWrapper.class);
+
+    @Override
+    public Answer execute(final UpgradeSnapshotCommand command, final CitrixResourceBase
citrixResourceBase) {
+        final String secondaryStorageUrl = command.getSecondaryStorageUrl();
+        final String backedUpSnapshotUuid = command.getSnapshotUuid();
+        final Long volumeId = command.getVolumeId();
+        final Long accountId = command.getAccountId();
+        final Long templateId = command.getTemplateId();
+        final Long tmpltAcountId = command.getTmpltAccountId();
+        final String version = command.getVersion();
+
+        if (!version.equals("2.1")) {
+            return new Answer(command, true, "success");
+        }
+        try {
+            final Connection conn = citrixResourceBase.getConnection();
+            final URI uri = new URI(secondaryStorageUrl);
+            final String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath();
+            final String snapshotPath = secondaryStorageMountPath + "/snapshots/" + accountId
+ "/" + volumeId + "/" + backedUpSnapshotUuid + ".vhd";
+            final String templatePath = secondaryStorageMountPath + "/template/tmpl/" + tmpltAcountId
+ "/" + templateId;
+            citrixResourceBase.upgradeSnapshot(conn, templatePath, snapshotPath);
+            return new Answer(command, true, "success");
+        } catch (final Exception e) {
+            final String details = "upgrading snapshot " + backedUpSnapshotUuid + " failed
due to " + e.toString();
+            s_logger.error(details, e);
+
+        }
+        return new Answer(command, false, "failure");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ea374b6a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java
b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java
index 9de002e..d5f44e0 100644
--- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java
+++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/CitrixRequestWrapperTest.java
@@ -17,6 +17,8 @@ import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
 
 import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeCommand;
 import com.cloud.agent.api.CheckHealthCommand;
 import com.cloud.agent.api.CheckVirtualMachineCommand;
 import com.cloud.agent.api.Command;
@@ -33,6 +35,7 @@ import com.cloud.agent.api.RebootAnswer;
 import com.cloud.agent.api.RebootCommand;
 import com.cloud.agent.api.RebootRouterCommand;
 import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UpgradeSnapshotCommand;
 import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
 import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
 import com.cloud.agent.api.storage.CreateAnswer;
@@ -43,6 +46,7 @@ import com.cloud.agent.api.to.StorageFilerTO;
 import com.cloud.agent.api.to.VirtualMachineTO;
 import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
 import com.cloud.hypervisor.xenserver.resource.XsHost;
+import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.vm.DiskProfile;
 
@@ -222,6 +226,7 @@ public class CitrixRequestWrapperTest {
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(virtualMachineCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertTrue(answer.getResult());
     }
@@ -235,6 +240,7 @@ public class CitrixRequestWrapperTest {
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(prepareCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
@@ -248,6 +254,7 @@ public class CitrixRequestWrapperTest {
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(migrateCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
@@ -264,6 +271,7 @@ public class CitrixRequestWrapperTest {
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
@@ -281,6 +289,7 @@ public class CitrixRequestWrapperTest {
         when(citrixResourceBase.getHost()).thenReturn(xsHost);
 
         final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
@@ -298,6 +307,7 @@ public class CitrixRequestWrapperTest {
         when(citrixResourceBase.getHost()).thenReturn(xsHost);
 
         final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
@@ -315,6 +325,7 @@ public class CitrixRequestWrapperTest {
         when(citrixResourceBase.getHost()).thenReturn(xsHost);
 
         final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertTrue(answer.getResult());
     }
@@ -323,15 +334,72 @@ public class CitrixRequestWrapperTest {
     public void testResizeVolumeCommand() {
         final StorageFilerTO pool = Mockito.mock(StorageFilerTO.class);
 
-        final ResizeVolumeCommand destroyCommand = new ResizeVolumeCommand("Test", pool,
1l, 3l, false, "Tests-1");
+        final ResizeVolumeCommand resizeCommand = new ResizeVolumeCommand("Test", pool, 1l,
3l, false, "Tests-1");
+
+        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(resizeCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
+
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testAttachVolumeCommand() {
+        final AttachVolumeCommand destroyCommand = new AttachVolumeCommand(false, true, "Test",
StoragePoolType.LVM, "/", "DATA", 100l, 1l, "123");
+
+        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
+
+        assertFalse(answer.getResult());
+    }
+
+    @Test
+    public void testAttachIsoCommand() {
+        final AttachIsoCommand destroyCommand = new AttachIsoCommand("Test", "/", true);
 
         final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
 
         assertFalse(answer.getResult());
     }
+
+    @Test
+    public void testUpgradeSnapshotCommand() {
+        final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class);
+
+        final UpgradeSnapshotCommand destroyCommand = new UpgradeSnapshotCommand(poolVO,
"http", 1l, 1l, 1l, 1l, 1l, "/", "58c5778b-7dd1-47cc-a7b5-f768541bf278", "Test", "2.1");
+
+        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(1)).getConnection();
+
+        assertTrue(answer.getResult());
+    }
+
+    @Test
+    public void testUpgradeSnapshotCommandNo21() {
+        final StoragePoolVO poolVO = Mockito.mock(StoragePoolVO.class);
+
+        final UpgradeSnapshotCommand destroyCommand = new UpgradeSnapshotCommand(poolVO,
"http", 1l, 1l, 1l, 1l, 1l, "/", "58c5778b-7dd1-47cc-a7b5-f768541bf278", "Test", "3.1");
+
+        final CitrixRequestWrapper wrapper = CitrixRequestWrapper.getInstance();
+        assertNotNull(wrapper);
+
+        final Answer answer = wrapper.execute(destroyCommand, citrixResourceBase);
+        verify(citrixResourceBase, times(0)).getConnection();
+
+        assertTrue(answer.getResult());
+    }
 }
 
 class NotAValidCommand extends Command {


Mime
View raw message