From 6dafbaf7bcea3380d9aa8fd7dd3b7fa9fc18859d Mon Sep 17 00:00:00 2001 From: Stephan Duehr Date: Thu, 18 Jun 2020 21:35:07 +0000 Subject: [PATCH] vmware: Optional config file The VMware plugin now allows to use an optional config file to specify plugin options. By cmake check for physicalSectorSize member in VixDiskLibCreateParams the build of bareos_vadp_dumper now works with VDDK 6.5.2, 6.7.3 an 7.0 --- .../src/plugins/filed/BareosFdPluginVMware.py | 102 ++++++++++++++++++ .../vmware/vadp_dumper/bareos_vadp_dumper.cc | 12 +++ .../source/TasksAndConcepts/Plugins.rst | 33 ++++++ .../etc/bareos/VMwareTest.ini.in | 9 ++ .../bareos-dir.d/fileset/VMwareTest.conf.in | 2 +- 5 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/VMwareTest.ini.in diff --git a/core/src/plugins/filed/BareosFdPluginVMware.py b/core/src/plugins/filed/BareosFdPluginVMware.py index a64ff853600..7f7d0ce7c94 100644 --- a/core/src/plugins/filed/BareosFdPluginVMware.py +++ b/core/src/plugins/filed/BareosFdPluginVMware.py @@ -39,6 +39,7 @@ import ssl import socket import hashlib +import ConfigParser as configparser from pyVim.connect import SmartConnect, Disconnect from pyVmomi import vim @@ -80,7 +81,17 @@ def __init__(self, context, plugindef): bareosfd.RegisterEvents(context, self.events) self.mandatory_options_default = ["vcserver", "vcuser", "vcpass"] self.mandatory_options_vmname = ["dc", "folder", "vmname"] + self.optional_options = [ + "uuid", + "vcthumbprint", + "transport", + "log_path", + "localvmdk", + "vadp_dumper_verbose", + ] self.utf8_options = ["vmname", "folder"] + self.config = None + self.config_parsed = False self.vadp = BareosVADPWrapper() self.vadp.plugin = self @@ -95,10 +106,93 @@ def parse_plugin_definition(self, context, plugindef): "parse_plugin_definition() was called in module %s\n" % (__name__), ) super(BareosFdPluginVMware, self).parse_plugin_definition(context, plugindef) + + # if the option config_file is present, parse the given file + config_file = self.options.get("config_file") + if config_file: + if not self.parse_config_file(context): + return bRCs["bRC_Error"] + self.vadp.options = self.options return bRCs["bRC_OK"] + def parse_config_file(self, context): + """ + Parse the config file given in the config_file plugin option + """ + if self.config_parsed: + return True + + bareosfd.DebugMessage( + context, + 100, + "BareosFdPluginVMware: parse_config_file(): parse %s\n" + % (self.options["config_file"]), + ) + + self.config = configparser.ConfigParser() + + try: + self.config.readfp(open(self.options["config_file"])) + except IOError as err: + bareosfd.JobMessage( + context, + bJobMessageType["M_FATAL"], + "BareosFdPluginVMware: Error reading config file %s: %s\n" + % (self.options["config_file"], err.strerror), + ) + return False + + self.config_parsed = True + + return self.check_config(context) + + def check_config(self, context): + """ + Check the configuration and set or override options if necessary + """ + bareosfd.DebugMessage(context, 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): + bareosfd.JobMessage( + context, + bJobMessageType["M_FATAL"], + "BareosFdPluginVMware: Section [%s] missing in config file %s\n" + % (section, self.options["config_file"]), + ) + return False + + for option in self.config.options(section): + if option not in allowed_options: + bareosfd.JobMessage( + context, + bJobMessageType["M_FATAL"], + "BareosFdPluginVMware: Invalid option %s in Section [%s] in config file %s\n" + % (option, section, self.options["config_file"]), + ) + return False + + plugin_option = self.options.get(option) + if plugin_option: + bareosfd.JobMessage( + context, + bJobMessageType["M_WARNING"], + "BareosFdPluginVMware: Overriding plugin option %s:%s from config file %s\n" + % (option, repr(plugin_option), self.options["config_file"]), + ) + + self.options[option] = self.config.get(section, option) + + return True + def check_options(self, context, mandatory_options=None): """ Check Plugin options @@ -1419,6 +1513,7 @@ def start_dumper(self, context, cmd): # -C: Create local VMDK # -d: Specify local VMDK name # -f: Specify forced transport method + # -v - Verbose output bareos_vadp_dumper_opts = {} bareos_vadp_dumper_opts["dump"] = "-S -D -M" if "transport" in self.options: @@ -1443,6 +1538,9 @@ def start_dumper(self, context, cmd): " -f %s" % self.options["transport"] ) + if self.options.get("vadp_dumper_verbose") == "yes": + bareos_vadp_dumper_opts[cmd] = "-v " + bareos_vadp_dumper_opts[cmd] + bareosfd.DebugMessage( context, 100, @@ -1470,7 +1568,11 @@ def start_dumper(self, context, cmd): "start_dumper(): bareos_vadp_dumper_command_args: %s\n" % (repr(bareos_vadp_dumper_command_args)), ) + log_path = "/var/log/bareos" + if self.options.get("log_path"): + log_path = self.options["log_path"] + stderr_log_fd = tempfile.NamedTemporaryFile(dir=log_path, delete=False) bareos_vadp_dumper_process = None diff --git a/core/src/vmware/vadp_dumper/bareos_vadp_dumper.cc b/core/src/vmware/vadp_dumper/bareos_vadp_dumper.cc index 346117eab0e..3856719ee06 100644 --- a/core/src/vmware/vadp_dumper/bareos_vadp_dumper.cc +++ b/core/src/vmware/vadp_dumper/bareos_vadp_dumper.cc @@ -681,6 +681,14 @@ static inline void do_vixdisklib_open(const char* key, VixDiskLib_FreeErrorText(error_txt); goto bail_out; } +#ifdef VIXDISKLIBCREATEPARAMS_HAS_PHYSICALSECTORSIZE + if (verbose) { + fprintf(stderr, "DiskInfo logicalSectorSize: %u\n", + info->logicalSectorSize); + fprintf(stderr, "DiskInfo physicalSectorSize: %u\n", + info->physicalSectorSize); + } +#endif } if (verbose) { @@ -737,6 +745,10 @@ static inline void do_vixdisklib_create(const char* key, } else { createParams.diskType = VIXDISKLIB_DISK_MONOLITHIC_SPARSE; } +#ifdef VIXDISKLIBCREATEPARAMS_HAS_PHYSICALSECTORSIZE + createParams.physicalSectorSize = VIXDISKLIB_SECTOR_SIZE; + createParams.logicalSectorSize = VIXDISKLIB_SECTOR_SIZE; +#endif createParams.hwVersion = 7; /* for ESX(i)4 */ err = VixDiskLib_Create(connection, disk_path, &createParams, NULL, NULL); if (VIX_FAILED(err)) { diff --git a/docs/manuals/source/TasksAndConcepts/Plugins.rst b/docs/manuals/source/TasksAndConcepts/Plugins.rst index dfa97bddabe..a4076ffb137 100644 --- a/docs/manuals/source/TasksAndConcepts/Plugins.rst +++ b/docs/manuals/source/TasksAndConcepts/Plugins.rst @@ -405,6 +405,39 @@ Before this, it was only possible specify VMs contained in vApps by using the in Note that it must be the so called vSphere instance UUID, not the BIOS UUID which is shown inside a VM when using for example :command:`dmidecode`. The :command:`vmware_cbt_tool.py` utility was adapted accordingly (see below for details). +Since :sinceVersion:`20.2.0: VMware Plugin: config file` it is optionally possible to use a configuration file on the system running the Bareos File Daemon. This can be useful to specify common plugin options instead of having to repeat them in every Fileset. Options which are specifed in the config file will override options from the Fileset, if the same option is given there, too. A warning will be issued in that case. Use the plugin option **config_file** to specify the config file name as in the following example: + +.. code-block:: bareosconfig + :caption: bareos-dir.conf: VMware Plugin Job and FileSet definition with config_file + + FileSet { + Name = "vm-websrv1_fileset" + + Include { + Options { + signature = MD5 + Compression = GZIP + } + Plugin = "python:module_path=/usr/lib64/bareos/plugins:module_name=bareos-fd-vmware:dc=mydc1:folder=/webservers:vmname=websrv1:config_file=/etc/bareos/vmware-plugin.ini" + } + } + +And the config file as follows: + +.. code-block:: bareosconfig + :caption: /etc/bareos/vmware-plugin.ini + + [vmware_plugin_options] + vcserver=vcenter.example.org + vcuser=bakadm@vsphere.local + vcpass=Bak.Adm-1234 + +.. note:: + + Do not use quotes in the above config file, it is processed by the Python ConfigParser module and the quotes would not be stripped from the string. + + + Backup ^^^^^^ diff --git a/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/VMwareTest.ini.in b/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/VMwareTest.ini.in new file mode 100644 index 00000000000..b56cd2cd685 --- /dev/null +++ b/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/VMwareTest.ini.in @@ -0,0 +1,9 @@ +[vmware_plugin_options] +dc=@vmware_datacenter@ +folder=@vmware_folder@ +vmname=@vmware_vm_name@ +vcserver=@vmware_server@ +vcuser=@vmware_user@ +vcpass=@vmware_password@ +log_path=@logdir@ +vadp_dumper_verbose=yes diff --git a/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/bareos-dir.d/fileset/VMwareTest.conf.in b/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/bareos-dir.d/fileset/VMwareTest.conf.in index 917bd1cca80..103c1b193c2 100644 --- a/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/bareos-dir.d/fileset/VMwareTest.conf.in +++ b/systemtests/tests/python-fd-vmware-plugin-test/etc/bareos/bareos-dir.d/fileset/VMwareTest.conf.in @@ -14,7 +14,7 @@ FileSet { #:vcserver=vcenter.example.org #:vcuser=bakadm@vsphere.local #:vcpass=Bak.Adm-1234" - Plugin = "python:module_path=@python_plugin_module_src_test_dir@:module_name=bareos-fd-vmware:dc=@vmware_datacenter@:folder=@vmware_folder@:vmname=@vmware_vm_name@:vcserver=@vmware_server@:vcuser=@vmware_user@:vcpass=@vmware_password@" + Plugin = "python:module_path=@python_plugin_module_src_test_dir@:module_name=bareos-fd-vmware:config_file=@confdir@/VMwareTest.ini" }