Signed-off-by: Agata Murawska <[email protected]>
---
 lib/ovf.py |  161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 161 insertions(+), 0 deletions(-)

diff --git a/lib/ovf.py b/lib/ovf.py
index d413ede..254298c 100644
--- a/lib/ovf.py
+++ b/lib/ovf.py
@@ -1168,8 +1168,18 @@ class OVFExporter(Converter):
   @ivar output_path: complete path to .ovf file
   @type config_parser: L{ConfigParserWithDefaults}
   @ivar config_parser: parser for the config.ini file
+  @type results_disk: list
+  @ivar results_disk: list of dictionaries of disk options from config.ini
+  @type results_network: list
+  @ivar results_network: list of dictionaries of network options form 
config.ini
   @type results_name: string
   @ivar results_name: name of the instance
+  @type results_vcpus: string
+  @ivar results_vcpus: number of VCPUs
+  @type results_memory: string
+  @ivar results_memory: RAM memory in MB
+  @type results_ganeti: dict
+  @ivar results_ganeti: dictionary of Ganeti-specific options from config.ini
 
   """
   def _ReadInputData(self, input_path):
@@ -1219,6 +1229,150 @@ class OVFExporter(Converter):
       raise errors.OpPrereqError("No instance name found")
     return name
 
+  def _ParseVCPUs(self):
+    """Parses vcpus number from config file.
+
+    @rtype: int
+    @return: number of virtual CPUs
+
+    @raises errors.OpPrereqError: if number of VCPUs equals 0
+
+    """
+    vcpus = self.config_parser.getint(constants.INISECT_BEP, "vcpus")
+    if vcpus == 0:
+      raise errors.OpPrereqError("No CPU information found")
+    return vcpus
+
+  def _ParseMemory(self):
+    """Parses vcpus number from config file.
+
+    @rtype: int
+    @return: amount of memory in MB
+
+    @raises errors.OpPrereqError: if amount of memory equals 0
+
+    """
+    memory = self.config_parser.getint(constants.INISECT_BEP, "memory")
+    if memory == 0:
+      raise errors.OpPrereqError("No memory information found")
+    return memory
+
+  def _ParseGaneti(self):
+    """Parses Ganeti data from config file.
+
+    @rtype: dictionary
+    @return: dictionary of Ganeti-specific options
+
+    """
+    results = {}
+    # hypervisor
+    results["hypervisor"] = {}
+    results["hypervisor"]["name"] = \
+      self.config_parser.get(constants.INISECT_INS, "hypervisor")
+    pairs = self.config_parser.items(constants.INISECT_HYP)
+    for (name, value) in pairs:
+      results["hypervisor"][name] = value
+    if results["hypervisor"].get("name") is None:
+      raise errors.OpPrereqError("No hypervisor information found")
+    # os
+    results["os"] = {}
+    results["os"]["name"] = \
+      self.config_parser.get(constants.INISECT_EXP, "os")
+    pairs = self.config_parser.items(constants.INISECT_OSP)
+    for (name, value) in pairs:
+      results["os"][name] = value
+    if results["os"].get("name") is None:
+      raise errors.OpPrereqError("No operating system information found")
+    # other
+    results["disk_template"] = \
+      self.config_parser.get(constants.INISECT_INS, "disk_template")
+    results["auto_balance"] = \
+      self.config_parser.get(constants.INISECT_BEP, "auto_balance")
+    results["tags"] = \
+      self.config_parser.get(constants.INISECT_INS, "tags")
+    results["version"] = \
+      self.config_parser.get(constants.INISECT_EXP, "version")
+    return results
+
+  def _ParseNetworks(self):
+    """Parses network data from config file.
+
+    @rtype: list
+    @return: list of dictionaries of network options
+
+    @raises errors.OpPrereqError: then network mode is not recognized
+
+    """
+    nics_count = self.config_parser.getint(constants.INISECT_INS, "nic_count")
+    results = []
+    for counter in range(nics_count):
+      results.append({})
+      results[counter]["mode"] = \
+        self.config_parser.get(constants.INISECT_INS, "nic%s_mode" % counter)
+      results[counter]["mac"] = \
+        self.config_parser.get(constants.INISECT_INS, "nic%s_mac" % counter)
+      results[counter]["ip"] = \
+        self.config_parser.get(constants.INISECT_INS, "nic%s_ip" % counter)
+      results[counter]["link"] = \
+        self.config_parser.get(constants.INISECT_INS, "nic%s_link" % counter)
+      if results[counter]["mode"] not in ["bridged", "routed"]:
+        raise errors.OpPrereqError("Network mode %s not recognized" %
+                                   results[counter]["mode"])
+    return results
+
+  def _GetDiskOptions(self, disk_file, compression):
+    """Convert the disk and gather disk info for .ovf file.
+
+    @type disk_file: string
+    @param disk_file: name of the disk (without the full path)
+    @type compression: bool
+    @param compression: whether the disk should be compressed or not
+
+    @raise errors.OpPrereqError: when disk image does not exist
+
+    """
+    disk_path = utils.PathJoin(self.input_dir, disk_file)
+    results = {}
+    if not os.path.isfile(disk_path):
+      raise errors.OpPrereqError("Disk image does not exist: %s" % disk_path)
+    if os.path.dirname(disk_file):
+      raise errors.OpPrereqError("Unsafe path for the disk: %s" % disk_path)
+    (disk_name, _) = os.path.splitext(disk_file)
+    new_disk_name = "%s.%s" % (disk_name, self.options.disk_format)
+    new_disk_path = utils.PathJoin(self.output_dir, new_disk_name)
+    self._ConvertDisk(self.options.disk_format, disk_path, new_disk_path)
+    results["format"] = self.options.disk_format
+    results["virt-size"] = self._GetDiskQemuInfo(new_disk_path,
+      "virtual size: \S+ \((\S+) bytes\)")
+    if compression:
+      skip_removing = disk_path == new_disk_path
+      # we do not want to delete the original disk
+      new_disk_path = self._CompressDisk(new_disk_path, "gzip", "compress",
+        skip_removing=skip_removing)
+      new_disk_name = "%s%s" % (new_disk_name, COMPRESSION_EXT)
+      results["compression"] = "gzip"
+    results["real-size"] = os.path.getsize(new_disk_path)
+    results["path"] = new_disk_name # TODO: path or name (after checking)?
+    self.references_files.append(new_disk_path)
+    return results
+
+  def _ParseDisks(self):
+    """Parses disk data from config file.
+
+    @rtype: list
+    @return: list of dictionaries of disk options
+
+    """
+    disk_count = self.config_parser.getint(constants.INISECT_INS, "disk_count")
+    results = []
+    for counter in range(disk_count):
+      results.append({})
+      disk_file = \
+        self.config_parser.get(constants.INISECT_INS, "disk%s_dump" % counter)
+      results[counter] = self._GetDiskOptions(disk_file,
+        self.options.compression)
+    return results
+
   def Parse(self):
     """Parses the data and creates a structure containing all required info.
 
@@ -1229,7 +1383,14 @@ class OVFExporter(Converter):
       raise errors.OpPrereqError("Failed to create directory %s:\n\t%s" %
                                  (self.output_dir, err))
 
+    self.references_files = []
     self.results_name = self._ParseName()
+    self.results_vcpus = self._ParseVCPUs()
+    self.results_memory = self._ParseMemory()
+    if not self.options.ext_usage:
+      self.results_ganeti = self._ParseGaneti()
+    self.results_network = self._ParseNetworks()
+    self.results_disk = self._ParseDisks()
 
   def _PrepareManifest(self, path):
     """Creates manifest for all the files in OVF package.
-- 
1.7.3.1

Reply via email to