Skip to content

Commit

Permalink
Merge pull request #1532
Browse files Browse the repository at this point in the history
VMware Plugin: Fix transformer issues
  • Loading branch information
BareosBot committed Sep 15, 2023
2 parents 57dbed1 + 164f745 commit 235cc6a
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 31 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -126,6 +126,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
- status storage: fix wrong data displayed about waiting jobs [PR #1476]
- stored: fix incoherent meta data when concurrently writing to the same volume [PR #1495]
- dird: fix expected file count error during bsr build [PR #1511]
- VMware Plugin: Fix transformer issues [PR #1532]

### Documentation
- add explanation about binary version numbers [PR #1354]
Expand Down Expand Up @@ -241,5 +242,6 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
[PR #1522]: https://github.com/bareos/bareos/pull/1522
[PR #1524]: https://github.com/bareos/bareos/pull/1524
[PR #1531]: https://github.com/bareos/bareos/pull/1531
[PR #1532]: https://github.com/bareos/bareos/pull/1532
[PR #1550]: https://github.com/bareos/bareos/pull/1550
[unreleased]: https://github.com/bareos/bareos/tree/master
117 changes: 89 additions & 28 deletions core/src/plugins/filed/python/vmware/BareosFdPluginVMware.py
Expand Up @@ -127,7 +127,7 @@ def __init__(self, plugindef):
self.vadp = BareosVADPWrapper()
self.vadp.plugin = self
self.vm_config_info_saved = False
self.current_object_index = -1
self.current_object_index = int(time.time())

def parse_plugin_definition(self, plugindef):
"""
Expand Down Expand Up @@ -2958,7 +2958,9 @@ def transform(self, target_datastore_name=None, target_vm_name=None):
"numCoresPerSocket"
]
config_spec.numCPUs = self.config_info["hardware"]["numCPU"]
config_spec.pmem = self._transform_pmem()
# Since vSphere API 7.0.3.0:
if hasattr(config_spec, "pmem"):
config_spec.pmem = self._transform_pmem()
config_spec.pmemFailoverEnabled = self.config_info["pmemFailoverEnabled"]
config_spec.powerOpInfo = self._transform_defaultPowerOps()
# Since vSphere API 7.0.1.0:
Expand All @@ -2982,9 +2984,12 @@ def transform(self, target_datastore_name=None, target_vm_name=None):
config_spec.virtualSMCPresent = self.config_info["hardware"][
"virtualSMCPresent"
]
config_spec.vmOpNotificationToAppEnabled = self.config_info[
"vmOpNotificationToAppEnabled"
]
# Since vSphere API 7.0.3.0:
if hasattr(config_spec, "vmOpNotificationToAppEnabled"):
if "vmOpNotificationToAppEnabled" in self.config_info:
config_spec.vmOpNotificationToAppEnabled = self.config_info[
"vmOpNotificationToAppEnabled"
]

return config_spec

Expand Down Expand Up @@ -3199,6 +3204,10 @@ def _transform_devices(self):
add_device = self._transform_virtual_ethernet_card(device)
elif device["_vimtype"] == "vim.vm.device.VirtualFloppy":
add_device = self._transform_virtual_floppy(device)
elif device["_vimtype"] == "vim.vm.device.VirtualPCIPassthrough":
add_device = self._transform_virtual_pci_passthrough(device)
elif device["_vimtype"] == "vim.vm.device.VirtualEnsoniq1371":
add_device = self._transform_virtual_ensoniq1371(device)
else:
raise RuntimeError(
"Error: Unknown Device Type %s" % (device["_vimtype"])
Expand Down Expand Up @@ -3330,14 +3339,7 @@ def _transform_virtual_cdrom(self, device):
return None

add_device.connectable = self._transform_connectable(device)

# Looks like negative values must not be used for default devices,
# the second VirtualIDEController seems to have key 201, that always seems to be the case.
# Same for VirtualCdrom, getting error "The device '1' is referring to a nonexisting controller '-200'."
add_device.controllerKey = device["controllerKey"]
if device["controllerKey"] not in [200, 201]:
add_device.controllerKey = device["controllerKey"] * -1
add_device.unitNumber = device["unitNumber"]
self._transform_controllerkey_and_unitnumber(add_device, device)

return add_device

Expand Down Expand Up @@ -3365,13 +3367,59 @@ def _transform_virtual_floppy(self, device):
return None

add_device.connectable = self._transform_connectable(device)
self._transform_controllerkey_and_unitnumber(add_device, device)

# Looks like negative values must not be used for default devices,
# the VirtualSIOController seems to have key 400, that seems to be always the case.
add_device.controllerKey = device["controllerKey"]
if device["controllerKey"] not in [400]:
add_device.controllerKey = device["controllerKey"] * -1
add_device.unitNumber = device["unitNumber"]
return add_device

def _transform_virtual_pci_passthrough(self, device):
add_device = vim.vm.device.VirtualPCIPassthrough()
add_device.key = device["key"] * -1
if (
device["backing"]["_vimtype"]
== "vim.vm.device.VirtualPCIPassthrough.DeviceBackingInfo"
):
add_device.backing = vim.vm.device.VirtualPCIPassthrough.DeviceBackingInfo()
add_device.backing.deviceId = device["backing"]["deviceId"]
add_device.backing.deviceName = device["backing"]["deviceName"]
add_device.backing.id = device["backing"]["id"]
add_device.backing.systemId = device["backing"]["systemId"]
add_device.backing.useAutoDetect = device["backing"]["useAutoDetect"]
add_device.backing.vendorId = device["backing"]["vendorId"]
else:
raise RuntimeError(
"Unknown Backing for VirtualPCIPassthrough: %s"
% (device["backing"]["_vimtype"])
)
return None

if device["connectable"]:
add_device.connectable = self._transform_connectable(device)

self._transform_controllerkey_and_unitnumber(add_device, device)

return add_device

def _transform_virtual_ensoniq1371(self, device):
add_device = vim.vm.device.VirtualEnsoniq1371()
add_device.key = device["key"] * -1
if (
device["backing"]["_vimtype"]
== "vim.vm.device.VirtualSoundCard.DeviceBackingInfo"
):
add_device.backing = vim.vm.device.VirtualSoundCard.DeviceBackingInfo()
add_device.backing.deviceName = device["backing"]["deviceName"]
add_device.backing.useAutoDetect = device["backing"]["useAutoDetect"]
else:
raise RuntimeError(
"Unknown Backing for VirtualEnsoniq1371: %s"
% (device["backing"]["_vimtype"])
)
return None

if device["connectable"]:
add_device.connectable = self._transform_connectable(device)

self._transform_controllerkey_and_unitnumber(add_device, device)

return add_device

Expand Down Expand Up @@ -3460,8 +3508,7 @@ def _transform_virtual_disk(self, device):
"reservation"
]

add_device.controllerKey = device["controllerKey"] * -1
add_device.unitNumber = device["unitNumber"]
self._transform_controllerkey_and_unitnumber(add_device, device)
add_device.capacityInBytes = device["capacityInBytes"]

return add_device
Expand Down Expand Up @@ -3536,12 +3583,7 @@ def _transform_virtual_ethernet_card(self, device):

add_device.key = device["key"] * -1
add_device.connectable = self._transform_connectable(device)
# Looks like negative values must not be used for default devices,
# the VirtualPCIController always seems to have key 100.
add_device.controllerKey = device["controllerKey"]
if device["controllerKey"] != 100:
add_device.controllerKey = device["controllerKey"] * -1
add_device.unitNumber = device["unitNumber"]
self._transform_controllerkey_and_unitnumber(add_device, device)
# Note: MAC address preservation is not safe with addressType "manual", the
# server does not check for conflicts. The calling code should check for
# MAC address conflicts before and set addressType to "generated" or "assigned"
Expand Down Expand Up @@ -3675,7 +3717,10 @@ def _transform_managedBy(self):
return managed_by

def _transform_pmem(self):
if self.config_info["pmem"] is None:
if (
self.config_info.get("pmem") is None
or self.config_info["pmem"].get("snapshotMode") is None
):
return None

pmem = vim.vm.VirtualPMem()
Expand Down Expand Up @@ -3842,5 +3887,21 @@ def _transform_VirtualMachineVcpuConfig(self):

return spec_vcpu_configs

def _transform_controllerkey_and_unitnumber(self, add_device, device):
# Looks like negative values must not be used for default devices,
# the second VirtualIDEController seems to have key 201, that always seems to be the case.
# Same for VirtualCdrom, getting error "The device '1' is referring to a nonexisting controller '-200'."
# Looks like negative values must not be used for default devices,
# the VirtualSIOController seems to have key 400, that seems to be always the case.
# Looks like negative values must not be used for default devices,
# the VirtualPCIController always seems to have key 100.
default_devices_controller_keys = [100, 200, 201, 400]
add_device.controllerKey = device["controllerKey"]
if device["controllerKey"] not in default_devices_controller_keys:
add_device.controllerKey = device["controllerKey"] * -1
add_device.unitNumber = device["unitNumber"]

return


# vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab
21 changes: 21 additions & 0 deletions core/src/vmware/vmware_cbt_tool/vmware_cbt_tool.py
Expand Up @@ -29,12 +29,14 @@

from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim, vmodl
from pyVmomi.VmomiSupport import VmomiJSONEncoder

import argparse
import atexit
import getpass
import sys
import os.path
import json

from collections import defaultdict

Expand Down Expand Up @@ -120,6 +122,12 @@ def GetArgs():
default=False,
help="Force SSL certificate verification",
)
parser.add_argument(
"--dumpvmconfig",
action="store_true",
default=False,
help="Dump VM config metadata to JSON file",
)
args = parser.parse_args()

if [args.enablecbt, args.disablecbt, args.resetcbt, args.info, args.listall].count(
Expand Down Expand Up @@ -239,6 +247,8 @@ def main():
print("INFO: VM %s trying to reset CBT now" % (vm.name))
disable_cbt(si, vm)
enable_cbt(si, vm)
if args.dumpvmconfig:
dump_vm_config(si, vm)

except vmodl.MethodFault as e:
print("Caught vmodl fault : " + e.msg)
Expand Down Expand Up @@ -390,6 +400,17 @@ def create_and_remove_snapshot(si, vm):
return False


def dump_vm_config(si, vm):
"""
Dump the VM config data to a JSON file
"""
dump_dir = "./"
dump_filename = dump_dir + vm.name + ".json"
print("INFO: Dumping VM config data to %s" % dump_filename)
with open(dump_filename, "w") as jsonfile:
json.dump(vm, jsonfile, indent=4, cls=VmomiJSONEncoder)


def WaitForTasks(tasks, si):
"""
Given the service instance si and tasks, it returns after all the
Expand Down
Expand Up @@ -304,7 +304,8 @@ As of https://kb.vmware.com/s/article/2075984 manually enabling CBT is currently
usage: vmware_cbt_tool.py [-h] -s HOST [-o PORT] -u USER [-p PASSWORD] -d
DATACENTER [-f FOLDER] [-v VMNAME]
[--vm-uuid VM_UUID] [--enablecbt] [--disablecbt]
[--resetcbt] [--info] [--listall]
[--resetcbt] [--info] [--listall] [--sslverify]
[--dumpvmconfig]

Process args for enabling/disabling/resetting CBT

Expand All @@ -329,9 +330,21 @@ As of https://kb.vmware.com/s/article/2075984 manually enabling CBT is currently
disabled)
--listall List all VMs in the given datacenter with UUID and
containing folder
--sslverify Force SSL certificate verification
--dumpvmconfig Dump VM config metadata to JSON file

Note: the options :command:`--vm-uuid` and :command:`--listall` have been added in version :sinceVersion:`17.2.8: VMware Plugin: new options in vmware\_cbt\_tool.py`, the tool is also able now to process non-ascii character arguments for the :command:`--folder` and :command:`--vmname` arguments and vApp names can be used like folder name components. With :command:`--listall` all VMs in the given datacenter are reported
in a tabular output including instance UUID and containing Folder/vApp name.
.. note::

The options :command:`--vm-uuid` and :command:`--listall` have been added in version :sinceVersion:`17.2.8: VMware Plugin: new options in vmware\_cbt\_tool.py`, the tool is also able now to process non-ascii character arguments for the :command:`--folder` and :command:`--vmname` arguments and vApp names can be used like folder name components.

With :command:`--listall` all VMs in the given datacenter are reported in a tabular output including instance UUID and containing Folder/vApp name.

Without the option :command:`--sslverify` also self-signed SSL certificates will
be accepted, but a warning message will be emitted in this case.

The option :command:`--dumpvmconfig` is helpful to debug issues with the transformation
of VM config metadata for recreating virtual machines.
The JSON file will be written to the current working directory when this option is used.

For the above configuration example, the command to enable CBT would be

Expand Down

0 comments on commit 235cc6a

Please sign in to comment.