Revision fa337742 lib/ovf.py

b/lib/ovf.py
72 72
]
73 73

  
74 74
COMPRESSION_TYPE = "gzip"
75
NO_COMPRESSION = [None, "identity"]
75 76
COMPRESS = "compression"
76 77
DECOMPRESS = "decompression"
77 78
ALLOWED_ACTIONS = [COMPRESS, DECOMPRESS]
78 79

  
80
VMDK = "vmdk"
81
RAW = "raw"
82
COW = "cow"
83
ALLOWED_FORMATS = [RAW, COW, VMDK]
84

  
79 85
# ResourceType values
80 86
RASD_TYPE = {
81 87
  "vcpus": "3",
......
85 91
  "disk": "17",
86 92
}
87 93

  
94
SCSI_SUBTYPE = "lsilogic"
95
VS_TYPE = {
96
  "ganeti": "ganeti-ovf",
97
  "external": "vmx-04",
98
}
99

  
88 100
# AllocationUnits values and conversion
89 101
ALLOCATION_UNITS = {
90 102
  'b': ["bytes", "b"],
......
111 123
VERSION = "version"
112 124

  
113 125
# Instance IDs of System and SCSI controller
114
SYSTEM_ID = 0
115
SCSI_ID = 3
126
INSTANCE_ID = {
127
  "system": 0,
128
  "vcpus": 1,
129
  "memory": 2,
130
  "scsi": 3,
131
}
116 132

  
117 133
# Disk format descriptions
118 134
DISK_FORMAT = {
119
  "raw": "http://en.wikipedia.org/wiki/Byte",
120
  "vmdk": "http://www.vmware.com/interfaces/specifications/vmdk.html"
135
  RAW: "http://en.wikipedia.org/wiki/Byte",
136
  VMDK: "http://www.vmware.com/interfaces/specifications/vmdk.html"
121 137
          "#monolithicSparse",
122
  "cow": "http://www.gnome.org/~markmc/qcow-image-format.html",
138
  COW: "http://www.gnome.org/~markmc/qcow-image-format.html",
123 139
}
124 140

  
125 141

  
......
571 587

  
572 588
  @type tree: ET.ElementTree
573 589
  @ivar tree: XML tree that we are constructing
590
  @type virtual_system_type: string
591
  @ivar virtual_system_type: value of vssd:VirtualSystemType, for external usage
592
    in VMWare this requires to be vmx
574 593
  @type hardware_list: list
575 594
  @ivar hardware_list: list of items prepared for VirtualHardwareSection
595
  @type next_instance_id: int
596
  @ivar next_instance_id: next instance id to be used when creating elements on
597
    hardware_list
576 598

  
577 599
  """
578 600
  def __init__(self, has_gnt_section):
......
593 615
    }
594 616
    if has_gnt_section:
595 617
      env_attribs["xmlns:gnt"] = GANETI_SCHEMA
618
      self.virtual_system_type = VS_TYPE["ganeti"]
619
    else:
620
      self.virtual_system_type = VS_TYPE["external"]
596 621
    self.tree = ET.Element("Envelope", attrib=env_attribs)
597 622
    self.hardware_list = []
623
    # INSTANCE_ID contains statically assigned IDs, starting from 0
624
    self.next_instance_id = len(INSTANCE_ID) # FIXME: hackish
598 625

  
599 626
  def SaveDisksData(self, disks):
600 627
    """Convert disk information to certain OVF sections.
......
605 632
    """
606 633
    references = ET.SubElement(self.tree, "References")
607 634
    disk_section = ET.SubElement(self.tree, "DiskSection")
635
    SubElementText(disk_section, "Info", "Virtual disk information")
608 636
    for counter, disk in enumerate(disks):
609 637
      file_id = "file%s" % counter
610 638
      disk_id = "disk%s" % counter
......
627 655
      # Item in VirtualHardwareSection creation
628 656
      disk_item = ET.Element("Item")
629 657
      SubElementText(disk_item, "rasd:ElementName", disk_id)
630
      SubElementText(disk_item, "rasd:ResourceType", RASD_TYPE["disk"])
631 658
      SubElementText(disk_item, "rasd:HostResource", "ovf:/disk/%s" % disk_id)
632
      SubElementText(disk_item, "rasd:Parent", SCSI_ID)
659
      SubElementText(disk_item, "rasd:InstanceID", self.next_instance_id)
660
      SubElementText(disk_item, "rasd:Parent", INSTANCE_ID["scsi"])
661
      SubElementText(disk_item, "rasd:ResourceType", RASD_TYPE["disk"])
633 662
      self.hardware_list.append(disk_item)
663
      self.next_instance_id += 1
634 664

  
635 665
  def SaveNetworksData(self, networks):
636 666
    """Convert network information to NetworkSection.
......
640 670

  
641 671
    """
642 672
    network_section = ET.SubElement(self.tree, "NetworkSection")
673
    SubElementText(network_section, "Info", "List of logical networks")
643 674
    for counter, network in enumerate(networks):
644 675
      network_name = "%s%s" % (network["mode"], counter)
645 676
      network_attrib = {"ovf:name": network_name}
......
647 678

  
648 679
      # Item in VirtualHardwareSection creation
649 680
      network_item = ET.Element("Item")
681
      SubElementText(network_item, "rasd:Address", network["mac"])
682
      SubElementText(network_item, "rasd:Connection", network_name)
650 683
      SubElementText(network_item, "rasd:ElementName", network_name)
684
      SubElementText(network_item, "rasd:InstanceID", self.next_instance_id)
651 685
      SubElementText(network_item, "rasd:ResourceType",
652 686
        RASD_TYPE["ethernet-adapter"])
653
      SubElementText(network_item, "rasd:Connection", network_name)
654
      SubElementText(network_item, "rasd:Address", network["mac"])
655 687
      self.hardware_list.append(network_item)
688
      self.next_instance_id += 1
656 689

  
657 690
  @staticmethod
658 691
  def _SaveNameAndParams(root, data):
......
720 753
    assert(memory > 0)
721 754
    vs_attrib = {"ovf:id": name}
722 755
    virtual_system = ET.SubElement(self.tree, "VirtualSystem", attrib=vs_attrib)
756
    SubElementText(virtual_system, "Info", "A virtual machine")
723 757

  
724 758
    name_section = ET.SubElement(virtual_system, "Name")
725 759
    name_section.text = name
726 760
    os_attrib = {"ovf:id": "0"}
727
    ET.SubElement(virtual_system, "OperatingSystemSection",
761
    os_section = ET.SubElement(virtual_system, "OperatingSystemSection",
728 762
      attrib=os_attrib)
763
    SubElementText(os_section, "Info", "Installed guest operating system")
729 764
    hardware_section = ET.SubElement(virtual_system, "VirtualHardwareSection")
765
    SubElementText(hardware_section, "Info", "Virtual hardware requirements")
730 766

  
731 767
    # System description
732 768
    system = ET.SubElement(hardware_section, "System")
733 769
    SubElementText(system, "vssd:ElementName", "Virtual Hardware Family")
734
    SubElementText(system, "vssd:InstanceId", SYSTEM_ID)
770
    SubElementText(system, "vssd:InstanceID", INSTANCE_ID["system"])
735 771
    SubElementText(system, "vssd:VirtualSystemIdentifier", name)
736
    SubElementText(system, "vssd:VirtualSystemType", "ganeti-ovf")
772
    SubElementText(system, "vssd:VirtualSystemType", self.virtual_system_type)
737 773

  
738 774
    # Item for vcpus
739 775
    vcpus_item = ET.SubElement(hardware_section, "Item")
740 776
    SubElementText(vcpus_item, "rasd:ElementName",
741 777
      "%s virtual CPU(s)" % vcpus)
742
    SubElementText(vcpus_item, "rasd:InstanceID", "1")
778
    SubElementText(vcpus_item, "rasd:InstanceID", INSTANCE_ID["vcpus"])
743 779
    SubElementText(vcpus_item, "rasd:ResourceType", RASD_TYPE["vcpus"])
744 780
    SubElementText(vcpus_item, "rasd:VirtualQuantity", vcpus)
745 781

  
......
747 783
    memory_item = ET.SubElement(hardware_section, "Item")
748 784
    SubElementText(memory_item, "rasd:AllocationUnits", "byte * 2^20")
749 785
    SubElementText(memory_item, "rasd:ElementName", "%sMB of memory" % memory)
750
    SubElementText(memory_item, "rasd:InstanceID", "2")
786
    SubElementText(memory_item, "rasd:InstanceID", INSTANCE_ID["memory"])
751 787
    SubElementText(memory_item, "rasd:ResourceType", RASD_TYPE["memory"])
752 788
    SubElementText(memory_item, "rasd:VirtualQuantity", memory)
753 789

  
754 790
    # Item for scsi controller
755 791
    scsi_item = ET.SubElement(hardware_section, "Item")
756
    SubElementText(scsi_item, "rasd:Address", SYSTEM_ID)
792
    SubElementText(scsi_item, "rasd:Address", INSTANCE_ID["system"])
757 793
    SubElementText(scsi_item, "rasd:ElementName", "scsi_controller0")
794
    SubElementText(scsi_item, "rasd:InstanceID", INSTANCE_ID["scsi"])
795
    SubElementText(scsi_item, "rasd:ResourceSubType", SCSI_SUBTYPE)
758 796
    SubElementText(scsi_item, "rasd:ResourceType", RASD_TYPE["scsi-controller"])
759
    SubElementText(scsi_item, "rasd:InstanceId", "3")
760 797

  
761 798
    # Other items - from self.hardware_list
762
    for counter, item in enumerate(self.hardware_list):
763
      SubElementText(item, "rasd:InstanceID", counter + 4)
799
    for item in self.hardware_list:
764 800
      hardware_section.append(item)
765 801

  
766 802
  def PrettyXmlDump(self):
......
1324 1360
                                   " paths or paths outside main OVF directory")
1325 1361
      disk, _ = os.path.splitext(disk_name)
1326 1362
      disk_path = utils.PathJoin(self.input_dir, disk_name)
1327
      if disk_compression:
1363
      if disk_compression not in NO_COMPRESSION:
1328 1364
        _, disk_path = self._CompressDisk(disk_path, disk_compression,
1329 1365
          DECOMPRESS)
1330 1366
        disk, _ = os.path.splitext(disk)
......
1709 1745
    logging.info("Preparing tarball for the OVF package")
1710 1746
    open(tar_path, mode="w").close()
1711 1747
    ova_package = tarfile.open(name=tar_path, mode="w")
1712
    for file_name in files_list:
1713
      ova_package.add(file_name)
1748
    for file_path in files_list:
1749
      file_name = os.path.basename(file_path)
1750
      ova_package.add(file_path, arcname=file_name)
1714 1751
    ova_package.close()
1715 1752

  
1716 1753
  def Save(self):

Also available in: Unified diff