diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 2180152ab067..b613f249af4d 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1804,9 +1804,43 @@ protected CheckSshAnswer execute(CheckSshCommand cmd) { networkUsage(privateIp, "create", null); } + if (VirtualMachineName.isValidRouterName(vmName)) { + reconfigureDomainRouterAfterStart(vmName); + } + return new CheckSshAnswer(cmd); } + private void reconfigureDomainRouterAfterStart(String vmName) { + s_logger.debug("Reconfigure to remove machine.id from domain router after start. vmName: " + vmName); + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + if (vmMo == null) { + if (hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO) hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(vmName); + } + } + if (vmMo == null) { + String msg = "VM " + vmName + " no longer exists to execute UnPlugNic command"; + s_logger.error(msg); + throw new Exception(msg); + } + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); + OptionValue option = new OptionValue(); + option.setKey("machine.id"); + option.setValue(""); + vmConfigSpec.getExtraConfig().add(option); + if (!vmMo.configureVm(vmConfigSpec)) { + throw new Exception("Failed to reconfigure domain router after start. vmName: " + vmName); + } + } catch (Exception e) { + s_logger.error("Unexpected exception when reconfigure domain router after start: ", e); + } + } + private DiskTO[] validateDisks(DiskTO[] disks) { List validatedDisks = new ArrayList(); diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 6bed711b5f07..bdfd7cf6541b 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -312,7 +312,7 @@ private static boolean isAlienVm(final VM vm, final Connection conn) throws XenA private static final String XENSTORE_DATA_IP = "vm-data/ip"; private static final String XENSTORE_DATA_GATEWAY = "vm-data/gateway"; private static final String XENSTORE_DATA_NETMASK = "vm-data/netmask"; - private static final String XENSTORE_DATA_CS_INIT = "vm-data/cloudstack/init"; + public static final String XENSTORE_DATA_CS_INIT = "vm-data/cloudstack/init"; public CitrixResourceBase() { } diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java index ec7d844dfbc7..25bf59927a57 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixCheckSshCommandWrapper.java @@ -19,6 +19,10 @@ package com.cloud.hypervisor.xenserver.resource.wrapper.xenbase; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -28,6 +32,8 @@ import com.cloud.resource.CommandWrapper; import com.cloud.resource.ResourceWrapper; import com.xensource.xenapi.Connection; +import com.xensource.xenapi.VM; + @ResourceWrapper(handles = CheckSshCommand.class) public final class CitrixCheckSshCommandWrapper extends CommandWrapper { @@ -60,6 +66,21 @@ public Answer execute(final CheckSshCommand command, final CitrixResourceBase ci s_logger.debug("Ping command port succeeded for vm " + vmName); } + try { + final Set vms = VM.getByNameLabel(conn, vmName); + if (vms != null) { + for (final VM vm : vms) { + s_logger.debug("Update boot args in xenstore-data for domain router after start. vmName: " + vmName); + Map xenstoreData = new HashMap<>(); + xenstoreData.put(citrixResourceBase.XENSTORE_DATA_CS_INIT, ""); + vm.setXenstoreData(conn, xenstoreData); + break; + } + } + } catch (final Exception e) { + s_logger.warn("Catch Exception: " + e.getClass().toString() + " due to " + e.toString(), e); + } + return new CheckSshAnswer(command); } } \ No newline at end of file diff --git a/scripts/vm/hypervisor/kvm/patch.sh b/scripts/vm/hypervisor/kvm/patch.sh index 84c6b5b14509..895dbf1fbe24 100755 --- a/scripts/vm/hypervisor/kvm/patch.sh +++ b/scripts/vm/hypervisor/kvm/patch.sh @@ -72,4 +72,8 @@ do done # Write cmdline payload -send_file $name "/var/cache/cloud/cmdline" $cmdline +if [[ $bootargs =~ .*type=cksnode.* ]];then + send_file $name "/var/cache/cloud/cmdline" $cmdline +else + send_file $name "/var/cache/cloud/cmdline_passed" $cmdline +fi \ No newline at end of file diff --git a/systemvm/debian/opt/cloud/bin/setup/init.sh b/systemvm/debian/opt/cloud/bin/setup/init.sh index a1ac48e46b56..32612975ccdb 100644 --- a/systemvm/debian/opt/cloud/bin/setup/init.sh +++ b/systemvm/debian/opt/cloud/bin/setup/init.sh @@ -19,6 +19,7 @@ set -x PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" CMDLINE=/var/cache/cloud/cmdline +CMDLINE_PASSED=/var/cache/cloud/cmdline_passed hypervisor() { if [ -d /proc/xen ]; then @@ -74,8 +75,14 @@ config_guest() { if [ ! -f /usr/bin/xenstore-read ]; then log_it "ERROR: xentools not installed, cannot found xenstore-read" && exit 5 fi - /usr/bin/xenstore-read vm-data/cloudstack/init > $CMDLINE - sed -i "s/%/ /g" $CMDLINE + /usr/bin/xenstore-read vm-data/cloudstack/init |tr -d "\n$" > $CMDLINE_PASSED + if [ -s $CMDLINE_PASSED ]; then + log_it "Received a new non-empty cmdline file from qemu-guest-agent" + perform_actions_when_boot_from_cloudstack + break + else + sed -i "s/%/ /g" $CMDLINE + fi ;; kvm) # Configure kvm hotplug support @@ -92,12 +99,10 @@ config_guest() { systemctl start qemu-guest-agent # Wait for $CMDLINE file to be written by the qemu-guest-agent - for i in {1..60}; do - if [ -s $CMDLINE ]; then + for i in {1..10}; do + if [ -s $CMDLINE_PASSED ]; then log_it "Received a new non-empty cmdline file from qemu-guest-agent" - # Remove old configuration files in /etc/cloudstack if VR is booted from cloudstack - rm -rf /etc/cloudstack/*.json - log_it "Booting from cloudstack, remove old configuration files in /etc/cloudstack/" + perform_actions_when_boot_from_cloudstack break fi sleep 1 @@ -113,14 +118,25 @@ config_guest() { systemctl enable open-vm-tools systemctl start open-vm-tools - vmtoolsd --cmd 'machine.id.get' > $CMDLINE + vmtoolsd --cmd 'machine.id.get' > $CMDLINE_PASSED + if [ -s $CMDLINE_PASSED ]; then + log_it "Received a new non-empty cmdline file from vm-tools" + perform_actions_when_boot_from_cloudstack + break + fi + ;; virtualpc|hyperv) # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon systemctl enable hyperv-daemons.hv-fcopy-daemon.service hyperv-daemons.hv-kvp-daemon.service hyperv-daemons.hv-vss-daemon.service systemctl start hyperv-daemons.hv-fcopy-daemon.service hyperv-daemons.hv-kvp-daemon.service hyperv-daemons.hv-vss-daemon.service sleep 5 - cp -f /var/opt/hyperv/.kvp_pool_0 $CMDLINE + cp -f /var/opt/hyperv/.kvp_pool_0 $CMDLINE_PASSED + if [ -s $CMDLINE_PASSED ]; then + log_it "Received a new non-empty cmdline file from vm-tools" + perform_actions_when_boot_from_cloudstack + break + fi cat /dev/null > /var/opt/hyperv/.kvp_pool_0 ;; virtualbox) @@ -142,6 +158,13 @@ config_guest() { export TYPE=$(grep -Po 'type=\K[a-zA-Z]*' $CMDLINE) } +perform_actions_when_boot_from_cloudstack() { + rm -rf $CMDLINE && mv $CMDLINE_PASSED $CMDLINE + # Remove old configuration files in /etc/cloudstack if VR is booted from cloudstack + rm -rf /etc/cloudstack/*.json + log_it "Booting from cloudstack, removed old configuration files in /etc/cloudstack/" +} + setup_interface_sshd() { if [ "$TYPE" != "cksnode" ]; then @@ -214,4 +237,4 @@ log_it "Starting guest services for $HYPERVISOR" config_guest source /opt/cloud/bin/setup/common.sh -setup_interface_sshd \ No newline at end of file +setup_interface_sshd diff --git a/tools/marvin/marvin/lib/common.py b/tools/marvin/marvin/lib/common.py index 1c5fc32c3a7c..a52c8bfbbcef 100644 --- a/tools/marvin/marvin/lib/common.py +++ b/tools/marvin/marvin/lib/common.py @@ -1139,6 +1139,14 @@ def get_free_vlan(apiclient, zoneid): list_physical_networks_response) > 0, "No physical networks found in zone %s" % zoneid physical_network = list_physical_networks_response[0] + for physicalNetwork in list_physical_networks_response: + trafficTypes = TrafficType.list( + apiclient, + physicalnetworkid=physicalNetwork.id) + for trafficType in trafficTypes: + if trafficType.traffictype == "Guest": + physical_network = physicalNetwork + break networks = list_networks(apiclient, zoneid=zoneid) usedVlanIds = [] @@ -1161,6 +1169,7 @@ def get_free_vlan(apiclient, zoneid): break else: vlans = xsplit(physical_network.vlan, ['-', ',']) + list.sort(vlans) assert len(vlans) > 0 assert int(vlans[0]) < int(