Statistics
| Branch: | Revision:

iof-tools / gen-rspec.py @ 0b1c84fc

History | View | Annotate | Download (4.99 KB)

1
#!/usr/bin/env python
2
import xml.etree.ElementTree as ET
3

    
4
try:
5
    from StringIO import StringIO
6
except ImportError:
7
    from io import StringIO
8
from subprocess import check_output
9
from argparse import ArgumentParser
10
import sys
11

    
12
from const import AVAILABLE, COMPONENT_ID, COMPONENT_NAME, FOOTER_TEMPLATE, \
13
    HARDWARE_TYPE, HEADER_TEMPLATE, LOCATION, NAME, NODE, NODE_TEMPLATE, NOW, \
14
    TRUE, X, Y, Z
15

    
16

    
17
def matches(name, filters, nodes):
18
    if len(nodes) > 0:
19
        return name in nodes
20
    if len(filters) == 0:
21
        return True
22
    for f in filters:
23
        if name.startswith(f):
24
            return True
25
    return False
26

    
27

    
28
def matches_hardware(hardware_filter, hardware_types):
29
    if len(hardware_filter) == 0:
30
        return True
31
    for f in hardware_filter:
32
        for h in hardware_types:
33
            if h.startswith(f):
34
                return True
35
    return False
36

    
37

    
38
def fetch_nodes(testbed, n, use_hardware, filters, nodes, hardware_types,
39
                dump_file, df):
40
    omni = ["omni", "-V3", "listresources", "-a", testbed, "--error",
41
            "--tostdout"]
42

    
43
    xml = check_output(omni)
44

    
45
    # parse the xml file removing the namespaces from tag names
46
    xml_file = StringIO(xml.decode('utf-8'))
47
    it = ET.iterparse(xml_file)
48
    for _, el in it:
49
        el.tag = el.tag.split('}', 1)[1]  # strip all namespaces
50
    e = it.root
51

    
52
    t = __import__('%stemplates' % testbed, globals(), locals(),
53
                   [NODE_TEMPLATE, HEADER_TEMPLATE, FOOTER_TEMPLATE])
54
    h = 40
55
    w = 120
56
    xs = 100
57
    ys = 100
58

    
59
    xml = ""
60

    
61
    for node in e.findall(NODE):
62
        name = node.get(COMPONENT_NAME)
63
        available = node.find(AVAILABLE).get(NOW).lower() == TRUE
64
        has_position = X in node.find(LOCATION).attrib
65
        component_id = node.get(COMPONENT_ID)
66
        if has_position:
67
            x = float(node.find(LOCATION).get(X))
68
            y = float(node.find(LOCATION).get(Y))
69
            z = float(node.find(LOCATION).get(Z))
70
        else:
71
            x = 0
72
            y = 0
73
            z = 0
74
        row = (n - 1) / 8
75
        col = (n - 1) % 8
76
        good_node = False
77
        if use_hardware:
78
            hardware_type_nodes = node.findall(HARDWARE_TYPE)
79
            hardware_types = [ht.get(NAME) for ht in hardware_type_nodes]
80
            if available and matches_hardware(hardware, hardware_types):
81
                good_node = True
82
        else:
83
            if available and matches(name, filters, nodes):
84
                good_node = True
85

    
86
        if good_node:
87
            domain = component_id.split("+")[1]
88
            hostname = "{}.{}".format(name, domain)
89
            xml += t.node_template % \
90
                   (name, component_id, xs + col * w, ys + row * h)
91
            if dump_file != "":
92
                df.write("%s\n" % name)
93
            n += 1
94
    return n, xml
95

    
96

    
97
parser = ArgumentParser()
98
parser.add_argument("-t", "--testbed", dest="testbed",
99
                    default="wall1", action="store", metavar="TESTBED",
100
                    help="Comma separated list of testbeds to use [default: "
101
                         "%(default)s]")
102
parser.add_argument("-f", "--filter", dest="filter",
103
                    default="", action="store", metavar="List of filters",
104
                    help="Comma separated list of node prefixes [default: %("
105
                         "default)s]")
106
parser.add_argument("-w", "--hardware", dest="hardware",
107
                    default="", action="store", metavar="List of hardware",
108
                    help="Comma separated list of hardware types [default: %("
109
                         "default)s]")
110
parser.add_argument("-n", "--nodes", dest="nodes",
111
                    default="", action="store", metavar="List of nodes",
112
                    help="Comma separated list of nodes [default: %("
113
                         "default)s] This argument has precedence over "
114
                         "--filter")
115
parser.add_argument("-d", "--dump", dest="dump",
116
                    default="", action="store", metavar="FILENAME",
117
                    help="Output file where to store the list of available "
118
                         "nodes. If not specified, no file will be written")
119
args = parser.parse_args()
120

    
121
if args.filter and args.hardware:
122
    print("Cannot use the --filter and the --hardware options together")
123
    sys.exit(1)
124

    
125
testbeds = args.testbed.split(",")
126
use_hardware = False
127
if args.filter:
128
    filters = args.filter.split(",")
129
else:
130
    filters = []
131

    
132
if args.nodes:
133
    nodes = args.nodes.split(",")
134
else:
135
    nodes = []
136

    
137
if args.hardware:
138
    use_hardware = True
139
    hardware = args.hardware.split(",")
140
else:
141
    hardware = []
142

    
143
dump_file = args.dump
144

    
145
t = __import__('%stemplates' % testbeds[0], globals(), locals(),
146
               [NODE_TEMPLATE, HEADER_TEMPLATE, FOOTER_TEMPLATE])
147

    
148
df = None
149
if dump_file != "":
150
    df = open(dump_file, "w")
151

    
152
print(t.header_template)
153

    
154
n = 0
155
for testbed in testbeds:
156
    n, xml = fetch_nodes(testbed, n, use_hardware, filters, nodes, hardware,
157
                         dump_file, df)
158
    print(xml)
159

    
160
print(t.footer_template)
161

    
162
if dump_file != "":
163
    df.close()