From b641231ab01f13685b8a237abceebf446a532169 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 17 Jun 2015 15:16:54 +0530 Subject: [PATCH 1/5] Fixed issue in adding vm SG rules on vm reboot for xenserver 6.5 --- scripts/vm/hypervisor/xenserver/vmops | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index d195f5357ae7..0dfa6da038ed 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -927,10 +927,9 @@ def network_rules_for_rebooted_vm(session, vmName): for cmd in [delcmd, delcmd2, inscmd, inscmd2, inscmd3, inscmd4]: cmds = util.pread2(['/bin/bash', '-c', cmd]).split('\n') cmds.pop() - for c in cmds: + for c in filter(None,cmds): ipt = c.split(' ') ipt.insert(0, 'iptables') - ipt.pop() ipts.append(ipt) for ipt in ipts: From c3304c5d38759a4f0f304c378886c274662c4815 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Tue, 9 Jun 2015 16:13:21 +0530 Subject: [PATCH 2/5] CLOUDSTACK-8324: Added migration changes for config drive --- .../AttachOrDettachConfigDriveCommand.java | 58 ++++++++++ .../cloud/vm/VirtualMachineManagerImpl.java | 59 +++++++++- .../resource/CitrixResourceBase.java | 102 +++++++++++++++++- ...er610MigrateWithStorageCommandWrapper.java | 2 +- ...achOrDettachConfigDriveCommandWrapper.java | 95 ++++++++++++++++ .../xenbase/CitrixMigrateCommandWrapper.java | 22 +++- ...trixPrepareForMigrationCommandWrapper.java | 11 +- .../xenbase/XenServer610WrapperTest.java | 2 +- 8 files changed, 339 insertions(+), 12 deletions(-) create mode 100644 core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java create mode 100644 plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java diff --git a/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java b/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java new file mode 100644 index 000000000000..ebf5d0b746ff --- /dev/null +++ b/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java @@ -0,0 +1,58 @@ +// +// 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.agent.api; + +import java.util.List; + +public class AttachOrDettachConfigDriveCommand extends Command { + + String vmName; + List vmData; + String configDriveLabel; + boolean isAttach = false; + + public AttachOrDettachConfigDriveCommand(String vmName, List vmData, String label, boolean attach) { + this.vmName = vmName; + this.vmData = vmData; + this.configDriveLabel = label; + this.isAttach = attach; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getVmName() { + return vmName; + } + + public List getVmData() { + return vmData; + } + + public boolean isAttach() { + return isAttach; + } + + public String getConfigDriveLabel() { + return configDriveLabel; + } +} diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index ad31fdda0a78..42d1bf3906d2 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -38,6 +38,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.agent.api.AttachOrDettachConfigDriveCommand; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -273,6 +274,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected VGPUTypesDao _vgpuTypesDao; @Inject protected EntityManager _entityMgr; + @Inject + protected GuestOSCategoryDao _guestOSCategoryDao; + @Inject + protected GuestOSDao _guestOSDao = null; + @Inject + protected UserVmDetailsDao _vmDetailsDao; + @Inject + ServiceOfferingDao _serviceOfferingDao = null; @Inject ConfigDepot _configDepot; @@ -315,6 +324,8 @@ public void setHostAllocators(final List hostAllocators) { protected VmWorkJobDao _workJobDao; @Inject protected AsyncJobManager _jobMgr; + @Inject + protected UserVmService _userVmSrv; VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); @@ -352,6 +363,9 @@ public void setHostAllocators(final List hostAllocators) { Integer.class, "vm.job.report.interval", "60", "Interval to send application level pings to make sure the connection is still working", false); + static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", + "The default lable name for the config drive", false); + ScheduledExecutorService _executor = null; protected long _nodeId; @@ -1916,6 +1930,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null); _networkMgr.prepareNicForMigration(profile, dest); volumeMgr.prepareForMigration(profile, dest); + profile.setConfigDriveLabel( _userVmSrv.VmConfigDriveLabel.value()); final VirtualMachineTO to = toVmTO(profile); final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); @@ -2215,6 +2230,48 @@ private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHo boolean migrated = false; try { + + // config drive: Detach the config drive at source host + // After migration successful attach the config drive in destination host + // On migration failure VM will be stopped, So configIso will be deleted + + Nic defaultNic = _networkModel.getDefaultNic(vm.getId()); + + List vmData = null; + if (defaultNic != null) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + Map details = _vmDetailsDao.listDetailsKeyPairs(vm.getId()); + vm.setDetails(details); + + Network network = _networkModel.getNetwork(defaultNic.getNetworkId()); + if (_networkModel.isSharedNetworkWithoutServices(network.getId())) { + final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); + final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); + boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); + + vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(), + (String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows); + String vmName = vm.getInstanceName(); + String configDriveIsoRootFolder = "/tmp"; + String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso"; + profile.setVmData(vmData); + profile.setConfigDriveLabel(VmConfigDriveLabel.value()); + profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder); + profile.setConfigDriveIsoFile(isoFile); + + // At source host detach the config drive iso. + AttachOrDettachConfigDriveCommand dettachCommand = new AttachOrDettachConfigDriveCommand(vm.getInstanceName(), vmData, VmConfigDriveLabel.value(), false); + try { + _agentMgr.send(srcHost.getId(), dettachCommand); + s_logger.debug("Deleted config drive ISO for vm " + vm.getInstanceName() + " In host " + srcHost); + } catch (OperationTimedoutException e) { + s_logger.debug("TIme out occured while exeuting command AttachOrDettachConfigDrive " + e.getMessage()); + + } + + } + } + // Migrate the vm and its volume. volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap); @@ -3614,7 +3671,7 @@ public String getConfigComponentName() { public ConfigKey[] getConfigKeys() { return new ConfigKey[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait, VmOpLockStateRetry, - VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval}; + VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel}; } public List getStoragePoolAllocators() { 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 aa02d00416f4..797fd5c485be 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 @@ -257,7 +257,7 @@ private static boolean isAlienVm(final VM vm, final Connection conn) throws XenA protected String _configDriveIsopath = "/opt/xensource/packages/configdrive_iso/"; protected String _configDriveSRName = "ConfigDriveISOs"; - protected String _attachIsoDeviceNum = "3"; + public String _attachIsoDeviceNum = "3"; protected int _wait; // Hypervisor specific params with generic value, may need to be overridden @@ -3879,17 +3879,29 @@ public ExecutionResult prepareCommand(final NetworkElementCommand cmd) { return new ExecutionResult(true, null); } - public void prepareISO(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + public void prepareISO(final Connection conn, final String vmName, List vmDataList, String configDriveLabel) throws XmlRpcException, XenAPIException { final Set vms = VM.getByNameLabel(conn, vmName); if (vms == null || vms.size() != 1) { throw new CloudRuntimeException("There are " + (vms == null ? "0" : vms.size()) + " VMs named " + vmName); } final VM vm = vms.iterator().next(); + + if (vmDataList != null) { + // create SR + SR sr = createLocalIsoSR(conn, _configDriveSRName+getHost().getIp()); + + // 1. create vm data files + createVmdataFiles(vmName, vmDataList, configDriveLabel); + + // 2. copy config drive iso to host + copyConfigDriveIsoToHost(conn, sr, vmName); + } + final Set vbds = vm.getVBDs(conn); for (final VBD vbd : vbds) { final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.type == Types.VbdType.CD && vbdr.empty == false) { + if (vbdr.type == Types.VbdType.CD && vbdr.empty == false && vbdr.userdevice.equals(_attachIsoDeviceNum)) { final VDI vdi = vbdr.VDI; final SR sr = vdi.getSR(conn); final Set pbds = sr.getPBDs(conn); @@ -5261,4 +5273,88 @@ public void deleteLocalFolder(String directory) throws Exception { } } + + protected SR getSRByNameLabel(Connection conn, String name) throws BadServerResponse, XenAPIException, XmlRpcException { + Set srs = SR.getByNameLabel(conn, name); + SR ressr = null; + for (SR sr : srs) { + Set pbds; + pbds = sr.getPBDs(conn); + for (PBD pbd : pbds) { + PBD.Record pbdr = pbd.getRecord(conn); + if (pbdr.host != null) { + ressr = sr; + break; + } + } + } + return ressr; + } + + + public boolean AttachConfigDriveToMigratedVm(Connection conn, String vmName, String ipAddr) { + + // attach the config drive in destination host + + try { + s_logger.debug("Attaching config drive iso device for the VM "+ vmName + " In host "+ ipAddr); + Set vms = VM.getByNameLabel(conn, vmName); + + SR sr = getSRByNameLabel(conn, _configDriveSRName + ipAddr); + //Here you will find only two vdis with the .iso. + //one is from source host and second from dest host + Set vdis = VDI.getByNameLabel(conn, vmName + ".iso"); + if (vdis.isEmpty()) { + s_logger.debug("Could not find config drive ISO: " + vmName); + return false; + } + + VDI configdriveVdi = null; + for (VDI vdi : vdis) { + SR vdiSr = vdi.getSR(conn); + if (vdiSr.getUuid(conn).equals(sr.getUuid(conn))) { + //get this vdi to attach to vbd + configdriveVdi = vdi; + s_logger.debug("VDI for the config drive ISO " + vdi); + } else { + // delete the vdi in source host so that the .iso file is get removed + s_logger.debug("Removing the source host VDI for the config drive ISO " + vdi); + vdi.destroy(conn); + } + } + + if (configdriveVdi == null) { + s_logger.debug("Config drive ISO VDI is not found "); + return false; + } + + for (VM vm : vms) { + + //create vbd + VBD.Record cfgDriveVbdr = new VBD.Record(); + cfgDriveVbdr.VM = vm; + cfgDriveVbdr.empty = true; + cfgDriveVbdr.bootable = false; + cfgDriveVbdr.userdevice = "autodetect"; + cfgDriveVbdr.mode = Types.VbdMode.RO; + cfgDriveVbdr.type = Types.VbdType.CD; + + VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr); + + s_logger.debug("Inserting vbd " + configdriveVdi); + cfgDriveVBD.insert(conn, configdriveVdi); + break; + + } + + return true; + + }catch (Exception ex) { + s_logger.debug("Failed to attach config drive ISO to the VM "+ vmName + " In host " + ipAddr ); + return false; + } + + } + + } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java index b5c175a9a7c9..2a79d26b0451 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java @@ -67,7 +67,7 @@ public Answer execute(final MigrateWithStorageCommand command, final XenServer61 final XsHost xsHost = xenServer610Resource.getHost(); final String uuid = xsHost.getUuid(); try { - xenServer610Resource.prepareISO(connection, vmName); + xenServer610Resource.prepareISO(connection, vmName, null, null); // Get the list of networks and recreate VLAN, if required. for (final NicTO nicTo : vmSpec.getNics()) { diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java new file mode 100644 index 000000000000..a7bfa45b3779 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java @@ -0,0 +1,95 @@ +// +// 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.xenbase; + +import java.util.List; +import java.util.Set; + +import com.cloud.agent.api.AttachOrDettachConfigDriveCommand; +import com.cloud.resource.ResourceWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.Types; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import org.apache.xmlrpc.XmlRpcException; + +@ResourceWrapper(handles = AttachOrDettachConfigDriveCommand.class) +public final class CitrixAttachOrDettachConfigDriveCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixAttachOrDettachConfigDriveCommandWrapper.class); + + @Override + public Answer execute(final AttachOrDettachConfigDriveCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + String vmName = command.getVmName(); + List vmData = command.getVmData(); + String label = command.getConfigDriveLabel(); + Boolean isAttach = command.isAttach(); + + try { + Set vms = VM.getByNameLabel(conn, vmName); + for (VM vm : vms) { + if (isAttach) { + if (!citrixResourceBase.createAndAttachConfigDriveIsoForVM(conn, vm, vmData, label)) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName); + } + } else { + // delete the config drive iso attached to VM + Set vdis = VDI.getByNameLabel(conn, vmName+".iso"); + if (vdis != null && !vdis.isEmpty()) { + s_logger.debug("Deleting config drive for the VM " + vmName); + VDI vdi = vdis.iterator().next(); + // Find the VM's CD-ROM VBD + Set vbds = vdi.getVBDs(conn); + + for (VBD vbd : vbds) { + VBD.Record vbdRec = vbd.getRecord(conn); + + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty && !vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) { + if (vbdRec.currentlyAttached) { + vbd.eject(conn); + } + vbd.destroy(conn); + } + } + vdi.destroy(conn); + } + + s_logger.debug("Successfully dettached config drive iso from the VM " + vmName); + } + } + }catch (Types.XenAPIException ex) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName + " " + ex.getMessage() ); + }catch (XmlRpcException ex) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName + " "+ex.getMessage()); + } + + return new Answer(command, true, "success"); + + + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java index 07f7cc611882..00ed622cc317 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java @@ -44,24 +44,23 @@ public final class CitrixMigrateCommandWrapper extends CommandWrapper vms = VM.getByNameLabel(conn, vmName); - final String ipaddr = command.getDestinationIp(); - final Set hosts = Host.getAll(conn); Host dsthost = null; if(hosts != null) { for (final Host host : hosts) { - if (host.getAddress(conn).equals(ipaddr)) { + if (host.getAddress(conn).equals(dstHostIpAddr)) { dsthost = host; break; } } } if (dsthost == null) { - final String msg = "Migration failed due to unable to find host " + ipaddr + " in XenServer pool " + citrixResourceBase.getHost().getPool(); + final String msg = "Migration failed due to unable to find host " + dstHostIpAddr + " in XenServer pool " + citrixResourceBase.getHost().getPool(); s_logger.warn(msg); return new MigrateAnswer(command, false, msg, null); } @@ -71,12 +70,25 @@ public Answer execute(final MigrateCommand command, final CitrixResourceBase cit final VBD.Record vbdRec = vbd.getRecord(conn); if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { vbd.eject(conn); - break; + // for config drive vbd destroy the vbd. + if (!vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) { + if (vbdRec.currentlyAttached) { + vbd.destroy(conn); + } + } + continue; } } citrixResourceBase.migrateVM(conn, dsthost, vm, vmName); vm.setAffinity(conn, dsthost); } + + // The iso can be attached to vm only once the vm is (present in the host) migrated. + // Attach the config drive iso device to VM + if (!citrixResourceBase.AttachConfigDriveToMigratedVm(conn, vmName, dstHostIpAddr)) { + s_logger.debug("Config drive ISO attach failed after migration for vm "+vmName); + } + return new MigrateAnswer(command, true, "migration succeeded", null); } catch (final Exception e) { s_logger.warn(e.getMessage(), e); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java index ffe875c8e195..2fa25be8e662 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java @@ -31,6 +31,8 @@ import com.cloud.resource.ResourceWrapper; import com.xensource.xenapi.Connection; +import java.util.List; + @ResourceWrapper(handles = PrepareForMigrationCommand.class) public final class CitrixPrepareForMigrationCommandWrapper extends CommandWrapper { @@ -41,13 +43,20 @@ public Answer execute(final PrepareForMigrationCommand command, final CitrixReso final Connection conn = citrixResourceBase.getConnection(); final VirtualMachineTO vm = command.getVirtualMachine(); + List vmDataList = vm.getVmData(); + String configDriveLabel = vm.getConfigDriveLabel(); + + if (configDriveLabel == null) { + configDriveLabel = "config"; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Preparing host for migrating " + vm); } final NicTO[] nics = vm.getNics(); try { - citrixResourceBase.prepareISO(conn, vm.getName()); + citrixResourceBase.prepareISO(conn, vm.getName(), vmDataList, configDriveLabel); for (final NicTO nic : nics) { citrixResourceBase.getNetwork(conn, nic); diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java index f308ea39a3fa..70ddfad0a808 100644 --- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java @@ -170,7 +170,7 @@ public void testMigrateWithStorageCommand() { verify(xenServer610Resource, times(1)).getConnection(); try { - verify(xenServer610Resource, times(1)).prepareISO(conn, vmName); + verify(xenServer610Resource, times(1)).prepareISO(conn, vmName, null, null); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO1); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO2); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO3); From b8c112e35bcc98e1ee142cfb8901a0d9af28320d Mon Sep 17 00:00:00 2001 From: Jayapal Date: Tue, 9 Jun 2015 16:13:21 +0530 Subject: [PATCH 3/5] CLOUDSTACK-8324: Added migration changes for config drive --- .../AttachOrDettachConfigDriveCommand.java | 58 ++++++++++ .../cloud/vm/VirtualMachineManagerImpl.java | 59 +++++++++- .../resource/CitrixResourceBase.java | 102 +++++++++++++++++- ...er610MigrateWithStorageCommandWrapper.java | 2 +- ...achOrDettachConfigDriveCommandWrapper.java | 95 ++++++++++++++++ .../xenbase/CitrixMigrateCommandWrapper.java | 22 +++- ...trixPrepareForMigrationCommandWrapper.java | 11 +- .../xenbase/XenServer610WrapperTest.java | 2 +- 8 files changed, 339 insertions(+), 12 deletions(-) create mode 100644 core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java create mode 100644 plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java diff --git a/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java b/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java new file mode 100644 index 000000000000..ebf5d0b746ff --- /dev/null +++ b/core/src/com/cloud/agent/api/AttachOrDettachConfigDriveCommand.java @@ -0,0 +1,58 @@ +// +// 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.agent.api; + +import java.util.List; + +public class AttachOrDettachConfigDriveCommand extends Command { + + String vmName; + List vmData; + String configDriveLabel; + boolean isAttach = false; + + public AttachOrDettachConfigDriveCommand(String vmName, List vmData, String label, boolean attach) { + this.vmName = vmName; + this.vmData = vmData; + this.configDriveLabel = label; + this.isAttach = attach; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getVmName() { + return vmName; + } + + public List getVmData() { + return vmData; + } + + public boolean isAttach() { + return isAttach; + } + + public String getConfigDriveLabel() { + return configDriveLabel; + } +} diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 057c9e2b77fe..41143866ee2b 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -38,6 +38,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.agent.api.AttachOrDettachConfigDriveCommand; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -273,6 +274,14 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac protected VGPUTypesDao _vgpuTypesDao; @Inject protected EntityManager _entityMgr; + @Inject + protected GuestOSCategoryDao _guestOSCategoryDao; + @Inject + protected GuestOSDao _guestOSDao = null; + @Inject + protected UserVmDetailsDao _vmDetailsDao; + @Inject + ServiceOfferingDao _serviceOfferingDao = null; @Inject ConfigDepot _configDepot; @@ -315,6 +324,8 @@ public void setHostAllocators(final List hostAllocators) { protected VmWorkJobDao _workJobDao; @Inject protected AsyncJobManager _jobMgr; + @Inject + protected UserVmService _userVmSrv; VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); @@ -352,6 +363,9 @@ public void setHostAllocators(final List hostAllocators) { Integer.class, "vm.job.report.interval", "60", "Interval to send application level pings to make sure the connection is still working", false); + static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", + "The default lable name for the config drive", false); + ScheduledExecutorService _executor = null; protected long _nodeId; @@ -1916,6 +1930,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null); _networkMgr.prepareNicForMigration(profile, dest); volumeMgr.prepareForMigration(profile, dest); + profile.setConfigDriveLabel( _userVmSrv.VmConfigDriveLabel.value()); final VirtualMachineTO to = toVmTO(profile); final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); @@ -2215,6 +2230,48 @@ private void orchestrateMigrateWithStorage(final String vmUuid, final long srcHo boolean migrated = false; try { + + // config drive: Detach the config drive at source host + // After migration successful attach the config drive in destination host + // On migration failure VM will be stopped, So configIso will be deleted + + Nic defaultNic = _networkModel.getDefaultNic(vm.getId()); + + List vmData = null; + if (defaultNic != null) { + UserVmVO userVm = _userVmDao.findById(vm.getId()); + Map details = _vmDetailsDao.listDetailsKeyPairs(vm.getId()); + vm.setDetails(details); + + Network network = _networkModel.getNetwork(defaultNic.getNetworkId()); + if (_networkModel.isSharedNetworkWithoutServices(network.getId())) { + final String serviceOffering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getId(), vm.getServiceOfferingId()).getDisplayText(); + final String zoneName = _dcDao.findById(vm.getDataCenterId()).getName(); + boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows"); + + vmData = _networkModel.generateVmData(userVm.getUserData(), serviceOffering, zoneName, vm.getInstanceName(), vm.getId(), + (String) profile.getParameter(VirtualMachineProfile.Param.VmSshPubKey), (String) profile.getParameter(VirtualMachineProfile.Param.VmPassword), isWindows); + String vmName = vm.getInstanceName(); + String configDriveIsoRootFolder = "/tmp"; + String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso"; + profile.setVmData(vmData); + profile.setConfigDriveLabel(VmConfigDriveLabel.value()); + profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder); + profile.setConfigDriveIsoFile(isoFile); + + // At source host detach the config drive iso. + AttachOrDettachConfigDriveCommand dettachCommand = new AttachOrDettachConfigDriveCommand(vm.getInstanceName(), vmData, VmConfigDriveLabel.value(), false); + try { + _agentMgr.send(srcHost.getId(), dettachCommand); + s_logger.debug("Deleted config drive ISO for vm " + vm.getInstanceName() + " In host " + srcHost); + } catch (OperationTimedoutException e) { + s_logger.debug("TIme out occured while exeuting command AttachOrDettachConfigDrive " + e.getMessage()); + + } + + } + } + // Migrate the vm and its volume. volumeMgr.migrateVolumes(vm, to, srcHost, destHost, volumeToPoolMap); @@ -3614,7 +3671,7 @@ public String getConfigComponentName() { public ConfigKey[] getConfigKeys() { return new ConfigKey[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait, VmOpLockStateRetry, - VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval}; + VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel}; } public List getStoragePoolAllocators() { 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 8ed4ffc166ac..9fb18b849049 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 @@ -257,7 +257,7 @@ private static boolean isAlienVm(final VM vm, final Connection conn) throws XenA protected String _configDriveIsopath = "/opt/xensource/packages/configdrive_iso/"; protected String _configDriveSRName = "ConfigDriveISOs"; - protected String _attachIsoDeviceNum = "3"; + public String _attachIsoDeviceNum = "3"; protected int _wait; // Hypervisor specific params with generic value, may need to be overridden @@ -3888,17 +3888,29 @@ public ExecutionResult prepareCommand(final NetworkElementCommand cmd) { return new ExecutionResult(true, null); } - public void prepareISO(final Connection conn, final String vmName) throws XmlRpcException, XenAPIException { + public void prepareISO(final Connection conn, final String vmName, List vmDataList, String configDriveLabel) throws XmlRpcException, XenAPIException { final Set vms = VM.getByNameLabel(conn, vmName); if (vms == null || vms.size() != 1) { throw new CloudRuntimeException("There are " + (vms == null ? "0" : vms.size()) + " VMs named " + vmName); } final VM vm = vms.iterator().next(); + + if (vmDataList != null) { + // create SR + SR sr = createLocalIsoSR(conn, _configDriveSRName+getHost().getIp()); + + // 1. create vm data files + createVmdataFiles(vmName, vmDataList, configDriveLabel); + + // 2. copy config drive iso to host + copyConfigDriveIsoToHost(conn, sr, vmName); + } + final Set vbds = vm.getVBDs(conn); for (final VBD vbd : vbds) { final VBD.Record vbdr = vbd.getRecord(conn); - if (vbdr.type == Types.VbdType.CD && vbdr.empty == false) { + if (vbdr.type == Types.VbdType.CD && vbdr.empty == false && vbdr.userdevice.equals(_attachIsoDeviceNum)) { final VDI vdi = vbdr.VDI; final SR sr = vdi.getSR(conn); final Set pbds = sr.getPBDs(conn); @@ -5270,4 +5282,88 @@ public void deleteLocalFolder(String directory) throws Exception { } } + + protected SR getSRByNameLabel(Connection conn, String name) throws BadServerResponse, XenAPIException, XmlRpcException { + Set srs = SR.getByNameLabel(conn, name); + SR ressr = null; + for (SR sr : srs) { + Set pbds; + pbds = sr.getPBDs(conn); + for (PBD pbd : pbds) { + PBD.Record pbdr = pbd.getRecord(conn); + if (pbdr.host != null) { + ressr = sr; + break; + } + } + } + return ressr; + } + + + public boolean AttachConfigDriveToMigratedVm(Connection conn, String vmName, String ipAddr) { + + // attach the config drive in destination host + + try { + s_logger.debug("Attaching config drive iso device for the VM "+ vmName + " In host "+ ipAddr); + Set vms = VM.getByNameLabel(conn, vmName); + + SR sr = getSRByNameLabel(conn, _configDriveSRName + ipAddr); + //Here you will find only two vdis with the .iso. + //one is from source host and second from dest host + Set vdis = VDI.getByNameLabel(conn, vmName + ".iso"); + if (vdis.isEmpty()) { + s_logger.debug("Could not find config drive ISO: " + vmName); + return false; + } + + VDI configdriveVdi = null; + for (VDI vdi : vdis) { + SR vdiSr = vdi.getSR(conn); + if (vdiSr.getUuid(conn).equals(sr.getUuid(conn))) { + //get this vdi to attach to vbd + configdriveVdi = vdi; + s_logger.debug("VDI for the config drive ISO " + vdi); + } else { + // delete the vdi in source host so that the .iso file is get removed + s_logger.debug("Removing the source host VDI for the config drive ISO " + vdi); + vdi.destroy(conn); + } + } + + if (configdriveVdi == null) { + s_logger.debug("Config drive ISO VDI is not found "); + return false; + } + + for (VM vm : vms) { + + //create vbd + VBD.Record cfgDriveVbdr = new VBD.Record(); + cfgDriveVbdr.VM = vm; + cfgDriveVbdr.empty = true; + cfgDriveVbdr.bootable = false; + cfgDriveVbdr.userdevice = "autodetect"; + cfgDriveVbdr.mode = Types.VbdMode.RO; + cfgDriveVbdr.type = Types.VbdType.CD; + + VBD cfgDriveVBD = VBD.create(conn, cfgDriveVbdr); + + s_logger.debug("Inserting vbd " + configdriveVdi); + cfgDriveVBD.insert(conn, configdriveVdi); + break; + + } + + return true; + + }catch (Exception ex) { + s_logger.debug("Failed to attach config drive ISO to the VM "+ vmName + " In host " + ipAddr ); + return false; + } + + } + + } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java index b5c175a9a7c9..2a79d26b0451 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xen610/XenServer610MigrateWithStorageCommandWrapper.java @@ -67,7 +67,7 @@ public Answer execute(final MigrateWithStorageCommand command, final XenServer61 final XsHost xsHost = xenServer610Resource.getHost(); final String uuid = xsHost.getUuid(); try { - xenServer610Resource.prepareISO(connection, vmName); + xenServer610Resource.prepareISO(connection, vmName, null, null); // Get the list of networks and recreate VLAN, if required. for (final NicTO nicTo : vmSpec.getNics()) { diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java new file mode 100644 index 000000000000..a7bfa45b3779 --- /dev/null +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixAttachOrDettachConfigDriveCommandWrapper.java @@ -0,0 +1,95 @@ +// +// 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.xenbase; + +import java.util.List; +import java.util.Set; + +import com.cloud.agent.api.AttachOrDettachConfigDriveCommand; +import com.cloud.resource.ResourceWrapper; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.Types; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase; +import com.cloud.resource.CommandWrapper; +import org.apache.xmlrpc.XmlRpcException; + +@ResourceWrapper(handles = AttachOrDettachConfigDriveCommand.class) +public final class CitrixAttachOrDettachConfigDriveCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(CitrixAttachOrDettachConfigDriveCommandWrapper.class); + + @Override + public Answer execute(final AttachOrDettachConfigDriveCommand command, final CitrixResourceBase citrixResourceBase) { + final Connection conn = citrixResourceBase.getConnection(); + + String vmName = command.getVmName(); + List vmData = command.getVmData(); + String label = command.getConfigDriveLabel(); + Boolean isAttach = command.isAttach(); + + try { + Set vms = VM.getByNameLabel(conn, vmName); + for (VM vm : vms) { + if (isAttach) { + if (!citrixResourceBase.createAndAttachConfigDriveIsoForVM(conn, vm, vmData, label)) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName); + } + } else { + // delete the config drive iso attached to VM + Set vdis = VDI.getByNameLabel(conn, vmName+".iso"); + if (vdis != null && !vdis.isEmpty()) { + s_logger.debug("Deleting config drive for the VM " + vmName); + VDI vdi = vdis.iterator().next(); + // Find the VM's CD-ROM VBD + Set vbds = vdi.getVBDs(conn); + + for (VBD vbd : vbds) { + VBD.Record vbdRec = vbd.getRecord(conn); + + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty && !vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) { + if (vbdRec.currentlyAttached) { + vbd.eject(conn); + } + vbd.destroy(conn); + } + } + vdi.destroy(conn); + } + + s_logger.debug("Successfully dettached config drive iso from the VM " + vmName); + } + } + }catch (Types.XenAPIException ex) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName + " " + ex.getMessage() ); + }catch (XmlRpcException ex) { + s_logger.debug("Failed to attach config drive iso to VM " + vmName + " "+ex.getMessage()); + } + + return new Answer(command, true, "success"); + + + } +} \ No newline at end of file diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java index 07f7cc611882..00ed622cc317 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixMigrateCommandWrapper.java @@ -44,24 +44,23 @@ public final class CitrixMigrateCommandWrapper extends CommandWrapper vms = VM.getByNameLabel(conn, vmName); - final String ipaddr = command.getDestinationIp(); - final Set hosts = Host.getAll(conn); Host dsthost = null; if(hosts != null) { for (final Host host : hosts) { - if (host.getAddress(conn).equals(ipaddr)) { + if (host.getAddress(conn).equals(dstHostIpAddr)) { dsthost = host; break; } } } if (dsthost == null) { - final String msg = "Migration failed due to unable to find host " + ipaddr + " in XenServer pool " + citrixResourceBase.getHost().getPool(); + final String msg = "Migration failed due to unable to find host " + dstHostIpAddr + " in XenServer pool " + citrixResourceBase.getHost().getPool(); s_logger.warn(msg); return new MigrateAnswer(command, false, msg, null); } @@ -71,12 +70,25 @@ public Answer execute(final MigrateCommand command, final CitrixResourceBase cit final VBD.Record vbdRec = vbd.getRecord(conn); if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { vbd.eject(conn); - break; + // for config drive vbd destroy the vbd. + if (!vbdRec.userdevice.equals(citrixResourceBase._attachIsoDeviceNum)) { + if (vbdRec.currentlyAttached) { + vbd.destroy(conn); + } + } + continue; } } citrixResourceBase.migrateVM(conn, dsthost, vm, vmName); vm.setAffinity(conn, dsthost); } + + // The iso can be attached to vm only once the vm is (present in the host) migrated. + // Attach the config drive iso device to VM + if (!citrixResourceBase.AttachConfigDriveToMigratedVm(conn, vmName, dstHostIpAddr)) { + s_logger.debug("Config drive ISO attach failed after migration for vm "+vmName); + } + return new MigrateAnswer(command, true, "migration succeeded", null); } catch (final Exception e) { s_logger.warn(e.getMessage(), e); diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java index ffe875c8e195..2fa25be8e662 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixPrepareForMigrationCommandWrapper.java @@ -31,6 +31,8 @@ import com.cloud.resource.ResourceWrapper; import com.xensource.xenapi.Connection; +import java.util.List; + @ResourceWrapper(handles = PrepareForMigrationCommand.class) public final class CitrixPrepareForMigrationCommandWrapper extends CommandWrapper { @@ -41,13 +43,20 @@ public Answer execute(final PrepareForMigrationCommand command, final CitrixReso final Connection conn = citrixResourceBase.getConnection(); final VirtualMachineTO vm = command.getVirtualMachine(); + List vmDataList = vm.getVmData(); + String configDriveLabel = vm.getConfigDriveLabel(); + + if (configDriveLabel == null) { + configDriveLabel = "config"; + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Preparing host for migrating " + vm); } final NicTO[] nics = vm.getNics(); try { - citrixResourceBase.prepareISO(conn, vm.getName()); + citrixResourceBase.prepareISO(conn, vm.getName(), vmDataList, configDriveLabel); for (final NicTO nic : nics) { citrixResourceBase.getNetwork(conn, nic); diff --git a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java index f308ea39a3fa..70ddfad0a808 100644 --- a/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java +++ b/plugins/hypervisors/xenserver/test/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/XenServer610WrapperTest.java @@ -170,7 +170,7 @@ public void testMigrateWithStorageCommand() { verify(xenServer610Resource, times(1)).getConnection(); try { - verify(xenServer610Resource, times(1)).prepareISO(conn, vmName); + verify(xenServer610Resource, times(1)).prepareISO(conn, vmName, null, null); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO1); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO2); verify(xenServer610Resource, times(1)).getNetwork(conn, nicTO3); From 197f0cb99e9e24684d644ae39ce62690b859b25f Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 1 Jul 2015 14:19:20 +0530 Subject: [PATCH 4/5] Removed using config drive label from the uservmservice --- .../src/com/cloud/vm/VirtualMachineManagerImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 41143866ee2b..c61f13fc1da6 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -324,8 +324,6 @@ public void setHostAllocators(final List hostAllocators) { protected VmWorkJobDao _workJobDao; @Inject protected AsyncJobManager _jobMgr; - @Inject - protected UserVmService _userVmSrv; VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); @@ -1930,7 +1928,7 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()), null, null); _networkMgr.prepareNicForMigration(profile, dest); volumeMgr.prepareForMigration(profile, dest); - profile.setConfigDriveLabel( _userVmSrv.VmConfigDriveLabel.value()); + profile.setConfigDriveLabel(VmConfigDriveLabel.value()); final VirtualMachineTO to = toVmTO(profile); final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to); From faa531de9dd3c1187a60d0ca62ed8a3eefba4f47 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 2 Jul 2015 09:56:58 +0530 Subject: [PATCH 5/5] Fixed config key in multiple places --- api/src/com/cloud/vm/UserVmService.java | 3 --- engine/api/src/com/cloud/vm/VirtualMachineManager.java | 3 +++ .../src/com/cloud/vm/VirtualMachineManagerImpl.java | 3 --- server/src/com/cloud/vm/UserVmManagerImpl.java | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index 2935815a1032..c0f2de992458 100644 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -55,12 +55,9 @@ import com.cloud.user.Account; import com.cloud.uservm.UserVm; import com.cloud.utils.exception.ExecutionException; -import org.apache.cloudstack.framework.config.ConfigKey; public interface UserVmService { - static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", - "The default lable name for the config drive", false); /** * Destroys one virtual machine diff --git a/engine/api/src/com/cloud/vm/VirtualMachineManager.java b/engine/api/src/com/cloud/vm/VirtualMachineManager.java index b1e5258af79a..8b2265642293 100644 --- a/engine/api/src/com/cloud/vm/VirtualMachineManager.java +++ b/engine/api/src/com/cloud/vm/VirtualMachineManager.java @@ -52,6 +52,9 @@ public interface VirtualMachineManager extends Manager { "If set to true, StartCommand, StopCommand, CopyCommand, MigrateCommand will be synchronized on the agent side." + " If set to false, these commands become asynchronous. Default value is false.", false); + static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", + "The default lable name for the config drive", false); + public interface Topics { public static final String VM_POWER_STATE = "vm.powerstate"; } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index c61f13fc1da6..30184890051d 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -361,9 +361,6 @@ public void setHostAllocators(final List hostAllocators) { Integer.class, "vm.job.report.interval", "60", "Interval to send application level pings to make sure the connection is still working", false); - static final ConfigKey VmConfigDriveLabel = new ConfigKey("Hidden", String.class, "vm.configdrive.label", "config", - "The default lable name for the config drive", false); - ScheduledExecutorService _executor = null; protected long _nodeId; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 894749cf0b37..b9c5350f2362 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3517,7 +3517,7 @@ public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, Depl String configDriveIsoRootFolder = "/tmp"; String isoFile = configDriveIsoRootFolder + "/" + vmName + "/configDrive/" + vmName + ".iso"; profile.setVmData(vmData); - profile.setConfigDriveLabel(VmConfigDriveLabel.value()); + profile.setConfigDriveLabel(VirtualMachineManager.VmConfigDriveLabel.value()); profile.setConfigDriveIsoRootFolder(configDriveIsoRootFolder); profile.setConfigDriveIsoFile(isoFile); } @@ -5292,7 +5292,7 @@ public String getConfigComponentName() { @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {EnableDynamicallyScaleVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax, VmConfigDriveLabel}; + return new ConfigKey[] {EnableDynamicallyScaleVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax}; } @Override