cloneVM_Task configure cloned VM to another distributed virtual port - vmware

How do I use VirtualMachineConfigSpec to set device change and configure my new clone to another distributed virtual port? My cloned VM network adapter type is VirtualVmxnet3, I would like to configure the 10.xx.xxx.xx-x_vm_ddc (dv port name) dv switch upon successful clone.
Following clone method takes a source vm (powered off) as template for new clone:
public ResponseEntity<?> cloneRhcosVm(#PathVariable String vcenter, #RequestBody VmClone vmClone) {
VirtualMachine vm = null;
VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
VirtualMachineRelocateSpec relocSpec = new VirtualMachineRelocateSpec();
VirtualMachineBootOptions boot = new VirtualMachineBootOptions();
VirtualMachineBootOptionsBootableCdromDevice isoBoot = new
VirtualMachineBootOptionsBootableCdromDevice();
VirtualMachineBootOptionsBootableDevice[] bootOrder = new
VirtualMachineBootOptionsBootableDevice[]{isoBoot};
List<VirtualDeviceConfigSpec> vdSpecAll = new ArrayList<VirtualDeviceConfigSpec>();
VirtualDeviceConfigSpec[] vdSpecArray = new VirtualDeviceConfigSpec[]{};
try {
String sourceVmName = vmClone.getSourceVmName();
String cloneVmName = vmClone.getTargetVmName();
vm = vmService.getVirtualMachine(vcenter, sourceVmName);
int cloneVmCPUs = vmClone.getTargetVmCPUs();
long cloneVmMemoryMB = (long) vmClone.getTargetVmMemoryGB() * Constants.MB_TO_GB;
String cloneVmNicName = vmClone.getTargetVmNicName();
boot.setBootOrder(bootOrder);
// Get target nic (dv switch) virutal device
VirtualDeviceConfigSpec nicSpec = getTargetNicVDConfigSpec(vm, cloneVmNicName);
if (nicSpec != null) {
vdSpecAll.add(nicSpec);
}
vdSpecArray = vdSpecAll.toArray(new VirtualDeviceConfigSpec[vdSpecAll.size()]);
configSpec.setDeviceChange(vdSpecArray);
configSpec.setName(cloneVmName);
configSpec.setNumCPUs(cloneVmCPUs);
configSpec.setNumCoresPerSocket(cloneVmCPUs);
configSpec.setMemoryMB(cloneVmMemoryMB);
configSpec.setBootOptions(boot);
cloneSpec.setConfig(configSpec);
cloneSpec.setLocation(relocSpec);
cloneSpec.setPowerOn(true);
cloneSpec.setTemplate(false);
Task task = vm.cloneVM_Task((Folder) vm.getParent(), cloneVmName, cloneSpec);
TaskInfo taskInfo = task.getTaskInfo();
...
}
Following method used to configure new nic virtual device: targetNicName is the new 10.xx.xxx.xx-x_vm_ddc I want to set to after cloning
private VirtualDeviceConfigSpec getTargetNicVDConfigSpec(VirtualMachine vm, String targetNicName) {
VirtualDevice[] vds = vm.getConfig().getHardware().getDevice();
VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
VirtualDeviceConnectInfo deviceConnInfo = new VirtualDeviceConnectInfo();
String adapter1 = "Network adapter 1";
for (int i = 0; i < vds.length; i++) {
if ((vds[i] instanceof VirtualEthernetCard) && (vds[i].getDeviceInfo().getLabel().equalsIgnoreCase(adapter1))) {
VirtualEthernetCard nic = (VirtualEthernetCard) vds[i];
VirtualEthernetCardNetworkBackingInfo nicBacking = (VirtualEthernetCardNetworkBackingInfo) nic.getBacking();
deviceConnInfo.setConnected(true);
nicBacking.setDeviceName(targetNicName);
nic.setBacking(nicBacking);
nic.setConnectable(deviceConnInfo);
nicSpec.setOperation(VirtualDeviceConfigSpecOperation.edit);
nicSpec.setDevice(nic);
return nicSpec;
}
}
return null;
}
Above code works but the new network adapter is not being configured as a dvSwitch as I was expecting by setting the new device name.
I found that my network adapter virtual device (vd) is of class VirtualVmxnet3 and the vd's backing info is of class VirtualEthernetCardDistributedVirtualPortBackingInfo, however these classes do not have any method that works like .setDevice(nicName) to configure the network adapter to new dvSwitch by passing name 10.xx.xxx.xx-x_vm_ddc.
Any clues if it's possible to clone and configure to another dv port?

Related

Is the following akka.conf file valid?

I am using OpenDaylight and trying to replace the default distributed database with Apache Ignite.
I am using the jar obtained by the source code here.
https://github.com/Romeh/akka-persistance-ignite
However, the class IgniteWriteJournal does not seem to load which i have checked by putting some print statements in its constuructor.
Is there any issue with the .conf file?
The following is a portion of the akka.conf file i am using in OpenDaylight.
odl-cluster-data {
akka {
remote {
artery {
enabled = off
canonical.hostname = "10.145.59.38"
canonical.port = 2550
}
netty.tcp {
hostname = "10.145.59.38"
port = 2550
}
# when under load we might trip a false positive on the failure detector
# transport-failure-detector {
# heartbeat-interval = 4 s
# acceptable-heartbeat-pause = 16s
# }
}
cluster {
# Remove ".tcp" when using artery.
seed-nodes = ["akka.tcp://opendaylight-cluster-data#10.145.59.38:2550"]
roles = ["member-1"]
}
extensions = ["akka.persistence.ignite.extension.IgniteExtensionProvider"]
akka.persistence.journal.plugin = "akka.persistence.journal.ignite"
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot.ignite"
persistence {
# Ignite journal plugin
journal {
ignite {
# Class name of the plugin
class = "akka.persistence.ignite.journal.IgniteWriteJournal"
cache-prefix = "akka-journal"
// Should be based into the the dara grid topology
cache-backups = 1
// if ignite is already started in a separate standalone grid where journal cache is already created
cachesAlreadyCreated = false
}
}
# Ignite snapshot plugin
snapshot {
ignite {
# Class name of the plugin
class = "akka.persistence.ignite.snapshot.IgniteSnapshotStore"
cache-prefix = "akka-snapshot"
// Should be based into the the dara grid topology
cache-backups = 1
// if ignite is already started in a separate standalone grid where snapshot cache is already created
cachesAlreadyCreated = false
}
}
}
}
ignite {
//to start client or server node to connect to Ignite data cluster
isClientNode = false
// for ONLY testing we use localhost
// used for grid cluster connectivity
tcpDiscoveryAddresses = "localhost"
metricsLogFrequency = 0
// thread pools used by Ignite , should based into target machine specs
queryThreadPoolSize = 4
dataStreamerThreadPoolSize = 1
managementThreadPoolSize = 2
publicThreadPoolSize = 4
systemThreadPoolSize = 2
rebalanceThreadPoolSize = 1
asyncCallbackPoolSize = 4
peerClassLoadingEnabled = false
// to enable or disable durable memory persistance
enableFilePersistence = true
// used for grid cluster connectivity, change it to suit your configuration
igniteConnectorPort = 11211
// used for grid cluster connectivity , change it to suit your configuration
igniteServerPortRange = "47500..47509"
//durable memory persistance storage file system path , change it to suit your configuration
ignitePersistenceFilePath = "./data"
}
}
I assume you modified the configuration/initial/akka.conf. First those sections need to be inside the odl-cluster-data section (can't tell from just your snippet). Also it looks like the following should be:
akka.persistence.journal.plugin = "akka.persistence.journal.ignite"
akka.persistence.snapshot-store.plugin = "akka.persistence.snapshot.ignite"

Multiple USB to RS485 FTDI Device ID

I need some help. I'm programming a Win 10 App in C++/CX. I am using two USB to RS485 devices, both of which have the same VID number. In days of old, I could write a bit software and connect to ports using good old COMx etc.
I'm now following the example here Serial Sample which uses the approach gathering the device info so when looking for connected devices, what I see in the list of available devices is the following.
\?\FTDIBUS#VID_0403+PID_6001
Both devices have the same VID and PID. This leads to the problem of me being cable to connect to the correct USB device. I think my app is trying to connect to both devices at the same time? Does anyone have any ideas about how I can resolve this hitch?
void MainPage::Get_Serial_Devices() {
cancellationTokenSource_Port1 = new Concurrency::cancellation_token_source();
cancellationTokenSource_Port2 = new Concurrency::cancellation_token_source();
// THIS USES ASYNCRONOUS OPERATION. GET A LIST OF SERIAL DEVICES AND POPULATE THE COMBO BOX
Concurrency::create_task(ListAvailablePortsAsync()).then([this](DeviceInformationCollection^ serialDeviceCollectioin)
{
// serialDeviceCollection CONTAINS ALL SERIAL DEVICES FOUND, COPY INTO _deviceCollection
DeviceInformationCollection^ _deviceCollection = serialDeviceCollectioin;
// CLEAR EXISTING DEVICES FOR OUR OBJECT COLLECTION
_availableDevices->Clear();
// FOR EVERY DEVICE IN _deviceCollection
for (auto &&device : _deviceCollection) {
if (device->Name->Equals("USB-RS485 Cable")) {
// CREATE A NEW DEVICE TYPE AND APPEND TO OUR OBJECT COLLECTION
_availableDevices->Append(ref new Device(device->Id, device));
Total_Ports++;
this->DeviceLists->Items->Append(device->Id);
}
}
});
void MainPage::ConnectButton_Click(Object^ sender, RoutedEventArgs^ e) {
if (Port1_Connected == false) {
// CAST INDEX TO CORRELATING Device IN _availableDevices
Device^ selectedDevice = static_cast<Device^>(_availableDevices->GetAt(Port_1_ID));
// GET THE DEVICE INFO
DeviceInformation^ entry = selectedDevice->DeviceInfo;
Concurrency::create_task(ConnectToSerialDeviceAsync_Port1(entry, cancellationTokenSource_Port1->get_token())).then([this]( ) {
Get_Echo();
Waiting_For_Ack = true;
});
}
Concurrency::task<void> MainPage::ConnectToSerialDeviceAsync_Port1(DeviceInformation^ device, Concurrency::cancellation_token cancellationToken) {
// CREATE A LINKED TOKEN WHICH IS CANCELLED WHEN THE PROVIDED TOKEN IS CANCELLED
auto childTokenSource = Concurrency::cancellation_token_source::create_linked_source(cancellationToken);
// GET THE TOKEN
auto childToken = childTokenSource.get_token();
// CONNECT TO ARDUINO TASK
return Concurrency::create_task(SerialDevice::FromIdAsync(device->Id), childToken).then([this](SerialDevice^ serial_device) {
try {
_serialPort_Port1 = serial_device;
TimeSpan _timeOut; _timeOut.Duration = 10;
// CONFIGURE SERIAL PORT SETTINGS
_serialPort_Port1->WriteTimeout = _timeOut;
_serialPort_Port1->ReadTimeout = _timeOut;
_serialPort_Port1->BaudRate = 57600;
_serialPort_Port1->Parity = Windows::Devices::SerialCommunication::SerialParity::None;
_serialPort_Port1->StopBits = Windows::Devices::SerialCommunication::SerialStopBitCount::One;
_serialPort_Port1->DataBits = 8;
_serialPort_Port1->Handshake = Windows::Devices::SerialCommunication::SerialHandshake::None;
// CREATE OUR DATA READER OBJECT
_dataReaderObject_Port1 = ref new DataReader(_serialPort_Port1->InputStream);
_dataReaderObject_Port1->InputStreamOptions = InputStreamOptions::None;
// CREATE OUR DATA WRITE OBJECT
_dataWriterObject_Port1 = ref new DataWriter(_serialPort_Port1->OutputStream);
this->ConnectButton->IsEnabled = false;
this->DisconnectButton->IsEnabled = true;
// KICK OF THE SERIAL PORT LISTENING PROCESS
Listen_Port1();
}
catch (Platform::Exception^ ex) {
this->Error_Window->Text = (ex->Message);
CloseDevice(PORT_1);
}
});
FT_PROG is a free EEPROM programming utility for use with FTDI devices. It is used for modifying EEPROM contents that store the FTDI device descriptors to customize designs.
The full FT_PROG User Guide can be downloaded here.

Open pegasus association provider

I am developing a SMI-S provider using openpegasus,
when I try
cimserver "cimcli -n root/ift a CIM_StoragePool -i"
console shows instance list of CIM_StoragePool,
which means that enumerateInstanceNames method in Instance provider works,
but, when I select a instance,there is nothing happening.
My associator method in association provider did not be called.
I register association provider in my mof below:
instance of PG_ProviderModule
{
Name = "IFTComputerSystemModule";
Location = "IFT_ComputerSystemProvider";
Vendor = "Infortrend";
Version = "2.4.0";
InterfaceType = "C++Default";
InterfaceVersion = "2.1.0";
};
instance of PG_Provider
{
ProviderModuleName = "IFTComputerSystemModule";
Name = "IFT_ComputerSystemProvider";
};
instance of PG_ProviderCapabilities
{
ProviderModuleName = "IFTComputerSystemModule";
ProviderName = "IFT_ComputerSystemProvider";
CapabilityID = "1";
ClassName = "CIM_ComputerSystem";
Namespaces = {"root/ift"};
ProviderType = { 2, 3 }; // Instance
SupportedProperties = NULL; // All properties
SupportedMethods = NULL; // All methods
};
Is there anyone could help ? thanks a lot!

VMWare VIM SDK. List all VM's working, but list all datasources does not. Am I missing something?

My goal is to get a listing of all the DataStores in a specific datacenter. I'm able to list all of the Hosts, and VM's, but not the Datastores, and I don't understand why (I'm still learning the API's). Any insight would be appreciated.
Here's the code for grabbing all of the VM's (this works as expected):
public List<VM> getVMsInDatacenter(String datacenter, IEnumerable<String> properties)
{
List<VM> VMs = null;
this.joinConnection((appUtil) =>
{
var svcUtil = appUtil.getServiceUtil();
var dcMoRef = svcUtil.GetDecendentMoRef(null, "Datacenter", datacenter);
var typeinfo = buildTypeInfo("VirtualMachine", properties.ToList());
VMs = buildVMsFromObjectContent(svcUtil.GetContentsRecursively(null, dcMoRef, typeinfo, true));
});
return VMs;
}
Here is the analogous code for the Datastore (which does not work as expected):
public List<DataStore> getDataStoresInDatacenter(String datacenter, IEnumerable<String> properties)
{
List<DataStore> DataStores = null;
this.joinConnection((appUtil) =>
{
var svcUtil = appUtil.getServiceUtil();
var dcMoRef = svcUtil.GetDecendentMoRef(null, "Datacenter", datacenter);
var typeinfo = buildTypeInfo("Datastore", properties.ToList());
DataStores = buildDataStoresFromObjectContent(svcUtil.GetContentsRecursively(null, dcMoRef, typeinfo, true));
});
return DataStores;
}
appUtil is an instantiation of the AppUtil class that came with the VIM SDK samples. It houses functionality for connecting, querying, etc.
joinConnection is a method for connecting, or re-using a connection if we've already connected.
If there are any other questions about the code, please let me know.
Also, if there's a better way, I'd like to know that too :)
Found the problem. The method getContentsRecursively is calling a method called 'buildFullTraversal' that builds a traversal/selection spec. This method was not adding a traversal for the datastore. I added one that like so:
TraversalSpec vmToDs = new TraversalSpec();
vmToDs.name = "vmToDs";
vmToDs.type = "VirtualMachine";
vmToDs.path = "datastore";
HToVm.skip = false;
HToVm.skipSpecified = true;
And then I modified the visitFolders traversal like so:
// Recurse through the folders
TraversalSpec visitFolders = new TraversalSpec();
visitFolders.name = "visitFolders";
visitFolders.type = "Folder";
visitFolders.path = "childEntity";
visitFolders.skip = false;
visitFolders.skipSpecified = true;
visitFolders.selectSet = new SelectionSpec[] { new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec(), new SelectionSpec() };
visitFolders.selectSet[0].name = "visitFolders";
visitFolders.selectSet[1].name = "dcToHf";
visitFolders.selectSet[2].name = "dcToVmf";
visitFolders.selectSet[3].name = "crToH";
visitFolders.selectSet[4].name = "crToRp";
visitFolders.selectSet[5].name = "HToVm";
visitFolders.selectSet[6].name = "rpToVm";
visitFolders.selectSet[7].name = "vmToDs";
return new SelectionSpec[] { visitFolders, dcToVmf, dcToHf, crToH, crToRp, rpToRp, HToVm, rpToVm, vmToDs };
Now, calls to getContentsRecursively will also include the datastores that belong to a VM, so the method in the question will works as expected.

Virtual Server IIS WMI Problem

I have been tasked with finding out what is causing an issue with this bit of code:
public static ArrayList GetEthernetMacAddresses()
{
ArrayList addresses = new ArrayList();
ManagementClass mc = new ManagementClass("Win32_NetworkAdapter");
// This causes GetInstances(options)
// to return all subclasses of Win32_NetworkAdapter
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true;
foreach (ManagementObject mo in mc.GetInstances(options)) {
string macAddr = mo["MACAddress"] as string;
string adapterType = mo["AdapterType"] as string;
if (!StringUtil.IsBlank(macAddr) && !StringUtil.IsBlank(adapterType))
{
if (adapterType.StartsWith("Ethernet")) {
addresses.Add(macAddr);
}
}
}
return addresses;
}
On our (Win2003) virtual servers, this works when run as part of a console application but not from a web service running on IIS (on that same machine).
Alternatively, I can use this code in a web service on IIS (on the virtual server) and get the correct return values:
public static string GetMacAddresses()
{
ManagementClass mgmt = new ManagementClass(
"Win32_NetworkAdapterConfiguration"
);
ManagementObjectCollection objCol = mgmt.GetInstances();
foreach (ManagementObject obj in objCol)
{
if ((bool)obj["IPEnabled"])
{
if (sb.Length > 0)
{
sb.Append(";");
}
sb.Append(obj["MacAddress"].ToString());
}
obj.Dispose();
}
}
Why does the second one work and not the first one?
Why only when called through an IIS web service on a virtual machine?
Any help would be appreciated.
UPDATE: After much telephone time with all different levels of MS Support, the've come to the conclusion that this is "As Designed".
Since it is on a driver level for the virtual network adapter driver, the answer was that we should change our code "to work around the issue".
This means that you cannot reliable test code on virtual servers unless you with the same code that you use on physical servers, since we can't guarantee that the servers are exact replicas...
Okay, so I wrote this code to test the issue:
public void GetWin32_NetworkAdapter()
{
DataTable dt = new DataTable();
dt.Columns.Add("AdapterName", typeof(string));
dt.Columns.Add("ServiceName", typeof(string));
dt.Columns.Add("AdapterType", typeof(string));
dt.Columns.Add("IPEnabled", typeof(bool));
dt.Columns.Add("MacAddress", typeof(string));
//Try getting it by Win32_NetworkAdapterConfiguration
ManagementClass mgmt = new ManagementClass("Win32_NetworkAdapter");
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true;
ManagementObjectCollection objCol = mgmt.GetInstances(options);
foreach (ManagementObject obj in objCol)
{
DataRow dr = dt.NewRow();
dr["AdapterName"] = obj["Caption"].ToString();
dr["ServiceName"] = obj["ServiceName"].ToString();
dr["AdapterType"] = obj["AdapterType"];
dr["IPEnabled"] = (bool)obj["IPEnabled"];
if (obj["MacAddress"] != null)
{
dr["MacAddress"] = obj["MacAddress"].ToString();
}
else
{
dr["MacAddress"] = "none";
}
dt.Rows.Add(dr);
}
gvConfig.DataSource = dt;
gvConfig.DataBind();
}
When it's run on a physical IIS box I get this:
Physical IIS server http://img14.imageshack.us/img14/8098/physicaloutput.gif
Same code on Virtual IIS server:
Virtual server http://img25.imageshack.us/img25/4391/virtualoutput.gif
See a difference? It's on the first line. The virtual server doesn't return the "AdapterType" string. Which is why the original code was failing.
This brings up an interesting thought. If Virtual Server is supposed to be an "virtual" representation of a real IIS server, why doesn't it return the same values?
Why are the two returning different results? It's possible that due to the different user accounts, you'll get different results running from the console and from a service.
Why does (1) fail and (2) work? Is it possible that a null result for adapterType return a null value? If so, would the code handle this condition?