Skip to content

Commit

Permalink
Merge pull request #1390
Browse files Browse the repository at this point in the history
VMware Plugin: fix restore to different vmname
  • Loading branch information
arogge committed Mar 1, 2023
2 parents 7cec0e6 + a8a688b commit ead1c4c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 13 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -37,6 +37,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
- Fix gcc warnings in ndmjob program [PR #1343]
- filed: avoid reading from ephemeral buffer [PR #1373]
- checkpoints: fix performance drop on big volume restores [PR #1345]
- VMware Plugin: fix restore to different vmname [PR #1390]

### Documentation
- add explanation about binary version numbers [PR #1354]
Expand Down Expand Up @@ -69,4 +70,5 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https:
[PR #1378]: https://github.com/bareos/bareos/pull/1378
[PR #1387]: https://github.com/bareos/bareos/pull/1387
[PR #1389]: https://github.com/bareos/bareos/pull/1389
[PR #1390]: https://github.com/bareos/bareos/pull/1390
[unreleased]: https://github.com/bareos/bareos/tree/master
32 changes: 23 additions & 9 deletions core/src/plugins/filed/python/vmware/BareosFdPluginVMware.py
Expand Up @@ -110,7 +110,14 @@ def __init__(self, plugindef):
"restore_resourcepool",
"restore_datastore",
"restore_powerstate",
"poweron_timeout",
"config_file",
]
self.allowed_options = (
self.mandatory_options_default
+ self.mandatory_options_vmname
+ self.optional_options
)
self.utf8_options = ["vmname", "folder"]
self.config = None
self.config_parsed = False
Expand Down Expand Up @@ -175,11 +182,6 @@ def check_config(self):
"""
bareosfd.DebugMessage(100, "BareosFdPluginVMware: check_config()\n")
mandatory_sections = ["vmware_plugin_options"]
allowed_options = (
self.mandatory_options_default
+ self.mandatory_options_vmname
+ self.optional_options
)

for section in mandatory_sections:
if not self.config.has_section(section):
Expand All @@ -191,7 +193,7 @@ def check_config(self):
return False

for option in self.config.options(section):
if option not in allowed_options:
if option not in self.allowed_options:
bareosfd.JobMessage(
bareosfd.M_FATAL,
"BareosFdPluginVMware: Invalid option %s in Section [%s] in config file %s\n"
Expand Down Expand Up @@ -266,6 +268,15 @@ def check_plugin_options(self, mandatory_options=None):

return bareosfd.bRC_Error

invalid_options = ",".join(list(set(self.options) - set(self.allowed_options)))
if invalid_options:
bareosfd.JobMessage(
bareosfd.M_FATAL,
"BareosFdPluginVMware: Invalid plugin options: %s\n"
% (invalid_options),
)
return bareosfd.bRC_Error

for option in self.utf8_options:
if self.options.get(option):
# make sure to convert to utf8
Expand Down Expand Up @@ -1442,7 +1453,9 @@ def create_vm(self):
return False
self.vmfs_vm_path_changed = True

config = transformer.transform(target_datastore_name=datastore_name)
config = transformer.transform(
target_datastore_name=datastore_name, target_vm_name=self.options["vmname"]
)

for child in self.si.content.rootFolder.childEntity:
if child.name == self.options["dc"]:
Expand Down Expand Up @@ -2626,7 +2639,7 @@ def __init__(self, config_info):
self.backing_filename_snapshot_rex = re.compile(r"(-\d{6})\.vmdk$")
self.target_datastore_name = None

def transform(self, target_datastore_name=None):
def transform(self, target_datastore_name=None, target_vm_name=None):
config_spec = vim.vm.ConfigSpec()
self.target_datastore_name = target_datastore_name
config_spec.alternateGuestName = self.config_info["alternateGuestName"]
Expand Down Expand Up @@ -2668,6 +2681,8 @@ def transform(self, target_datastore_name=None):
]
config_spec.migrateEncryption = self.config_info["migrateEncryption"]
config_spec.name = self.config_info["name"]
if target_vm_name:
config_spec.name = target_vm_name
config_spec.nestedHVEnabled = self.config_info["nestedHVEnabled"]
config_spec.numCoresPerSocket = self.config_info["hardware"][
"numCoresPerSocket"
Expand Down Expand Up @@ -3408,7 +3423,6 @@ def _transform_vAppConfig(self):
return vapp_config_spec

def _transform_VAppIpAssignmentInfo(self, ip_assignment_info):

ip_assignment = vim.vApp.IPAssignmentInfo()
ip_assignment.ipAllocationPolicy = ip_assignment_info["ipAllocationPolicy"]
ip_assignment.ipProtocol = ip_assignment_info["ipProtocol"]
Expand Down
Expand Up @@ -39,6 +39,10 @@ Current limitations amongst others are:
When creating a VM from template or OVA, the parameter **ddb.adaptertype** in the .vmdk file is changed from **lsilogic** to **buslogic** although SCSI adapter type is VMware Paravirtual or LSI Logic. Restore works to the same still existing VM, but when such a VM was completely removed so that the plugin recreates it via vSphere API, the newly created disk will have **ddb.adaptertype** set to **lsilogic** with different numbers of cylinders and heads which causes the restore to fail due to disk geometry mismatch. Currently there's no known workaround.


.. limitation:: VMware Plugin: Restore to different vCenter Server is unsupported.

Restore to a different vCenter Server was not tested, it will probably not work, so it is currently unsupported.


Requirements
^^^^^^^^^^^^
Expand Down Expand Up @@ -338,6 +342,35 @@ Since :sinceVersion:`22.0.0: VMware Plugin: recreate VMs` the plugin will recrea

When restoring a VM to a different location while the backed up VM still exists and a static IP is configured within the VM: To avoid IP address conflicts, make sure to also add the plugin option :command:`restore_powerstate=off` and disable or change the network adapter configuration of the VM before powering it on.

To restore to a different folder, datacenter, host, cluster, resource pool or datastore, the corresponding plugin options must be passed. All plugin options which have been effective at backup time will be passed on restore and each individual option can be overridden by passing an options string at restore time. For example, to restore to a different VM name and different datastore, pass the following plugin option string:

.. code-block:: bconsole
:caption: Example restore plugin options string

python:datastore=datastore2:vmname=testvm1restored

All other plugin options which are not passed explicitily on restore will be the same as at backup time.

Note that most plugin options are used for backup and restore, but there are some which can be only used on restore, for example to prevent from powering on the VM automatically after restore if it was powered on at backup time, use this plugin options string:

.. code-block:: bconsole
:caption: Example restore plugin options string with powerstate

python:restore_datastore=datastore2:vmname=testvm1restored:restore_powerstate=off

See below for a complete restore example and description of all plugin options.


Restore using Bareos WebUI
''''''''''''''''''''''''''

Since :sinceVersion:`22.0.0: VMware Plugin: Restore using WebUI` it is possible to use the Bareos WebUI to restore VMware Plugin jobs.

When using the WebUI to restore a VMware Plugin job, it is **important** to set *Merge all client file sets* to **no** and *Merge all jobs up to the last full backup together* to **yes**. In the *File selection* all files must be selected. Only restoring selected virtual disks will probably not work and is currently unsupported. The Bareos WebUI will detect if a plugin based jobs is restore and will then show an additional *Plugin options* field, here a plugin options string starting with ``python:`` as described above can be entered.

.. image:: /include/images/bareos-webui-restore-with-pluginoptions.*
:width: 80.0%

Restore to local VMDK File
^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -484,8 +517,10 @@ After the restore process has finished, the restored VMDK files can be found und
Description of all Plugin Options
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Note that all plugin options that have been used at backup time, are passed on restore. The VM metadata is saved in restoreobjects both in the catalog DB and volume, it is used on restore if the VM must be recreated. Most options are used for both backup and restore, some which can be only used for restore start with **restore_**. Where nothing special is mentioned regarding restore, it is normally not necessary or useful to override that option on restore.

vcserver (mandatory on backup)
Hostname (FQDN) or IP address of vCenter server
Hostname (FQDN) or IP address of vCenter server. Restore to different vCenter Server is unsupported.

vcuser (mandatory on backup)
Username for API access to vCenter, eg. administrator@vsphere.local
Expand All @@ -494,13 +529,13 @@ vcpass (mandatory on backup)
Password for API access to vCenter

dc (mandatory on backup)
Datacenter name
Datacenter name. This can be optionally passed on restore to recreate the VM in a different datacenter.

folder (mandatory on backup)
The VM folder in which the VM to be backed up resides. This must be given like a UNIX path with ``/`` as separator.
The VM folder in which the VM to be backed up resides. This must be given like a UNIX path with ``/`` as separator. On restore if defined will recreate the VM in a different folder. The given folder must exist before starting the restore.

vmname (mandatory on backup)
The name of the VM to be backed up.
The name of the VM to be backed up. On restore it is possible to override this option in order to recreate the VM with a different name.

vcthumbprint (optional)
Thumbprint of the vCenter SSL Certificate, which is the SHA1 checksum of the SSL Certificate
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit ead1c4c

Please sign in to comment.