You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ra...@apache.org on 2014/01/28 03:03:37 UTC
[1/3] git commit: updated refs/heads/master to 39447cc
Updated Branches:
refs/heads/master ce0dc3b30 -> 39447cce6
CLOUDSTACK-5941 User Vm deployment on HyperV is failing due to change in the userdata script location and moved to json model
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/39447cce
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/39447cce
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/39447cce
Branch: refs/heads/master
Commit: 39447cce6ec973e84abc04e3af96f2a027a4632a
Parents: 7ac4893
Author: Rajesh Battala <ra...@citrix.com>
Authored: Tue Jan 28 07:02:11 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Tue Jan 28 07:03:08 2014 +0530
----------------------------------------------------------------------
.../resource/HypervDirectConnectResource.java | 62 ++++----------------
1 file changed, 12 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/39447cce/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index e9647ad..2f64590 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -36,13 +36,13 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import javax.annotation.PostConstruct;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
@@ -1120,73 +1120,35 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd));
}
- String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd);
+ Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
+ data.put(cmd.getVmIpAddress(), cmd.getVmData());
- String vmIpAddress = cmd.getVmIpAddress();
- List<String[]> vmData = cmd.getVmData();
- String[] vmDataArgs = new String[vmData.size() * 2 + 4];
- vmDataArgs[0] = "routerIP";
- vmDataArgs[1] = routerPrivateIpAddress;
- vmDataArgs[2] = "vmIP";
- vmDataArgs[3] = vmIpAddress;
- int i = 4;
- for (String[] vmDataEntry : vmData) {
- String folder = vmDataEntry[0];
- String file = vmDataEntry[1];
- String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none";
+ String json = new Gson().toJson(data);
+ s_logger.debug("VM data JSON IS:" + json);
- vmDataArgs[i] = folder + "," + file;
- vmDataArgs[i + 1] = contents;
- i += 2;
- }
+ json = Base64.encodeBase64String(json.getBytes());
- String content = encodeDataArgs(vmDataArgs);
- String tmpFileName = UUID.randomUUID().toString();
-
- if (s_logger.isDebugEnabled()) {
- s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content);
- }
+ String args = "-d " + json;
try {
- SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null);
-
- try {
- Pair<Boolean, String> result =
- SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/userdata.py " + tmpFileName);
-
- if (!result.first()) {
- s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second());
- return new Answer(cmd, false, "VmDataCommand failed due to " + result.second());
- }
- } finally {
-
- SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName);
+ Pair<Boolean, String> result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args);
+ if (!result.first()) {
+ s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second());
+ return new Answer(cmd, false, "VmDataCommand failed due to " + result.second());
}
if (s_logger.isInfoEnabled()) {
s_logger.info("vm_data command on domain router " + controlIp + " completed");
}
-
} catch (Throwable e) {
- String msg = "VmDataCommand failed due to " + e;
+ String msg = "VmDataCommand failed due to " + e.getMessage();
s_logger.error(msg, e);
return new Answer(cmd, false, msg);
}
return new Answer(cmd);
}
- private String encodeDataArgs(String[] dataArgs) {
- StringBuilder sb = new StringBuilder();
-
- for (String arg : dataArgs) {
- sb.append(arg);
- sb.append("\n");
- }
-
- return sb.toString();
- }
-
protected Answer execute(DhcpEntryCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd));
[2/3] git commit: updated refs/heads/master to 39447cc
Posted by ra...@apache.org.
CLOUDSTACK-5821 systemvmiso is locked by systevmvm in hyperv
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7ac48934
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7ac48934
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7ac48934
Branch: refs/heads/master
Commit: 7ac48934f77c3b9a72c05300163088a4c198ebf2
Parents: 807dc09
Author: Rajesh Battala <ra...@citrix.com>
Authored: Tue Jan 28 06:42:54 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Tue Jan 28 07:03:08 2014 +0530
----------------------------------------------------------------------
systemvm/patches/debian/config/etc/init.d/cloud-early-config | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7ac48934/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
index d6dc8f0..df80a28 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -135,7 +135,7 @@ get_boot_params() {
virtualpc|hyperv)
# Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon
#waiting for the hv_kvp_daemon to start up
- #sleep 30 need to fix the race condition of hv_kvp_daemon and cloud-early-config
+ #sleep need to fix the race condition of hv_kvp_daemon and cloud-early-config
sleep 5
cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline
cat /dev/null > /var/opt/hyperv/.kvp_pool_0
@@ -1211,6 +1211,10 @@ start() {
patch_log4j
parse_cmd_line
change_password
+ if [ "$hyp" == "hyperv" ]; then
+ # eject the systemvm.iso
+ eject
+ fi
case $TYPE in
router)
[ "$NAME" == "" ] && NAME=router
[3/3] git commit: updated refs/heads/master to 39447cc
Posted by ra...@apache.org.
CLOUDSTACK-5561 Support of multiple public vlans on VR running in HyperV
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/807dc091
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/807dc091
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/807dc091
Branch: refs/heads/master
Commit: 807dc091382fbf6fbd4b8fc53e7cdb414078ea2e
Parents: ce0dc3b
Author: Rajesh Battala <ra...@citrix.com>
Authored: Tue Jan 28 06:40:47 2014 +0530
Committer: Rajesh Battala <ra...@citrix.com>
Committed: Tue Jan 28 07:03:08 2014 +0530
----------------------------------------------------------------------
.../com/cloud/agent/api/GetVmConfigAnswer.java | 68 +++++
.../com/cloud/agent/api/GetVmConfigCommand.java | 46 ++++
.../agent/api/ModifyVmNicConfigAnswer.java | 36 +++
.../agent/api/ModifyVmNicConfigCommand.java | 42 +++
.../DotNet/ServerResource/AgentShell/App.config | 2 +-
.../HypervResource/CloudStackTypes.cs | 18 ++
.../HypervResource/HypervResourceController.cs | 100 +++++++
.../HypervResource/IWmiCallsV2.cs | 1 +
.../ServerResource/HypervResource/WmiCallsV2.cs | 62 +++++
.../hypervisor/hyperv/guru/HypervGuru.java | 113 ++++++++
.../hyperv/manager/HypervManager.java | 1 +
.../hyperv/manager/HypervManagerImpl.java | 20 +-
.../resource/HypervDirectConnectResource.java | 258 ++++++++++++++-----
.../VirtualNetworkApplianceManagerImpl.java | 2 +-
.../debian/config/opt/cloud/bin/ipassoc.sh | 3 +-
15 files changed, 697 insertions(+), 75 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
new file mode 100644
index 0000000..46e003e
--- /dev/null
+++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java
@@ -0,0 +1,68 @@
+// 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 GetVmConfigAnswer extends Answer {
+
+ String vmName;
+ List<NicDetails> nics;
+
+ protected GetVmConfigAnswer() {
+ }
+
+ public GetVmConfigAnswer(String vmName, List<NicDetails> nics) {
+ this.vmName = vmName;
+ this.nics = nics;
+ }
+
+ public String getVmName() {
+ return vmName;
+ }
+
+ public List<NicDetails> getNics() {
+ return nics;
+ }
+
+ public class NicDetails {
+ String macAddress;
+ int vlanid;
+
+ public NicDetails() {
+ }
+
+ public NicDetails(String macAddress, int vlanid) {
+ this.macAddress = macAddress;
+ this.vlanid = vlanid;
+ }
+
+ public String getMacAddress() {
+ return macAddress;
+ }
+
+ public int getVlanid() {
+ return vlanid;
+ }
+
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/core/src/com/cloud/agent/api/GetVmConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetVmConfigCommand.java b/core/src/com/cloud/agent/api/GetVmConfigCommand.java
new file mode 100644
index 0000000..9133bd6
--- /dev/null
+++ b/core/src/com/cloud/agent/api/GetVmConfigCommand.java
@@ -0,0 +1,46 @@
+// 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;
+
+import com.cloud.agent.api.to.NicTO;
+
+public class GetVmConfigCommand extends Command {
+ String vmName;
+ List<NicTO> nics;
+ protected GetVmConfigCommand() {
+ }
+
+ public GetVmConfigCommand(String vmName) {
+ this.vmName = vmName;
+ }
+
+ public String getVmName() {
+ return vmName;
+ }
+
+ public void setNics(List<NicTO> nics){
+ this.nics = nics;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
new file mode 100644
index 0000000..1140485
--- /dev/null
+++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java
@@ -0,0 +1,36 @@
+// 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;
+
+public class ModifyVmNicConfigAnswer extends Answer {
+ String vmName;
+ protected ModifyVmNicConfigAnswer() {
+ }
+
+ public ModifyVmNicConfigAnswer(String vmName) {
+ this.vmName = vmName;
+ }
+
+ public String getVmName() {
+ return vmName;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
new file mode 100644
index 0000000..0230bec
--- /dev/null
+++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java
@@ -0,0 +1,42 @@
+// 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;
+
+
+public class ModifyVmNicConfigCommand extends Command {
+ String vmName;
+ int vlan;
+ String macAddress;
+ protected ModifyVmNicConfigCommand() {
+ }
+
+ public ModifyVmNicConfigCommand(String vmName, int vlan, String macAddress) {
+ this.vmName = vmName;
+ this.vlan = vlan;
+ this.macAddress = macAddress;
+ }
+
+ public String getVmName() {
+ return vmName;
+ }
+
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config
index b783dfe..3ec08bd 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config
@@ -96,7 +96,7 @@
<value>2048</value>
</setting>
<setting name="private_ip_address" serializeAs="String">
- <value>10.102.192.150</value>
+ <value>0.0.0.0</value>
</setting>
</CloudStack.Plugin.AgentShell.AgentSettings>
</applicationSettings>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
index d54295c..c336a38 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs
@@ -690,6 +690,20 @@ namespace HypervResource
public String entityType;
}
+ public class NicDetails
+ {
+ [JsonProperty("macAddress")]
+ public string macaddress;
+ [JsonProperty("vlanid")]
+ public int vlanid;
+ public NicDetails() { }
+ public NicDetails(String macaddress, int vlanid)
+ {
+ this.macaddress = macaddress;
+ this.vlanid = vlanid;
+ }
+ }
+
/// <summary>
/// Fully qualified named for a number of types used in CloudStack. Used to specify the intended type for JSON serialised objects.
/// </summary>
@@ -738,6 +752,10 @@ namespace HypervResource
public const string GetVmDiskStatsCommand = "com.cloud.agent.api.GetVmDiskStatsCommand";
public const string GetVmStatsAnswer = "com.cloud.agent.api.GetVmStatsAnswer";
public const string GetVmStatsCommand = "com.cloud.agent.api.GetVmStatsCommand";
+ public const string GetVmConfigCommand = "com.cloud.agent.api.GetVmConfigCommand";
+ public const string GetVmConfigAnswer = "com.cloud.agent.api.GetVmConfigAnswer";
+ public const string ModifyVmNicConfigCommand = "com.cloud.agent.api.ModifyVmNicConfigCommand";
+ public const string ModifyVmNicConfigAnswer = "com.cloud.agent.api.ModifyVmNicConfigAnswer";
public const string GetVncPortAnswer = "com.cloud.agent.api.GetVncPortAnswer";
public const string GetVncPortCommand = "com.cloud.agent.api.GetVncPortCommand";
public const string HostStatsEntry = "com.cloud.agent.api.HostStatsEntry";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
index f7787c3..ebb3bce 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs
@@ -982,6 +982,24 @@ namespace HypervResource
return true;
}
+ // POST api/HypervResource/PlugNicCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.PlugNicCommand)]
+ public JContainer PlugNicCommand([FromBody]dynamic cmd)
+ {
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
+ logger.Info(CloudStackTypes.PlugNicCommand + cmd.ToString());
+ object ansContent = new
+ {
+ result = true,
+ details = "instead of plug, change he network settings",
+ contextMap = contextMap
+ };
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer);
+ }
+ }
+
// POST api/HypervResource/CleanupNetworkRulesCmd
[HttpPost]
@@ -1264,6 +1282,88 @@ namespace HypervResource
}
}
+ // POST api/HypervResource/ModifyVmVnicVlanCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.ModifyVmNicConfigCommand)]
+ public JContainer ModifyVmNicConfigCommand([FromBody]dynamic cmd)
+ {
+
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
+ logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + cmd.ToString());
+ bool result = false;
+ String vmName = cmd.vmName;
+ uint vlan = (uint)cmd.vlan;
+ string macAddress = cmd.macAddress;
+ wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress);
+
+ result = true;
+
+ object ansContent = new
+ {
+ vmName = vmName,
+ result = result,
+ contextMap = contextMap
+ };
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyVmNicConfigAnswer);
+ }
+
+ }
+
+ // POST api/HypervResource/GetVmConfigCommand
+ [HttpPost]
+ [ActionName(CloudStackTypes.GetVmConfigCommand)]
+ public JContainer GetVmConfigCommand([FromBody]dynamic cmd)
+ {
+ using (log4net.NDC.Push(Guid.NewGuid().ToString()))
+ {
+ logger.Info(CloudStackTypes.GetVmConfigCommand + cmd.ToString());
+ bool result = false;
+ String vmName = cmd.vmName;
+ ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName);
+ List<NicDetails> nicDetails = new List<NicDetails>();
+ var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm);
+ NicDetails nic = null;
+ String[] macAddress = new String[nicSettingsViaVm.Length];
+ int index = 0;
+ foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
+ {
+ macAddress[index++] = item.Address;
+ }
+
+ index = 0;
+ var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm);
+ int vlanid = 1;
+ foreach (EthernetPortAllocationSettingData item in ethernetConnections)
+ {
+ EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item);
+ if (vlanSettings == null)
+ {
+ vlanid = -1;
+ }
+ else
+ {
+ vlanid = vlanSettings.AccessVlanId;
+ }
+ nic = new NicDetails(macAddress[index++], vlanid);
+ nicDetails.Add(nic);
+ }
+
+ result = true;
+
+ object ansContent = new
+ {
+ vmName = vmName,
+ nics = nicDetails,
+ result = result,
+ contextMap = contextMap
+ };
+ return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmConfigAnswer);
+ }
+ }
+
+
+
// POST api/HypervResource/GetVmStatsCommand
[HttpPost]
[ActionName(CloudStackTypes.GetVmStatsCommand)]
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
index 5f814c5..9042d7c 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs
@@ -66,5 +66,6 @@ namespace HypervResource
void patchSystemVmIso(string vmName, string systemVmIso);
void SetState(ComputerSystem vm, ushort requiredState);
Dictionary<String, VmState> GetVmSync(String privateIpAddress);
+ void ModifyVmVLan(string vmName, uint vlanid, string mac);
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
index 2e3aca5..b9694f0 100644
--- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
+++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs
@@ -443,6 +443,7 @@ namespace HypervResource
nicCount++;
}
+
// pass the boot args for the VM using KVP component.
// We need to pass the boot args to system vm's to get them configured with cloudstack configuration.
// Add new user data
@@ -909,6 +910,37 @@ namespace HypervResource
return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone());
}
+
+ // Modify the systemvm nic's VLAN id
+ public void ModifyVmVLan(string vmName, uint vlanid, String mac)
+ {
+ ComputerSystem vm = GetComputerSystem(vmName);
+ SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm);
+ // Obtain controller for Hyper-V virtualisation subsystem
+ VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService();
+ string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' })));
+ int index = 0;
+ foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm)
+ {
+ if (normalisedMAC.ToLower().Equals(item.Address.ToLower()))
+ {
+ break;
+ }
+ index++;
+ }
+
+ //TODO: make sure the index wont be out of range.
+
+ EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm);
+ EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]);
+
+ //Assign configuration to new NIC
+ vlanSettings.LateBoundObject["AccessVlanId"] = vlanid;
+ vlanSettings.LateBoundObject["OperationMode"] = 1;
+ ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] {
+ vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)});
+ }
+
public void AttachIso(string displayName, string iso)
{
logger.DebugFormat("Got request to attach iso {0} to vm {1}", iso, displayName);
@@ -1420,6 +1452,36 @@ namespace HypervResource
return vSwitch;
}
+
+ private static void ModifyFeatureVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings)
+ {
+ // Resource settings are changed through the management service
+ System.Management.ManagementPath jobPath;
+ System.Management.ManagementPath[] results;
+
+ var ret_val = vmMgmtSvc.ModifyFeatureSettings(
+ resourceSettings,
+ out jobPath,
+ out results);
+
+ // If the Job is done asynchronously
+ if (ret_val == ReturnCode.Started)
+ {
+ JobCompleted(jobPath);
+ }
+ else if (ret_val != ReturnCode.Completed)
+ {
+ var errMsg = string.Format(
+ "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted",
+ vm.ElementName,
+ vm.Name,
+ ReturnCode.ToString(ret_val));
+ var ex = new WmiException(errMsg);
+ logger.Error(errMsg, ex);
+ throw ex;
+ }
+ }
+
private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings)
{
// Resource settings are changed through the management service
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
index 5845038..1d9e7f6 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java
@@ -16,15 +16,30 @@
// under the License.
package com.cloud.hypervisor.hyperv.guru;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
import javax.ejb.Local;
import javax.inject.Inject;
+import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruBase;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.hypervisor.hyperv.manager.HypervManager;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
/**
@@ -35,6 +50,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject
private GuestOSDao _guestOsDao;
+ @Inject HypervManager _hypervMgr;
+ @Inject NetworkDao _networkDao;
+ @Inject NetworkModel _networkMgr;
@Override
public final HypervisorType getHypervisorType() {
@@ -51,6 +69,78 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
@Override
public final VirtualMachineTO implement(VirtualMachineProfile vm) {
VirtualMachineTO to = toVirtualMachineTO(vm);
+ List<NicProfile> nicProfiles = vm.getNics();
+
+ if(vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) {
+
+ NicProfile publicNicProfile = null;
+ for(NicProfile nicProfile : nicProfiles) {
+ if(nicProfile.getTrafficType() == TrafficType.Public) {
+ publicNicProfile = nicProfile;
+ break;
+ }
+ }
+
+ if(publicNicProfile != null) {
+ NicTO[] nics = to.getNics();
+
+ // reserve extra NICs
+ NicTO[] expandedNics = new NicTO[nics.length + _hypervMgr.getRouterExtraPublicNics()];
+ int i = 0;
+ int deviceId = -1;
+ for(i = 0; i < nics.length; i++) {
+ expandedNics[i] = nics[i];
+ if(nics[i].getDeviceId() > deviceId)
+ deviceId = nics[i].getDeviceId();
+ }
+ deviceId++;
+
+ long networkId = publicNicProfile.getNetworkId();
+ NetworkVO network = _networkDao.findById(networkId);
+
+ for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) {
+ NicTO nicTo = new NicTO();
+ nicTo.setDeviceId(deviceId++);
+ nicTo.setBroadcastType(publicNicProfile.getBroadcastType());
+ nicTo.setType(publicNicProfile.getTrafficType());
+ nicTo.setIp("0.0.0.0");
+ nicTo.setNetmask("255.255.255.255");
+ nicTo.setName(publicNicProfile.getName());
+
+ try {
+ String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId);
+ nicTo.setMac(mac);
+ } catch (InsufficientAddressCapacityException e) {
+ throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId);
+ }
+ nicTo.setDns1(publicNicProfile.getDns1());
+ nicTo.setDns2(publicNicProfile.getDns2());
+ if (publicNicProfile.getGateway() != null) {
+ nicTo.setGateway(publicNicProfile.getGateway());
+ } else {
+ nicTo.setGateway(network.getGateway());
+ }
+ nicTo.setDefaultNic(false);
+ nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri());
+ nicTo.setIsolationuri(publicNicProfile.getIsolationUri());
+
+ Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null);
+ nicTo.setNetworkRateMbps(networkRate);
+
+ expandedNics[i] = nicTo;
+ }
+ to.setNics(expandedNics);
+ }
+
+ StringBuffer sbMacSequence = new StringBuffer();
+ for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) {
+ sbMacSequence.append(nicTo.getMac()).append("|");
+ }
+ sbMacSequence.deleteCharAt(sbMacSequence.length() - 1);
+ String bootArgs = to.getBootArgs();
+ to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString());
+
+ }
// Determine the VM's OS description
GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
@@ -59,6 +149,29 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru {
return to;
}
+ private NicTO[] sortNicsByDeviceId(NicTO[] nics) {
+
+ List<NicTO> listForSort = new ArrayList<NicTO>();
+ for (NicTO nic : nics) {
+ listForSort.add(nic);
+ }
+ Collections.sort(listForSort, new Comparator<NicTO>() {
+
+ @Override
+ public int compare(NicTO arg0, NicTO arg1) {
+ if (arg0.getDeviceId() < arg1.getDeviceId()) {
+ return -1;
+ } else if (arg0.getDeviceId() == arg1.getDeviceId()) {
+ return 0;
+ }
+
+ return 1;
+ }
+ });
+
+ return listForSort.toArray(new NicTO[0]);
+ }
+
@Override
public final boolean trackVmHostChange() {
return false;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java
index 9030e29..5821fe4 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java
@@ -21,4 +21,5 @@ import com.cloud.utils.component.Manager;
public interface HypervManager extends Manager {
public String prepareSecondaryStorageStore(long zoneId);
+ int getRouterExtraPublicNics();
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
index a30eb7d..71a619a 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java
@@ -45,6 +45,8 @@ import com.cloud.utils.NumbersUtil;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
@Local(value = {HypervManager.class})
public class HypervManagerImpl implements HypervManager {
@@ -60,10 +62,11 @@ public class HypervManagerImpl implements HypervManager {
Map<String, String> _storageMounts = new HashMap<String, String>();
StorageLayer _storage;
- @Inject
- ConfigurationDao _configDao;
- @Inject
- DataStoreManager _dataStoreMgr;
+ @Inject ConfigurationDao _configDao;
+ @Inject DataStoreManager _dataStoreMgr;
+ @Inject VMInstanceDao _vminstanceDao;
+ @Inject NicDao _nicDao;
+ int _routerExtraPublicNics = 2;
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -77,7 +80,7 @@ public class HypervManagerImpl implements HypervManager {
_storage = new JavaStorageLayer();
_storage.configure("StorageLayer", params);
}
-
+ _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2);
return true;
}
@@ -373,4 +376,9 @@ public class HypervManagerImpl implements HypervManager {
}
}
}
-}
+
+ @Override
+ public int getRouterExtraPublicNics() {
+ return _routerExtraPublicNics;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
index d6ffa1d..e9647ad 100644
--- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
+++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java
@@ -71,7 +71,12 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.GetDomRVersionAnswer;
import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.GetVmConfigAnswer;
+import com.cloud.agent.api.GetVmConfigAnswer.NicDetails;
+import com.cloud.agent.api.GetVmConfigCommand;
import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.ModifyVmNicConfigAnswer;
+import com.cloud.agent.api.ModifyVmNicConfigCommand;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.PingCommand;
@@ -117,11 +122,13 @@ import com.cloud.agent.api.to.PortForwardingRuleTO;
import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.exception.InternalErrorException;
import com.cloud.host.Host.Type;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.hyperv.manager.HypervManager;
import com.cloud.network.HAProxyConfigurator;
import com.cloud.network.LoadBalancerConfigurator;
+import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.RouterPrivateIpStrategy;
import com.cloud.network.rules.FirewallRule;
import com.cloud.resource.ServerResource;
@@ -133,6 +140,8 @@ import com.cloud.utils.net.NetUtils;
import com.cloud.utils.ssh.SshHelper;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineName;
+
+
/**
* Implementation of dummy resource to be returned from discoverer.
**/
@@ -706,65 +715,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
}
}
- //
- // find mac address of a specified ethx device
- // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
- // returns
- // eth0:xx.xx.xx.xx
-
- //
- // list IP with eth devices
- // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
- // | awk -F: '{ print $1 ": " $3 }'
- //
- // returns
- // eth0:xx.xx.xx.xx
- //
- //
-
- private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception {
-
- s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
-
- // TODO : this is a temporary very inefficient solution, will refactor it later
- Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "ls /proc/sys/net/ipv4/conf");
-
- // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
- // we use a waiting loop here as a workaround to synchronize activities in systems
- long startTick = System.currentTimeMillis();
- while (System.currentTimeMillis() - startTick < 15000) {
- if (result.first()) {
- String[] tokens = result.second().split("\\s+");
- for (String token : tokens) {
- if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
- String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
-
- if (s_logger.isDebugEnabled())
- s_logger.debug("Run domr script " + cmd);
- Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
- // TODO need to find the dev index inside router based on IP address
- cmd);
- if (s_logger.isDebugEnabled())
- s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
-
- if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim()))
- return Integer.parseInt(token.substring(3));
- }
- }
- }
-
- s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
-
- try {
- Thread.currentThread();
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- }
-
- return -1;
- }
-
protected Answer execute(SetPortForwardingRulesCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd));
@@ -1170,7 +1120,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd));
}
-
String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
String controlIp = getRouterSshControlIp(cmd);
@@ -1386,6 +1335,102 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
return new Answer(cmd);
}
+ //
+ // find mac address of a specified ethx device
+ // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2
+ // returns
+ // eth0:xx.xx.xx.xx
+
+ //
+ // list IP with eth devices
+ // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }'
+ // | awk -F: '{ print $1 ": " $3 }'
+ //
+ // returns
+ // eth0:xx.xx.xx.xx
+ //
+ //
+
+ private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception {
+
+ s_logger.info("findRouterEthDeviceIndex. mac: " + mac);
+
+ // TODO : this is a temporary very inefficient solution, will refactor it later
+ Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+ "ls /proc/sys/net/ipv4/conf");
+
+ // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
+ // we use a waiting loop here as a workaround to synchronize activities in systems
+ long startTick = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTick < 15000) {
+ if (result.first()) {
+ String[] tokens = result.second().split("\\s+");
+ for (String token : tokens) {
+ if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
+ String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+
+ if (s_logger.isDebugEnabled())
+ s_logger.debug("Run domr script " + cmd);
+ Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+ // TODO need to find the dev index inside router based on IP address
+ cmd);
+ if (s_logger.isDebugEnabled())
+ s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
+
+ if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim()))
+ return Integer.parseInt(token.substring(3));
+ }
+ }
+ }
+
+ s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry...");
+
+ }
+
+ return -1;
+ }
+
+ private Pair<Integer, String> findRouterFreeEthDeviceIndex(String routerIp) throws Exception {
+
+ s_logger.info("findRouterFreeEthDeviceIndex. mac: ");
+
+ // TODO : this is a temporary very inefficient solution, will refactor it later
+ Pair<Boolean, String> result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+ "ip address | grep DOWN| cut -f2 -d :");
+
+ // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS
+ // we use a waiting loop here as a workaround to synchronize activities in systems
+ long startTick = System.currentTimeMillis();
+ while (System.currentTimeMillis() - startTick < 15000) {
+ if (result.first() && !result.second().isEmpty()) {
+ String[] tokens = result.second().split("\\n");
+ for (String token : tokens) {
+ if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) {
+ //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+ //TODO: don't check for eth0,1,2, as they will be empty by default.
+ //String cmd = String.format("ip address show %s ", token);
+ String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token);
+ if (s_logger.isDebugEnabled())
+ s_logger.debug("Run domr script " + cmd);
+ Pair<Boolean, String> result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null,
+ // TODO need to find the dev index inside router based on IP address
+ cmd);
+ if (s_logger.isDebugEnabled())
+ s_logger.debug("result: " + result2.first() + ", output: " + result2.second());
+
+ if (result2.first() && result2.second().trim().length() > 0)
+ return new Pair<Integer, String>(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ;
+ }
+ }
+ }
+
+ //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry...");
+
+ }
+
+ return new Pair<Integer, String>(-1, "");
+ }
+
protected Answer execute(IpAssocCommand cmd) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd));
@@ -1401,7 +1446,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
String controlIp = getRouterSshControlIp(cmd);
for (IpAddressTO ip : ips) {
assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(),
- ip.getVlanNetmask(), ip.getVifMacAddress());
+ ip.getVlanNetmask(), ip.getVifMacAddress());
results[i++] = ip.getPublicIp() + " - success";
}
@@ -1419,16 +1464,97 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
return new IpAssocAnswer(cmd, results);
}
+ protected int getVmNics(String vmName, int vlanid) {
+ GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName);
+ URI agentUri = null;
+ int nicposition = -1;
+ try {
+ String cmdName = GetVmConfigCommand.class.getName();
+ agentUri =
+ new URI("https", null, _agentIp, _port,
+ "/api/HypervResource/" + cmdName, null, null);
+ } catch (URISyntaxException e) {
+ String errMsg = "Could not generate URI for Hyper-V agent";
+ s_logger.error(errMsg, e);
+ }
+ String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri);
+ Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+ s_logger.debug("executeRequest received response "
+ + s_gson.toJson(result));
+ if (result.length > 0) {
+ GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]);
+ List<NicDetails> nics = ans.getNics();
+ for (NicDetails nic : nics) {
+ if (nic.getVlanid() == vlanid) {
+ nicposition = nics.indexOf(nic);
+ break;
+ }
+ }
+ }
+ return nicposition;
+ }
+
+ protected void modifyNicVlan(String vmName, int vlanId, String macAddress) {
+ ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress);
+ URI agentUri = null;
+ try {
+ String cmdName = ModifyVmNicConfigCommand.class.getName();
+ agentUri =
+ new URI("https", null, _agentIp, _port,
+ "/api/HypervResource/" + cmdName, null, null);
+ } catch (URISyntaxException e) {
+ String errMsg = "Could not generate URI for Hyper-V agent";
+ s_logger.error(errMsg, e);
+ }
+ String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri);
+ Answer[] result = s_gson.fromJson(ansStr, Answer[].class);
+ s_logger.debug("executeRequest received response "
+ + s_gson.toJson(result));
+ if (result.length > 0) {
+ ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]);
+ }
+ }
+
protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP,
- final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
+ final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception {
+
+ URI broadcastUri = BroadcastDomainType.fromString(broadcastId);
+ if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) {
+ throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId);
+ }
+ int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri));
+
+ int publicNicInfo = -1;
+ publicNicInfo = getVmNics(vmName, vlanId);
boolean addVif = false;
- if (add) {
+ if (add && publicNicInfo == -1) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress);
}
addVif = true;
} else if (!add && firstIP) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unplug NIC " + publicNicInfo);
+ }
+ }
+
+ if (addVif) {
+ Pair<Integer, String> nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress);
+ publicNicInfo = nicdevice.first();
+ if (publicNicInfo > 0) {
+ modifyNicVlan(vmName, vlanId, nicdevice.second());
+ // After modifying the vnic on VR, check the VR VNics config in the host and get the device position
+ publicNicInfo = getVmNics(vmName, vlanId);
+ // As a new nic got activated in the VR. add the entry in the NIC's table.
+ networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo);
+ }
+ else {
+ // we didn't find any eth device available in VR to configure the ip range with new VLAN
+ String msg = "No Nic is available on DomR VIF to associate/disassociate IP with.";
+ s_logger.error(msg);
+ throw new InternalErrorException(msg);
+ }
}
String args = null;
@@ -1450,8 +1576,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
args += publicIpAddress + "/" + cidrSize;
args += " -c ";
- args += "eth" + "2"; // currently hardcoding to eth 2 (which is default public ipd)//publicNicInfo.first();
+ args += "eth" + publicNicInfo;
args += " -g ";
args += vlanGateway;
@@ -1464,7 +1590,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
}
Pair<Boolean, String> result =
- SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args);
+ SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args);
if (!result.first()) {
s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second());
@@ -1840,7 +1966,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S
sch.connect(addr);
return null;
} catch (IOException e) {
- s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString());
+ s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString());
if (e instanceof ConnectException) {
// if connection is refused because of VM is being started,
// we give it more sleep time
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 13291d0..bf2516a 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -2125,7 +2125,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
buf.append(" dnssearchorder=").append(domain_suffix);
}
- if (profile.getHypervisorType() == HypervisorType.VMware) {
+ if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) {
buf.append(" extra_pubnics=" + _routerExtraPublicNics);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/807dc091/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh
index ae2d7e4..2a9d780 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh
+++ b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh
@@ -254,10 +254,11 @@ remove_first_ip() {
if [ $? -gt 0 -a $? -ne 2 ]
then
remove_routing $1
+ sudo ip link set $ethDev down
return 1
fi
remove_routing $1
-
+ sudo ip link set $ethDev down
return $?
}