ia64/xen-unstable

view tools/python/xen/xend/XendNode.py @ 13192:159ae46d5e7f

Persist the VLAN setting.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Mon Dec 25 17:02:16 2006 +0000 (2006-12-25)
parents c1fbe291b564
children a8e853aecb3e
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 # Copyright (c) 2006 Xensource Inc.
17 #============================================================================
19 import os
20 import socket
21 import xen.lowlevel.xc
22 from xen.xend import uuid
23 from xen.xend.XendError import XendError
24 from xen.xend.XendRoot import instance as xendroot
25 from xen.xend.XendStorageRepository import XendStorageRepository
26 from xen.xend.XendLogging import log
27 from xen.xend.XendPIF import *
28 from xen.xend.XendNetwork import *
29 from xen.xend.XendStateStore import XendStateStore
31 class XendNode:
32 """XendNode - Represents a Domain 0 Host."""
34 def __init__(self):
35 """Initalises the state of all host specific objects such as
37 * Host
38 * Host_CPU
39 * PIF
40 * Network
41 * Storage Repository
42 """
44 self.xc = xen.lowlevel.xc.xc()
45 self.state_store = XendStateStore(xendroot().get_xend_state_path())
47 # load host state from XML file
48 saved_host = self.state_store.load_state('host')
49 if saved_host and len(saved_host.keys()) == 1:
50 self.uuid = saved_host.keys()[0]
51 host = saved_host[self.uuid]
52 self.name = host.get('name_label', socket.gethostname())
53 self.desc = host.get('name_description', '')
54 self.cpus = {}
55 else:
56 self.uuid = uuid.createString()
57 self.name = socket.gethostname()
58 self.desc = ''
59 self.cpus = {}
61 # load CPU UUIDs
62 saved_cpus = self.state_store.load_state('cpu')
63 for cpu_uuid, cpu in saved_cpus.items():
64 self.cpus[cpu_uuid] = cpu
66 # verify we have enough cpus here
67 physinfo = self.physinfo_dict()
68 cpu_count = physinfo['nr_cpus']
69 cpu_features = physinfo['hw_caps']
71 # If the number of CPUs don't match, we should just reinitialise
72 # the CPU UUIDs.
73 if cpu_count != len(self.cpus):
74 self.cpus = {}
75 for i in range(cpu_count):
76 cpu_uuid = uuid.createString()
77 cpu_info = {'uuid': cpu_uuid,
78 'host': self.uuid,
79 'number': i,
80 'features': cpu_features}
81 self.cpus[cpu_uuid] = cpu_info
83 self.pifs = {}
84 self.networks = {}
86 # initialise networks
87 saved_networks = self.state_store.load_state('network')
88 if saved_networks:
89 for net_uuid, network in saved_networks.items():
90 self.networks[net_uuid] = XendNetwork(net_uuid,
91 network.get('name_label'),
92 network.get('name_description', ''),
93 network.get('default_gateway', ''),
94 network.get('default_netmask', ''))
95 else:
96 gateway, netmask = linux_get_default_network()
97 net_uuid = uuid.createString()
98 net = XendNetwork(net_uuid, 'net0', '', gateway, netmask)
99 self.networks[net_uuid] = net
101 # initialise PIFs
102 saved_pifs = self.state_store.load_state('pif')
103 if saved_pifs:
104 for pif_uuid, pif in saved_pifs.items():
105 if pif['network'] in self.networks:
106 network = self.networks[pif['network']]
107 self.pifs[pif_uuid] = XendPIF(pif_uuid,
108 pif['name'],
109 pif['MTU'],
110 pif['VLAN'],
111 pif['MAC'],
112 network,
113 self)
114 else:
115 for name, mtu, mac in linux_get_phy_ifaces():
116 network = self.networks.values()[0]
117 pif_uuid = uuid.createString()
118 pif = XendPIF(pif_uuid, name, mtu, '', mac, network, self)
119 self.pifs[pif_uuid] = pif
121 # initialise storage
122 saved_sr = self.state_store.load_state('sr')
123 if saved_sr and len(saved_sr) == 1:
124 sr_uuid = saved_sr.keys()[0]
125 self.sr = XendStorageRepository(sr_uuid)
126 else:
127 sr_uuid = uuid.createString()
128 self.sr = XendStorageRepository(sr_uuid)
130 def save(self):
131 # save state
132 host_record = {self.uuid: {'name_label':self.name,
133 'name_description':self.desc}}
134 self.state_store.save_state('host',host_record)
135 self.state_store.save_state('cpu', self.cpus)
136 pif_records = dict([(k, v.get_record(transient = False))
137 for k, v in self.pifs.items()])
138 self.state_store.save_state('pif', pif_records)
140 self.save_networks()
142 sr_record = {self.sr.uuid: self.sr.get_record()}
143 self.state_store.save_state('sr', sr_record)
145 def save_networks(self):
146 net_records = dict([(k, v.get_record(transient = False))
147 for k, v in self.networks.items()])
148 self.state_store.save_state('network', net_records)
150 def shutdown(self):
151 return 0
153 def reboot(self):
154 return 0
156 def notify(self, _):
157 return 0
160 #
161 # Ref validation
162 #
164 def is_valid_host(self, host_ref):
165 return (host_ref == self.uuid)
167 def is_valid_cpu(self, cpu_ref):
168 return (cpu_ref in self.cpus)
170 def is_valid_network(self, network_ref):
171 return (network_ref in self.networks)
173 #
174 # Storage Repo
175 #
177 def get_sr(self):
178 return self.sr
180 #
181 # Host Functions
182 #
184 def xen_version(self):
185 info = self.xc.xeninfo()
186 try:
187 from xen import VERSION
188 return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
189 'Xend': VERSION}
190 except (ImportError, AttributeError):
191 return {'Xen': '%(xen_major)d.%(xen_minor)d' % info,
192 'Xend': '3.0.3'}
194 def get_name(self):
195 return self.name
197 def set_name(self, new_name):
198 self.name = new_name
200 def get_description(self):
201 return self.desc
203 def set_description(self, new_desc):
204 self.desc = new_desc
206 def get_uuid(self):
207 return self.uuid
209 #
210 # Host CPU Functions
211 #
213 def get_host_cpu_by_uuid(self, host_cpu_uuid):
214 if host_cpu_uuid in self.cpus:
215 return host_cpu_uuid
216 raise XendError('Invalid CPU UUID')
218 def get_host_cpu_refs(self):
219 return self.cpus.keys()
221 def get_host_cpu_uuid(self, host_cpu_ref):
222 if host_cpu_ref in self.cpus:
223 return host_cpu_ref
224 else:
225 raise XendError('Invalid CPU Reference')
227 def get_host_cpu_features(self, host_cpu_ref):
228 try:
229 return self.cpus[host_cpu_ref]['features']
230 except KeyError:
231 raise XendError('Invalid CPU Reference')
233 def get_host_cpu_number(self, host_cpu_ref):
234 try:
235 return self.cpus[host_cpu_ref]['number']
236 except KeyError:
237 raise XendError('Invalid CPU Reference')
239 def get_host_cpu_load(self, host_cpu_ref):
240 return 0.0
243 #
244 # Network Functions
245 #
247 def get_network_refs(self):
248 return self.networks.keys()
250 def get_network(self, network_ref):
251 return self.networks[network_ref]
254 #
255 # Getting host information.
256 #
258 def info(self):
259 return (self.nodeinfo() + self.physinfo() + self.xeninfo() +
260 self.xendinfo())
262 def nodeinfo(self):
263 (sys, host, rel, ver, mch) = os.uname()
264 return [['system', sys],
265 ['host', host],
266 ['release', rel],
267 ['version', ver],
268 ['machine', mch]]
270 def physinfo(self):
271 info = self.xc.physinfo()
273 info['nr_cpus'] = (info['nr_nodes'] *
274 info['sockets_per_node'] *
275 info['cores_per_socket'] *
276 info['threads_per_core'])
277 info['cpu_mhz'] = info['cpu_khz'] / 1000
278 # physinfo is in KiB
279 info['total_memory'] = info['total_memory'] / 1024
280 info['free_memory'] = info['free_memory'] / 1024
282 ITEM_ORDER = ['nr_cpus',
283 'nr_nodes',
284 'sockets_per_node',
285 'cores_per_socket',
286 'threads_per_core',
287 'cpu_mhz',
288 'hw_caps',
289 'total_memory',
290 'free_memory',
291 ]
293 return [[k, info[k]] for k in ITEM_ORDER]
296 def xeninfo(self):
297 info = self.xc.xeninfo()
299 ITEM_ORDER = ['xen_major',
300 'xen_minor',
301 'xen_extra',
302 'xen_caps',
303 'xen_pagesize',
304 'platform_params',
305 'xen_changeset',
306 'cc_compiler',
307 'cc_compile_by',
308 'cc_compile_domain',
309 'cc_compile_date',
310 ]
312 return [[k, info[k]] for k in ITEM_ORDER]
314 def xendinfo(self):
315 return [['xend_config_format', 3]]
317 # dictionary version of *info() functions to get rid of
318 # SXPisms.
319 def nodeinfo_dict(self):
320 return dict(self.nodeinfo())
321 def xendinfo_dict(self):
322 return dict(self.xendinfo())
323 def xeninfo_dict(self):
324 return dict(self.xeninfo())
325 def physinfo_dict(self):
326 return dict(self.physinfo())
327 def info_dict(self):
328 return dict(self.info())
331 def instance():
332 global inst
333 try:
334 inst
335 except:
336 inst = XendNode()
337 inst.save()
338 return inst