mirror of https://github.com/apache/cloudstack.git
CS-14956 Support for rate limiting policies in Nexus dvSwith feature for CloudStack
Reviewed-by: Devdeep Conflicts: vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
This commit is contained in:
parent
7cf04c1fe4
commit
ab768f03fd
|
|
@ -10,8 +10,8 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.hypervisor.vmware.mo;
|
||||
|
||||
package com.cloud.hypervisor.vmware.mo;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
|
@ -26,6 +26,8 @@ import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
|||
import com.cloud.utils.ActionDelegate;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.PolicyMap;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.PortProfile;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.BindingType;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.OperationType;
|
||||
import com.cloud.utils.cisco.n1kv.vsm.VsmCommand.PortProfileType;
|
||||
|
|
@ -59,7 +61,8 @@ import com.vmware.vim25.VirtualSCSISharing;
|
|||
|
||||
public class HypervisorHostHelper {
|
||||
private static final Logger s_logger = Logger.getLogger(HypervisorHostHelper.class);
|
||||
private static final int DEFAULT_LOCK_TIMEOUT_SECONDS = 600;
|
||||
private static final int DEFAULT_LOCK_TIMEOUT_SECONDS = 600;
|
||||
private static final String s_policyNamePrefix = "cloud.policy.";
|
||||
|
||||
// make vmware-base loosely coupled with cloud-specific stuff, duplicate VLAN.UNTAGGED constant here
|
||||
private static final String UNTAGGED_VLAN_NAME = "untagged";
|
||||
|
|
@ -109,7 +112,7 @@ public class HypervisorHostHelper {
|
|||
return "cloud.public." + vlanId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String composeCloudNetworkName(String prefix, String vlanId, Integer networkRateMbps, String vSwitchName) {
|
||||
StringBuffer sb = new StringBuffer(prefix);
|
||||
if(vlanId == null || UNTAGGED_VLAN_NAME.equalsIgnoreCase(vlanId))
|
||||
|
|
@ -129,43 +132,71 @@ public class HypervisorHostHelper {
|
|||
|
||||
public static Map<String, String> getValidatedVsmCredentials(VmwareContext context) throws Exception {
|
||||
Map<String, String> vsmCredentials = context.getStockObject("vsmcredentials");
|
||||
String msg;
|
||||
if(vsmCredentials == null || vsmCredentials.size() != 3) {
|
||||
msg = "Failed to retrieve required credentials of Nexus VSM from database.";
|
||||
s_logger.error(msg);
|
||||
String msg;
|
||||
if (vsmCredentials == null || vsmCredentials.size() != 3) {
|
||||
msg = "Failed to retrieve required credentials of Nexus VSM from database.";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
String vsmIp = vsmCredentials.containsKey("vsmip") ? vsmCredentials.get("vsmip") : null;
|
||||
String vsmUserName = vsmCredentials.containsKey("vsmusername") ? vsmCredentials.get("vsmusername") : null;
|
||||
String vsmPassword = vsmCredentials.containsKey("vsmpassword") ? vsmCredentials.get("vsmpassword") : null;
|
||||
if(vsmIp == null || vsmIp.isEmpty() || vsmUserName == null || vsmUserName.isEmpty() || vsmPassword == null || vsmPassword.isEmpty()) {
|
||||
msg = "Detected invalid credentials for Nexus VSM";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
return vsmCredentials;
|
||||
}
|
||||
|
||||
public static void createPortProfile(VmwareContext context, String ethPortProfileName, String networkName, Integer vlanId, Integer networkRateMbps) throws Exception {
|
||||
Map<String, String> vsmCredentials = getValidatedVsmCredentials(context);
|
||||
String vsmIp = vsmCredentials.get("vsmip");
|
||||
String vsmUserName = vsmCredentials.get("vsmusername");
|
||||
String vsmPassword = vsmCredentials.get("vsmpassword");
|
||||
String msg;
|
||||
|
||||
NetconfHelper netconfClient;
|
||||
try {
|
||||
s_logger.info("Connecting to Nexus VSM : " + vsmIp);
|
||||
netconfClient = new NetconfHelper(vsmIp, vsmUserName, vsmPassword);
|
||||
s_logger.info("Successfully connected to Nexus VSM : " + vsmIp);
|
||||
} catch(CloudRuntimeException e) {
|
||||
msg = "Failed to connect to Nexus VSM " + vsmIp + " with credentials of user " + vsmUserName;
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
|
||||
String vsmIp = vsmCredentials.containsKey("vsmip") ? vsmCredentials.get("vsmip") : null;
|
||||
String vsmUserName = vsmCredentials.containsKey("vsmusername") ? vsmCredentials.get("vsmusername") : null;
|
||||
String vsmPassword = vsmCredentials.containsKey("vsmpassword") ? vsmCredentials.get("vsmpassword") : null;
|
||||
if (vsmIp == null || vsmIp.isEmpty() || vsmUserName == null || vsmUserName.isEmpty() || vsmPassword == null
|
||||
|| vsmPassword.isEmpty()) {
|
||||
msg = "Detected invalid credentials for Nexus 1000v.";
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
return vsmCredentials;
|
||||
}
|
||||
|
||||
public static void createPortProfile(VmwareContext context, String ethPortProfileName, String networkName,
|
||||
Integer vlanId, Integer networkRateMbps, long peakBandwidth, long burstSize) throws Exception {
|
||||
Map<String, String> vsmCredentials = getValidatedVsmCredentials(context);
|
||||
String vsmIp = vsmCredentials.get("vsmip");
|
||||
String vsmUserName = vsmCredentials.get("vsmusername");
|
||||
String vsmPassword = vsmCredentials.get("vsmpassword");
|
||||
String msg;
|
||||
|
||||
NetconfHelper netconfClient;
|
||||
try {
|
||||
s_logger.info("Connecting to Nexus 1000v: " + vsmIp);
|
||||
netconfClient = new NetconfHelper(vsmIp, vsmUserName, vsmPassword);
|
||||
s_logger.info("Successfully connected to Nexus 1000v : " + vsmIp);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to connect to Nexus 1000v " + vsmIp + " with credentials of user " + vsmUserName
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
String policyName = s_policyNamePrefix;
|
||||
int averageBandwidth = 0;
|
||||
if (networkRateMbps != null) {
|
||||
averageBandwidth = networkRateMbps.intValue();
|
||||
policyName += averageBandwidth;
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO(sateesh): Change the type of peakBandwidth & burstRate in
|
||||
// PolicyMap to long.
|
||||
if (averageBandwidth > 0) {
|
||||
s_logger.debug("Adding policy map " + policyName);
|
||||
netconfClient.addPolicyMap(policyName, averageBandwidth, (int) peakBandwidth, (int) burstSize);
|
||||
}
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to add policy map of " + policyName + " with parameters " + "committed rate = "
|
||||
+ averageBandwidth + "peak bandwidth = " + peakBandwidth + "burst size = " + burstSize
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
|
||||
List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
|
||||
if (vlanId != null) {
|
||||
// No need to update ethernet port profile for untagged vlans
|
||||
params.add(new Pair<OperationType, String>(OperationType.addvlanid, vlanId.toString()));
|
||||
|
|
@ -174,17 +205,17 @@ public class HypervisorHostHelper {
|
|||
netconfClient.updatePortProfile(ethPortProfileName, SwitchPortMode.trunk, params);
|
||||
s_logger.info("Added " + vlanId + " to Ethernet port profile " + ethPortProfileName);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to modify ethernet port profile " + ethPortProfileName + " with parameters " + params.toString();
|
||||
msg = "Failed to update Ethernet port profile " + ethPortProfileName + " with VLAN " + vlanId
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if(netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected VSM session.");
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
if (vlanId == null) {
|
||||
s_logger.info("Adding port profile configured over untagged VLAN.");
|
||||
netconfClient.addPortProfile(networkName, PortProfileType.vethernet, BindingType.portbindingstatic, SwitchPortMode.access, 0);
|
||||
|
|
@ -192,61 +223,150 @@ public class HypervisorHostHelper {
|
|||
s_logger.info("Adding port profile configured over VLAN : " + vlanId.toString());
|
||||
netconfClient.addPortProfile(networkName, PortProfileType.vethernet, BindingType.portbindingstatic, SwitchPortMode.access, vlanId.intValue());
|
||||
}
|
||||
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to add vEthernet port profile " + networkName + ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if(vlanId == null) {
|
||||
s_logger.warn("Ignoring exception : " + e.toString());
|
||||
// throw new CloudRuntimeException(msg);
|
||||
}
|
||||
} finally {
|
||||
if(netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected VSM session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void updatePortProfile(VmwareContext context, String ethPortProfileName, Integer vlanId, Integer networkRateMbps) throws Exception {
|
||||
msg = "Failed to add vEthernet port profile " + networkName + "." + ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if(netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (averageBandwidth > 0) {
|
||||
s_logger.info("Associating policy map " + policyName + " with port profile " + networkName + ".");
|
||||
netconfClient.attachServicePolicy(policyName, networkName);
|
||||
}
|
||||
}
|
||||
catch(CloudRuntimeException e) {
|
||||
msg = "Failed to associate policy map " + policyName + " with port profile " + networkName
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
} finally {
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void updatePortProfile(VmwareContext context, String ethPortProfileName, String vethPortProfileName,
|
||||
Integer vlanId, Integer networkRateMbps, long peakBandwidth, long burstRate) throws Exception {
|
||||
NetconfHelper netconfClient = null;
|
||||
Map<String, String> vsmCredentials = getValidatedVsmCredentials(context);
|
||||
String vsmIp = vsmCredentials.get("vsmip");
|
||||
String vsmUserName = vsmCredentials.get("vsmusername");
|
||||
String vsmPassword = vsmCredentials.get("vsmpassword");
|
||||
|
||||
String msg;
|
||||
try {
|
||||
netconfClient = new NetconfHelper(vsmIp, vsmUserName, vsmPassword);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to connect to Nexus 1000v " + vsmIp + " with credentials of user " + vsmUserName
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
PortProfile portProfile = netconfClient.getPortProfileByName(vethPortProfileName);
|
||||
int averageBandwidth = 0;
|
||||
String policyName = s_policyNamePrefix;
|
||||
if (networkRateMbps != null) {
|
||||
averageBandwidth = networkRateMbps.intValue();
|
||||
policyName += averageBandwidth;
|
||||
}
|
||||
|
||||
if (averageBandwidth > 0) {
|
||||
PolicyMap policyMap = netconfClient.getPolicyMapByName(portProfile.inputPolicyMap);
|
||||
if (policyMap.committedRate == averageBandwidth && policyMap.peakRate == peakBandwidth
|
||||
&& policyMap.burstRate == burstRate) {
|
||||
s_logger.debug("Detected that policy map is already applied to port profile " + vethPortProfileName);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
// TODO(sateesh): Change the type of peakBandwidth &
|
||||
// burstRate in PolicyMap to long.
|
||||
s_logger.info("Adding policy map " + policyName);
|
||||
netconfClient.addPolicyMap(policyName, averageBandwidth, (int) peakBandwidth, (int) burstRate);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to add policy map of " + policyName + " with parameters " + "committed rate = "
|
||||
+ averageBandwidth + "peak bandwidth = " + peakBandwidth + "burst size = " + burstRate
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
s_logger.info("Associating policy map " + policyName + " with port profile " + vethPortProfileName
|
||||
+ ".");
|
||||
netconfClient.attachServicePolicy(policyName, vethPortProfileName);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to associate policy map " + policyName + " with port profile " + vethPortProfileName
|
||||
+ ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vlanId == null) {
|
||||
s_logger.info("Skipping update operation over ethernet port profile " + ethPortProfileName + " for untagged VLAN.");
|
||||
s_logger.info("Skipping update operation over ethernet port profile " + ethPortProfileName
|
||||
+ " for untagged VLAN.");
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
s_logger.info("Updating vEthernet port profile with VLAN " + vlanId);
|
||||
|
||||
Map<String, String> vsmCredentials = getValidatedVsmCredentials(context);
|
||||
String vsmIp = vsmCredentials.get("vsmip");
|
||||
String vsmUserName = vsmCredentials.get("vsmusername");
|
||||
String vsmPassword = vsmCredentials.get("vsmpassword");
|
||||
String msg;
|
||||
|
||||
NetconfHelper netconfClient;
|
||||
try {
|
||||
netconfClient = new NetconfHelper(vsmIp, vsmUserName, vsmPassword);
|
||||
} catch(CloudRuntimeException e) {
|
||||
msg = "Failed to connect to Nexus VSM " + vsmIp + " with credentials of user " + vsmUserName;
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
|
||||
params.add(new Pair<OperationType, String>(OperationType.addvlanid, vlanId.toString()));
|
||||
|
||||
try {
|
||||
netconfClient.updatePortProfile(ethPortProfileName, SwitchPortMode.trunk, params);
|
||||
} catch(CloudRuntimeException e) {
|
||||
msg = "Failed to modify ethernet port profile " + ethPortProfileName + " with parameters " + params.toString();
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
} finally {
|
||||
if(netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected VSM session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String currentVlan = portProfile.vlan;
|
||||
String newVlan = Integer.toString(vlanId.intValue());
|
||||
if (currentVlan.equalsIgnoreCase(newVlan)) {
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
|
||||
params.add(new Pair<OperationType, String>(OperationType.addvlanid, newVlan));
|
||||
try {
|
||||
s_logger.info("Updating vEthernet port profile with VLAN " + vlanId.toString());
|
||||
netconfClient.updatePortProfile(ethPortProfileName, SwitchPortMode.trunk, params);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to update ethernet port profile " + ethPortProfileName + " with parameters "
|
||||
+ params.toString() + ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
netconfClient.updatePortProfile(vethPortProfileName, SwitchPortMode.access, params);
|
||||
} catch (CloudRuntimeException e) {
|
||||
msg = "Failed to update vEthernet port profile " + vethPortProfileName + " with parameters "
|
||||
+ params.toString() + ". Exception: " + e.toString();
|
||||
s_logger.error(msg);
|
||||
if (netconfClient != null) {
|
||||
netconfClient.disconnect();
|
||||
s_logger.debug("Disconnected Nexus 1000v session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ethPortProfileName
|
||||
* @param namePrefix
|
||||
|
|
@ -258,15 +378,16 @@ public class HypervisorHostHelper {
|
|||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Pair<ManagedObjectReference, String> prepareNetwork(String ethPortProfileName, String namePrefix,
|
||||
HostMO hostMo, String vlanId, Integer networkRateMbps, Integer networkRateMulticastMbps,
|
||||
long timeOutMs) throws Exception {
|
||||
ManagedObjectReference morNetwork = null;
|
||||
VmwareContext context = hostMo.getContext();
|
||||
ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter();
|
||||
DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
|
||||
|
||||
ManagedObjectReference morEthernetPortProfile = dataCenterMo.getDvPortGroupMor(ethPortProfileName);
|
||||
public static Pair<ManagedObjectReference, String> prepareNetwork(String ethPortProfileName, String namePrefix,
|
||||
HostMO hostMo, String vlanId, Integer networkRateMbps, Integer networkRateMulticastMbps, long timeOutMs)
|
||||
throws Exception {
|
||||
ManagedObjectReference morNetwork = null;
|
||||
VmwareContext context = hostMo.getContext();
|
||||
ManagedObjectReference dcMor = hostMo.getHyperHostDatacenter();
|
||||
DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
|
||||
|
||||
ManagedObjectReference morEthernetPortProfile = dataCenterMo.getDvPortGroupMor(ethPortProfileName);
|
||||
|
||||
if (morEthernetPortProfile == null) {
|
||||
String msg = "Unable to find Ethernet port profile " + ethPortProfileName;
|
||||
|
|
@ -274,7 +395,7 @@ public class HypervisorHostHelper {
|
|||
throw new Exception(msg);
|
||||
}
|
||||
else {
|
||||
s_logger.info("Found Ethernet port profile " + ethPortProfileName);
|
||||
s_logger.info("Found Ethernet port profile " + ethPortProfileName);
|
||||
}
|
||||
|
||||
boolean createGCTag = false;
|
||||
|
|
@ -285,63 +406,53 @@ public class HypervisorHostHelper {
|
|||
createGCTag = true;
|
||||
vid = Integer.parseInt(vlanId);
|
||||
}
|
||||
|
||||
networkName = composeCloudNetworkName(namePrefix, vlanId, networkRateMbps, ethPortProfileName);
|
||||
|
||||
networkName = composeCloudNetworkName(namePrefix, vlanId, networkRateMbps, ethPortProfileName);
|
||||
|
||||
// TODO(sateesh): Enable this for VMware DVS.
|
||||
/*DVSTrafficShapingPolicy shapingPolicy = null;
|
||||
if(networkRateMbps != null && networkRateMbps.intValue() > 0) {
|
||||
shapingPolicy = new DVSTrafficShapingPolicy();
|
||||
BoolPolicy isEnabled = new BoolPolicy();
|
||||
LongPolicy averageBandwidth = new LongPolicy();
|
||||
LongPolicy peakBandwidth = new LongPolicy();
|
||||
LongPolicy burstSize = new LongPolicy();
|
||||
|
||||
isEnabled.setValue(true);
|
||||
averageBandwidth.setValue((long)networkRateMbps.intValue()*1024L*1024L);
|
||||
// We chose 50% higher allocation than average bandwidth.
|
||||
// TODO(sateesh): Also let user specify the peak coefficient
|
||||
peakBandwidth.setValue((long)(averageBandwidth.getValue()*1.5));
|
||||
// TODO(sateesh): Also let user specify the burst coefficient
|
||||
burstSize.setValue((long)(5*averageBandwidth.getValue()/8));
|
||||
|
||||
shapingPolicy.setEnabled(isEnabled);
|
||||
shapingPolicy.setAverageBandwidth(averageBandwidth);
|
||||
shapingPolicy.setPeakBandwidth(peakBandwidth);
|
||||
shapingPolicy.setBurstSize(burstSize);
|
||||
}
|
||||
DVPortgroupConfigInfo spec = dataCenterMo.getDvPortGroupSpec(networkName);*/
|
||||
// DVSTrafficShapingPolicy shapingPolicy = null;
|
||||
// if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
|
||||
// shapingPolicy = new DVSTrafficShapingPolicy();
|
||||
// BoolPolicy isEnabled = new BoolPolicy();
|
||||
// LongPolicy averageBandwidth = new LongPolicy();
|
||||
// LongPolicy peakBandwidth = new LongPolicy();
|
||||
// LongPolicy burstSize = new LongPolicy();
|
||||
//
|
||||
// isEnabled.setValue(true);
|
||||
// averageBandwidth.setValue((long) networkRateMbps.intValue() * 1024L * 1024L);
|
||||
// // We chose 50% higher allocation than average bandwidth.
|
||||
// // TODO(sateesh): Also let user specify the peak coefficient
|
||||
// peakBandwidth.setValue((long) (averageBandwidth.getValue() * 1.5));
|
||||
// // TODO(sateesh): Also let user specify the burst coefficient
|
||||
// burstSize.setValue((long) (5 * averageBandwidth.getValue() / 8));
|
||||
//
|
||||
// shapingPolicy.setEnabled(isEnabled);
|
||||
// shapingPolicy.setAverageBandwidth(averageBandwidth);
|
||||
// shapingPolicy.setPeakBandwidth(peakBandwidth);
|
||||
// shapingPolicy.setBurstSize(burstSize);
|
||||
// }
|
||||
DVPortgroupConfigInfo spec = dataCenterMo.getDvPortGroupSpec(networkName);
|
||||
long averageBandwidth = 0L;
|
||||
if (networkRateMbps != null && networkRateMbps.intValue() > 0) {
|
||||
averageBandwidth = (long) (networkRateMbps.intValue() * 1024L * 1024L);
|
||||
}
|
||||
//We chose 50% higher allocation than average bandwidth.
|
||||
//TODO(sateesh): Also let user specify the peak coefficient
|
||||
// We chose 50% higher allocation than average bandwidth.
|
||||
// TODO(sateesh): Also let user specify the peak coefficient
|
||||
long peakBandwidth = (long) (averageBandwidth * 1.5);
|
||||
//TODO(sateesh): Also let user specify the burst coefficient
|
||||
long burstSize = 5 * averageBandwidth / 8;
|
||||
|
||||
boolean bWaitPortGroupReady = false;
|
||||
// TODO(sateesh): Also let user specify the burst coefficient
|
||||
long burstSize = 5 * averageBandwidth / 8;
|
||||
|
||||
boolean bWaitPortGroupReady = false;
|
||||
if (!dataCenterMo.hasDvPortGroup(networkName)) {
|
||||
s_logger.info("Port profile " + networkName + " not found.");
|
||||
createPortProfile(context, ethPortProfileName, networkName, vid, networkRateMbps);
|
||||
createPortProfile(context, ethPortProfileName, networkName, vid, networkRateMbps, peakBandwidth, burstSize);
|
||||
bWaitPortGroupReady = true;
|
||||
} else {
|
||||
s_logger.info("Port profile " + networkName + " found.");
|
||||
updatePortProfile(context, ethPortProfileName, vid, networkRateMbps);
|
||||
bWaitPortGroupReady = true;
|
||||
// TODO(sateesh): Enable port profile policy configuration
|
||||
// PortProfile portProfile;
|
||||
// try {
|
||||
// portProfile = getPortProfileByName(networkName);
|
||||
// if (portProfile.vlanId != vlanId ||
|
||||
// portProfile.policy.getAverageBandwidth() != averageBandwidth ||
|
||||
// portProfile.policy.getPeakBandwidth() != peakBandwidth ||
|
||||
// portProfile.policy.getBurstRate() != burstRate) {
|
||||
// updatePortProfile(context, ethPortProfileName, vlanId, averageBandwidth, peakBandwidth, burstSize);
|
||||
// }
|
||||
updatePortProfile(context, ethPortProfileName, networkName, vid, networkRateMbps, peakBandwidth, burstSize);
|
||||
}
|
||||
//Wait for dvPortGroup on vCenter
|
||||
// Wait for dvPortGroup on vCenter
|
||||
if(bWaitPortGroupReady)
|
||||
morNetwork = waitForDvPortGroupReady(dataCenterMo, networkName, timeOutMs);
|
||||
else
|
||||
|
|
@ -357,10 +468,10 @@ public class HypervisorHostHelper {
|
|||
networkMo.setCustomFieldValue(CustomFieldConstants.CLOUD_GC_DVP, "true");
|
||||
s_logger.debug("Added custom field : " + CustomFieldConstants.CLOUD_GC_DVP);
|
||||
}
|
||||
|
||||
return new Pair<ManagedObjectReference, String>(morNetwork, networkName);
|
||||
}
|
||||
|
||||
|
||||
return new Pair<ManagedObjectReference, String>(morNetwork, networkName);
|
||||
}
|
||||
|
||||
private static ManagedObjectReference waitForDvPortGroupReady(
|
||||
DatacenterMO dataCenterMo, String dvPortGroupName, long timeOutMs) throws Exception {
|
||||
ManagedObjectReference morDvPortGroup = null;
|
||||
|
|
@ -380,8 +491,8 @@ public class HypervisorHostHelper {
|
|||
return morDvPortGroup;
|
||||
}
|
||||
|
||||
private static boolean isSpecMatch(DVPortgroupConfigInfo spec, Integer vid,
|
||||
DVSTrafficShapingPolicy shapingPolicy) {
|
||||
// This method would be used for VMware Distributed Virtual Switch.
|
||||
private static boolean isSpecMatch(DVPortgroupConfigInfo spec, Integer vid, DVSTrafficShapingPolicy shapingPolicy) {
|
||||
DVSTrafficShapingPolicy currentTrafficShapingPolicy;
|
||||
currentTrafficShapingPolicy = spec.getDefaultPortConfig().getInShapingPolicy();
|
||||
// TODO(sateesh): Extract and compare vendor specific configuration specification as well.
|
||||
|
|
@ -561,222 +672,222 @@ public class HypervisorHostHelper {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ManagedObjectReference waitForNetworkReady(HostMO hostMo,
|
||||
String networkName, long timeOutMs) throws Exception {
|
||||
|
||||
ManagedObjectReference morNetwork = null;
|
||||
|
||||
// if portGroup is just created, getNetwork may fail to retrieve it, we
|
||||
// need to retry
|
||||
long startTick = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis() - startTick <= timeOutMs) {
|
||||
morNetwork = hostMo.getNetworkMor(networkName);
|
||||
if (morNetwork != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
s_logger.info("Waiting for network " + networkName + " to be ready");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
return morNetwork;
|
||||
}
|
||||
|
||||
public static boolean createBlankVm(VmwareHypervisorHost host, String vmName,
|
||||
int cpuCount, int cpuSpeedMHz, int cpuReservedMHz, boolean limitCpuUse, int memoryMB, int memoryReserveMB, String guestOsIdentifier,
|
||||
ManagedObjectReference morDs, boolean snapshotDirToParent) throws Exception {
|
||||
|
||||
if(s_logger.isInfoEnabled())
|
||||
s_logger.info("Create blank VM. cpuCount: " + cpuCount + ", cpuSpeed(MHz): " + cpuSpeedMHz + ", mem(Mb): " + memoryMB);
|
||||
|
||||
// VM config basics
|
||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
||||
vmConfig.setName(vmName);
|
||||
VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse);
|
||||
|
||||
// Scsi controller
|
||||
VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
|
||||
scsiController.setSharedBus(VirtualSCSISharing.noSharing);
|
||||
scsiController.setBusNumber(0);
|
||||
scsiController.setKey(1);
|
||||
VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
|
||||
scsiControllerSpec.setDevice(scsiController);
|
||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
|
||||
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
|
||||
DatastoreMO dsMo = new DatastoreMO(host.getContext(), morDs);
|
||||
fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
|
||||
vmConfig.setFiles(fileInfo);
|
||||
|
||||
VirtualMachineVideoCard videoCard = new VirtualMachineVideoCard();
|
||||
videoCard.setControllerKey(100);
|
||||
videoCard.setUseAutoDetect(true);
|
||||
|
||||
VirtualDeviceConfigSpec videoDeviceSpec = new VirtualDeviceConfigSpec();
|
||||
videoDeviceSpec.setDevice(videoCard);
|
||||
videoDeviceSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
|
||||
vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec, videoDeviceSpec });
|
||||
if(host.createVm(vmConfig)) {
|
||||
VirtualMachineMO vmMo = host.findVmOnHyperHost(vmName);
|
||||
assert(vmMo != null);
|
||||
|
||||
int ideControllerKey = -1;
|
||||
while(ideControllerKey < 0) {
|
||||
ideControllerKey = vmMo.tryGetIDEDeviceControllerKey();
|
||||
if(ideControllerKey >= 0)
|
||||
break;
|
||||
|
||||
s_logger.info("Waiting for IDE controller be ready in VM: " + vmName);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
if(snapshotDirToParent) {
|
||||
String snapshotDir = String.format("/vmfs/volumes/%s/", dsMo.getName());
|
||||
|
||||
s_logger.info("Switch snapshot working directory to " + snapshotDir + " for " + vmName);
|
||||
vmMo.setSnapshotDirectory(snapshotDir);
|
||||
|
||||
// Don't have a good way to test if the VM is really ready for use through normal API after configuration file manipulation,
|
||||
// delay 3 seconds
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
|
||||
s_logger.info("Blank VM: " + vmName + " is ready for use");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) {
|
||||
|
||||
s_logger.info("Resolving host name in url through vCenter, url: " + url);
|
||||
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(url);
|
||||
} catch (URISyntaxException e) {
|
||||
s_logger.warn("URISyntaxException on url " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
String host = uri.getHost();
|
||||
if(NetUtils.isValidIp(host)) {
|
||||
s_logger.info("host name in url is already in IP address, url: " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
try {
|
||||
ManagedObjectReference morHost = dcMo.findHost(host);
|
||||
if(morHost != null) {
|
||||
|
||||
public static ManagedObjectReference waitForNetworkReady(HostMO hostMo,
|
||||
String networkName, long timeOutMs) throws Exception {
|
||||
|
||||
ManagedObjectReference morNetwork = null;
|
||||
|
||||
// if portGroup is just created, getNetwork may fail to retrieve it, we
|
||||
// need to retry
|
||||
long startTick = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis() - startTick <= timeOutMs) {
|
||||
morNetwork = hostMo.getNetworkMor(networkName);
|
||||
if (morNetwork != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
s_logger.info("Waiting for network " + networkName + " to be ready");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
return morNetwork;
|
||||
}
|
||||
|
||||
public static boolean createBlankVm(VmwareHypervisorHost host, String vmName,
|
||||
int cpuCount, int cpuSpeedMHz, int cpuReservedMHz, boolean limitCpuUse, int memoryMB, int memoryReserveMB, String guestOsIdentifier,
|
||||
ManagedObjectReference morDs, boolean snapshotDirToParent) throws Exception {
|
||||
|
||||
if(s_logger.isInfoEnabled())
|
||||
s_logger.info("Create blank VM. cpuCount: " + cpuCount + ", cpuSpeed(MHz): " + cpuSpeedMHz + ", mem(Mb): " + memoryMB);
|
||||
|
||||
// VM config basics
|
||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
||||
vmConfig.setName(vmName);
|
||||
VmwareHelper.setBasicVmConfig(vmConfig, cpuCount, cpuSpeedMHz, cpuReservedMHz, memoryMB, memoryReserveMB, guestOsIdentifier, limitCpuUse);
|
||||
|
||||
// Scsi controller
|
||||
VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
|
||||
scsiController.setSharedBus(VirtualSCSISharing.noSharing);
|
||||
scsiController.setBusNumber(0);
|
||||
scsiController.setKey(1);
|
||||
VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
|
||||
scsiControllerSpec.setDevice(scsiController);
|
||||
scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
|
||||
VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo();
|
||||
DatastoreMO dsMo = new DatastoreMO(host.getContext(), morDs);
|
||||
fileInfo.setVmPathName(String.format("[%s]", dsMo.getName()));
|
||||
vmConfig.setFiles(fileInfo);
|
||||
|
||||
VirtualMachineVideoCard videoCard = new VirtualMachineVideoCard();
|
||||
videoCard.setControllerKey(100);
|
||||
videoCard.setUseAutoDetect(true);
|
||||
|
||||
VirtualDeviceConfigSpec videoDeviceSpec = new VirtualDeviceConfigSpec();
|
||||
videoDeviceSpec.setDevice(videoCard);
|
||||
videoDeviceSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
|
||||
vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec, videoDeviceSpec });
|
||||
if(host.createVm(vmConfig)) {
|
||||
VirtualMachineMO vmMo = host.findVmOnHyperHost(vmName);
|
||||
assert(vmMo != null);
|
||||
|
||||
int ideControllerKey = -1;
|
||||
while(ideControllerKey < 0) {
|
||||
ideControllerKey = vmMo.tryGetIDEDeviceControllerKey();
|
||||
if(ideControllerKey >= 0)
|
||||
break;
|
||||
|
||||
s_logger.info("Waiting for IDE controller be ready in VM: " + vmName);
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
|
||||
if(snapshotDirToParent) {
|
||||
String snapshotDir = String.format("/vmfs/volumes/%s/", dsMo.getName());
|
||||
|
||||
s_logger.info("Switch snapshot working directory to " + snapshotDir + " for " + vmName);
|
||||
vmMo.setSnapshotDirectory(snapshotDir);
|
||||
|
||||
// Don't have a good way to test if the VM is really ready for use through normal API after configuration file manipulation,
|
||||
// delay 3 seconds
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
|
||||
s_logger.info("Blank VM: " + vmName + " is ready for use");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String resolveHostNameInUrl(DatacenterMO dcMo, String url) {
|
||||
|
||||
s_logger.info("Resolving host name in url through vCenter, url: " + url);
|
||||
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(url);
|
||||
} catch (URISyntaxException e) {
|
||||
s_logger.warn("URISyntaxException on url " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
String host = uri.getHost();
|
||||
if(NetUtils.isValidIp(host)) {
|
||||
s_logger.info("host name in url is already in IP address, url: " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
try {
|
||||
ManagedObjectReference morHost = dcMo.findHost(host);
|
||||
if(morHost != null) {
|
||||
HostMO hostMo = new HostMO(dcMo.getContext(), morHost);
|
||||
String managementPortGroupName;
|
||||
if(hostMo.getHostType() == VmwareHostType.ESXi)
|
||||
managementPortGroupName = (String)dcMo.getContext().getStockObject("manageportgroup");
|
||||
else
|
||||
managementPortGroupName = (String)dcMo.getContext().getStockObject("serviceconsole");
|
||||
|
||||
VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(managementPortGroupName);
|
||||
if(summary == null) {
|
||||
s_logger.warn("Unable to resolve host name in url through vSphere, url: " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
String hostIp = summary.getHostIp();
|
||||
|
||||
try {
|
||||
URI resolvedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostIp, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
|
||||
|
||||
s_logger.info("url " + url + " is resolved to " + resolvedUri.toString() + " through vCenter");
|
||||
return resolvedUri.toString();
|
||||
} catch (URISyntaxException e) {
|
||||
assert(false);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
s_logger.warn("Unexpected exception ", e);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption,
|
||||
ManagedObjectReference morRp, ManagedObjectReference morHost) throws Exception {
|
||||
|
||||
assert(morRp != null);
|
||||
|
||||
OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams();
|
||||
importSpecParams.setHostSystem(morHost);
|
||||
importSpecParams.setLocale("US");
|
||||
importSpecParams.setEntityName(vmName);
|
||||
importSpecParams.setDeploymentOption("");
|
||||
importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc
|
||||
importSpecParams.setPropertyMapping(null);
|
||||
|
||||
String ovfDescriptor = HttpNfcLeaseMO.readOvfContent(ovfFilePath);
|
||||
VmwareContext context = host.getContext();
|
||||
OvfCreateImportSpecResult ovfImportResult = context.getService().createImportSpec(
|
||||
context.getServiceContent().getOvfManager(), ovfDescriptor, morRp,
|
||||
dsMo.getMor(), importSpecParams);
|
||||
|
||||
if(ovfImportResult == null) {
|
||||
String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: "
|
||||
+ vmName + ", diskOption: " + diskOption;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
DatacenterMO dcMo = new DatacenterMO(context, host.getHyperHostDatacenter());
|
||||
ManagedObjectReference morLease = context.getService().importVApp(morRp,
|
||||
ovfImportResult.getImportSpec(), dcMo.getVmFolder(), morHost);
|
||||
if(morLease == null) {
|
||||
String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: "
|
||||
+ vmName + ", diskOption: " + diskOption;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease);
|
||||
HttpNfcLeaseState state = leaseMo.waitState(
|
||||
new HttpNfcLeaseState[] { HttpNfcLeaseState.ready, HttpNfcLeaseState.error });
|
||||
try {
|
||||
if(state == HttpNfcLeaseState.ready) {
|
||||
final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult);
|
||||
File ovfFile = new File(ovfFilePath);
|
||||
|
||||
HttpNfcLeaseInfo httpNfcLeaseInfo = leaseMo.getLeaseInfo();
|
||||
HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl();
|
||||
long bytesAlreadyWritten = 0;
|
||||
|
||||
final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter();
|
||||
try {
|
||||
for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) {
|
||||
String deviceKey = deviceUrl.getImportKey();
|
||||
for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) {
|
||||
if (deviceKey.equals(ovfFileItem.getDeviceId())) {
|
||||
String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath();
|
||||
String urlToPost = deviceUrl.getUrl();
|
||||
urlToPost = resolveHostNameInUrl(dcMo, urlToPost);
|
||||
|
||||
context.uploadVmdkFile(ovfFileItem.isCreate() ? "PUT" : "POST", urlToPost, absoluteFile,
|
||||
bytesAlreadyWritten, new ActionDelegate<Long> () {
|
||||
public void action(Long param) {
|
||||
progressReporter.reportProgress((int)(param * 100 / totalBytes));
|
||||
}
|
||||
});
|
||||
|
||||
bytesAlreadyWritten += ovfFileItem.getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
progressReporter.close();
|
||||
}
|
||||
leaseMo.updateLeaseProgress(100);
|
||||
}
|
||||
} finally {
|
||||
leaseMo.completeLease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VmwareHypervisorHostNetworkSummary summary = hostMo.getHyperHostNetworkSummary(managementPortGroupName);
|
||||
if(summary == null) {
|
||||
s_logger.warn("Unable to resolve host name in url through vSphere, url: " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
String hostIp = summary.getHostIp();
|
||||
|
||||
try {
|
||||
URI resolvedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostIp, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
|
||||
|
||||
s_logger.info("url " + url + " is resolved to " + resolvedUri.toString() + " through vCenter");
|
||||
return resolvedUri.toString();
|
||||
} catch (URISyntaxException e) {
|
||||
assert(false);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
s_logger.warn("Unexpected exception ", e);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public static void importVmFromOVF(VmwareHypervisorHost host, String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption,
|
||||
ManagedObjectReference morRp, ManagedObjectReference morHost) throws Exception {
|
||||
|
||||
assert(morRp != null);
|
||||
|
||||
OvfCreateImportSpecParams importSpecParams = new OvfCreateImportSpecParams();
|
||||
importSpecParams.setHostSystem(morHost);
|
||||
importSpecParams.setLocale("US");
|
||||
importSpecParams.setEntityName(vmName);
|
||||
importSpecParams.setDeploymentOption("");
|
||||
importSpecParams.setDiskProvisioning(diskOption); // diskOption: thin, thick, etc
|
||||
importSpecParams.setPropertyMapping(null);
|
||||
|
||||
String ovfDescriptor = HttpNfcLeaseMO.readOvfContent(ovfFilePath);
|
||||
VmwareContext context = host.getContext();
|
||||
OvfCreateImportSpecResult ovfImportResult = context.getService().createImportSpec(
|
||||
context.getServiceContent().getOvfManager(), ovfDescriptor, morRp,
|
||||
dsMo.getMor(), importSpecParams);
|
||||
|
||||
if(ovfImportResult == null) {
|
||||
String msg = "createImportSpec() failed. ovfFilePath: " + ovfFilePath + ", vmName: "
|
||||
+ vmName + ", diskOption: " + diskOption;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
DatacenterMO dcMo = new DatacenterMO(context, host.getHyperHostDatacenter());
|
||||
ManagedObjectReference morLease = context.getService().importVApp(morRp,
|
||||
ovfImportResult.getImportSpec(), dcMo.getVmFolder(), morHost);
|
||||
if(morLease == null) {
|
||||
String msg = "importVApp() failed. ovfFilePath: " + ovfFilePath + ", vmName: "
|
||||
+ vmName + ", diskOption: " + diskOption;
|
||||
s_logger.error(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
final HttpNfcLeaseMO leaseMo = new HttpNfcLeaseMO(context, morLease);
|
||||
HttpNfcLeaseState state = leaseMo.waitState(
|
||||
new HttpNfcLeaseState[] { HttpNfcLeaseState.ready, HttpNfcLeaseState.error });
|
||||
try {
|
||||
if(state == HttpNfcLeaseState.ready) {
|
||||
final long totalBytes = HttpNfcLeaseMO.calcTotalBytes(ovfImportResult);
|
||||
File ovfFile = new File(ovfFilePath);
|
||||
|
||||
HttpNfcLeaseInfo httpNfcLeaseInfo = leaseMo.getLeaseInfo();
|
||||
HttpNfcLeaseDeviceUrl[] deviceUrls = httpNfcLeaseInfo.getDeviceUrl();
|
||||
long bytesAlreadyWritten = 0;
|
||||
|
||||
final HttpNfcLeaseMO.ProgressReporter progressReporter = leaseMo.createProgressReporter();
|
||||
try {
|
||||
for (HttpNfcLeaseDeviceUrl deviceUrl : deviceUrls) {
|
||||
String deviceKey = deviceUrl.getImportKey();
|
||||
for (OvfFileItem ovfFileItem : ovfImportResult.getFileItem()) {
|
||||
if (deviceKey.equals(ovfFileItem.getDeviceId())) {
|
||||
String absoluteFile = ovfFile.getParent() + File.separator + ovfFileItem.getPath();
|
||||
String urlToPost = deviceUrl.getUrl();
|
||||
urlToPost = resolveHostNameInUrl(dcMo, urlToPost);
|
||||
|
||||
context.uploadVmdkFile(ovfFileItem.isCreate() ? "PUT" : "POST", urlToPost, absoluteFile,
|
||||
bytesAlreadyWritten, new ActionDelegate<Long> () {
|
||||
public void action(Long param) {
|
||||
progressReporter.reportProgress((int)(param * 100 / totalBytes));
|
||||
}
|
||||
});
|
||||
|
||||
bytesAlreadyWritten += ovfFileItem.getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
progressReporter.close();
|
||||
}
|
||||
leaseMo.updateLeaseProgress(100);
|
||||
}
|
||||
} finally {
|
||||
leaseMo.completeLease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue