| Clark Boylan | edd6048 | 2015-03-27 09:19:57 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 2 | # | 
|  | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | 
|  | 4 | # not use this file except in compliance with the License. You may obtain | 
|  | 5 | # a copy of the License at | 
|  | 6 | # | 
|  | 7 | #      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | # | 
|  | 9 | # Unless required by applicable law or agreed to in writing, software | 
|  | 10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
|  | 11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
|  | 12 | # License for the specific language governing permissions and limitations | 
|  | 13 | # under the License. | 
|  | 14 |  | 
|  | 15 | # This small script updates the libvirt CPU map to add a gate64 cpu model | 
|  | 16 | # that can be used to enable a common 64bit capable feature set across | 
|  | 17 | # devstack nodes so that features like nova live migration work. | 
|  | 18 |  | 
|  | 19 | import sys | 
|  | 20 | import xml.etree.ElementTree as ET | 
|  | 21 | from xml.dom import minidom | 
|  | 22 |  | 
|  | 23 |  | 
|  | 24 | def update_cpu_map(tree): | 
|  | 25 | root = tree.getroot() | 
|  | 26 | cpus = root#.find("cpus") | 
|  | 27 | x86 = None | 
|  | 28 | for arch in cpus.findall("arch"): | 
|  | 29 | if arch.get("name") == "x86": | 
|  | 30 | x86 = arch | 
|  | 31 | break | 
|  | 32 | if x86 is not None: | 
|  | 33 | # Create a gate64 cpu model that is core2duo less monitor and pse36 | 
|  | 34 | gate64 = ET.SubElement(x86, "model") | 
|  | 35 | gate64.set("name", "gate64") | 
|  | 36 | ET.SubElement(gate64, "vendor").set("name", "Intel") | 
|  | 37 | ET.SubElement(gate64, "feature").set("name", "fpu") | 
|  | 38 | ET.SubElement(gate64, "feature").set("name", "de") | 
|  | 39 | ET.SubElement(gate64, "feature").set("name", "pse") | 
|  | 40 | ET.SubElement(gate64, "feature").set("name", "tsc") | 
|  | 41 | ET.SubElement(gate64, "feature").set("name", "msr") | 
|  | 42 | ET.SubElement(gate64, "feature").set("name", "pae") | 
|  | 43 | ET.SubElement(gate64, "feature").set("name", "mce") | 
|  | 44 | ET.SubElement(gate64, "feature").set("name", "cx8") | 
|  | 45 | ET.SubElement(gate64, "feature").set("name", "apic") | 
|  | 46 | ET.SubElement(gate64, "feature").set("name", "sep") | 
|  | 47 | ET.SubElement(gate64, "feature").set("name", "pge") | 
|  | 48 | ET.SubElement(gate64, "feature").set("name", "cmov") | 
|  | 49 | ET.SubElement(gate64, "feature").set("name", "pat") | 
|  | 50 | ET.SubElement(gate64, "feature").set("name", "mmx") | 
|  | 51 | ET.SubElement(gate64, "feature").set("name", "fxsr") | 
|  | 52 | ET.SubElement(gate64, "feature").set("name", "sse") | 
|  | 53 | ET.SubElement(gate64, "feature").set("name", "sse2") | 
|  | 54 | ET.SubElement(gate64, "feature").set("name", "vme") | 
|  | 55 | ET.SubElement(gate64, "feature").set("name", "mtrr") | 
|  | 56 | ET.SubElement(gate64, "feature").set("name", "mca") | 
|  | 57 | ET.SubElement(gate64, "feature").set("name", "clflush") | 
|  | 58 | ET.SubElement(gate64, "feature").set("name", "pni") | 
|  | 59 | ET.SubElement(gate64, "feature").set("name", "nx") | 
|  | 60 | ET.SubElement(gate64, "feature").set("name", "ssse3") | 
|  | 61 | ET.SubElement(gate64, "feature").set("name", "syscall") | 
|  | 62 | ET.SubElement(gate64, "feature").set("name", "lm") | 
|  | 63 |  | 
|  | 64 |  | 
|  | 65 | def format_xml(root): | 
|  | 66 | # Adapted from http://pymotw.com/2/xml/etree/ElementTree/create.html | 
|  | 67 | # thank you dhellmann | 
|  | 68 | rough_string = ET.tostring(root, encoding="UTF-8") | 
|  | 69 | dom_parsed = minidom.parseString(rough_string) | 
|  | 70 | return dom_parsed.toprettyxml("  ", encoding="UTF-8") | 
|  | 71 |  | 
|  | 72 |  | 
|  | 73 | def main(): | 
|  | 74 | if len(sys.argv) != 2: | 
|  | 75 | raise Exception("Must pass path to cpu_map.xml to update") | 
|  | 76 | cpu_map = sys.argv[1] | 
|  | 77 | tree = ET.parse(cpu_map) | 
|  | 78 | for model in tree.getroot().iter("model"): | 
|  | 79 | if model.get("name") == "gate64": | 
|  | 80 | # gate64 model is already present | 
|  | 81 | return | 
|  | 82 | update_cpu_map(tree) | 
|  | 83 | pretty_xml = format_xml(tree.getroot()) | 
|  | 84 | with open(cpu_map, 'w') as f: | 
|  | 85 | f.write(pretty_xml) | 
|  | 86 |  | 
|  | 87 |  | 
|  | 88 | if __name__ == "__main__": | 
|  | 89 | main() |