]> git.proxmox.com Git - mirror_ovs.git/blob - xenserver/opt_xensource_libexec_interface-reconfigure
cirrus: Use FreeBSD 12.2.
[mirror_ovs.git] / xenserver / opt_xensource_libexec_interface-reconfigure
1 #!/usr/bin/env python3
2 #
3 # Copyright (c) 2008,2009 Citrix Systems, Inc.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU Lesser General Public License as published
7 # by the Free Software Foundation; version 2.1 only. with the special
8 # exception on linking described in file LICENSE.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Lesser General Public License for more details.
14 #
15 """Usage:
16
17 %(command-name)s <PIF> up
18 %(command-name)s <PIF> down
19 %(command-name)s rewrite
20 %(command-name)s --force <BRIDGE> up
21 %(command-name)s --force <BRIDGE> down
22 %(command-name)s --force <BRIDGE> rewrite --device=<INTERFACE> --mac=<MAC-ADDRESS> <CONFIG>
23
24 where <PIF> is one of:
25 --session <SESSION-REF> --pif <PIF-REF>
26 --pif-uuid <PIF-UUID>
27 and <CONFIG> is one of:
28 --mode=dhcp
29 --mode=static --ip=<IPADDR> --netmask=<NM> [--gateway=<GW>]
30
31 Options:
32 --session A session reference to use to access the xapi DB
33 --pif A PIF reference within the session.
34 --pif-uuid The UUID of a PIF.
35 --force An interface name.
36 --root-prefix=DIR Use DIR as alternate root directory (for testing).
37 --no-syslog Write log messages to stderr instead of system log.
38 """
39
40 # Notes:
41 # 1. Every pif belongs to exactly one network
42 # 2. Every network has zero or one pifs
43 # 3. A network may have an associated bridge, allowing vifs to be attached
44 # 4. A network may be bridgeless (there's no point having a bridge over a storage pif)
45
46 from InterfaceReconfigure import *
47
48 import os, sys, getopt
49 import syslog
50 import traceback
51 import re
52 import random
53 import syslog
54
55 management_pif = None
56
57 dbcache_file = "/var/xapi/network.dbcache"
58
59 #
60 # Logging.
61 #
62
63 def log_pif_action(action, pif):
64 pifrec = db().get_pif_record(pif)
65 rec = {}
66 rec['uuid'] = pifrec['uuid']
67 rec['ip_configuration_mode'] = pifrec['ip_configuration_mode']
68 rec['action'] = action
69 rec['pif_netdev_name'] = pif_netdev_name(pif)
70 rec['message'] = "Bring %(action)s PIF %(uuid)s" % rec
71 log("%(message)s: %(pif_netdev_name)s configured as %(ip_configuration_mode)s" % rec)
72
73 #
74 # Exceptions.
75 #
76
77 class Usage(Exception):
78 def __init__(self, msg):
79 Exception.__init__(self)
80 self.msg = msg
81
82 #
83 # Boot from Network filesystem or device.
84 #
85
86 def check_allowed(pif):
87 """Determine whether interface-reconfigure should be manipulating this PIF.
88
89 Used to prevent system PIFs (such as network root disk) from being interfered with.
90 """
91
92 pifrec = db().get_pif_record(pif)
93 try:
94 f = open(root_prefix() + "/proc/ardence")
95 macline = filter(lambda x: x.startswith("HWaddr:"), f.readlines())
96 f.close()
97 if len(macline) == 1:
98 p = re.compile(".*\s%(MAC)s\s.*" % pifrec, re.IGNORECASE)
99 if p.match(macline[0]):
100 log("Skipping PVS device %(device)s (%(MAC)s)" % pifrec)
101 return False
102 except IOError:
103 pass
104 return True
105
106 #
107 # Bare Network Devices -- network devices without IP configuration
108 #
109
110 def netdev_remap_name(pif, already_renamed=[]):
111 """Check whether 'pif' exists and has the correct MAC.
112 If not, try to find a device with the correct MAC and rename it.
113 'already_renamed' is used to avoid infinite recursion.
114 """
115
116 def read1(name):
117 file = None
118 try:
119 file = open(name, 'r')
120 return file.readline().rstrip('\n')
121 finally:
122 if file != None:
123 file.close()
124
125 def get_netdev_mac(device):
126 try:
127 return read1("%s/sys/class/net/%s/address" % (root_prefix(), device))
128 except:
129 # Probably no such device.
130 return None
131
132 def get_netdev_tx_queue_len(device):
133 try:
134 return int(read1("%s/sys/class/net/%s/tx_queue_len" % (root_prefix(), device)))
135 except:
136 # Probably no such device.
137 return None
138
139 def get_netdev_by_mac(mac):
140 for device in os.listdir(root_prefix() + "/sys/class/net"):
141 dev_mac = get_netdev_mac(device)
142 if (dev_mac and mac.lower() == dev_mac.lower() and
143 get_netdev_tx_queue_len(device)):
144 return device
145 return None
146
147 def rename_netdev(old_name, new_name):
148 raise Error("Trying to rename %s to %s - This functionality has been removed" % (old_name, new_name))
149 # log("Changing the name of %s to %s" % (old_name, new_name))
150 # run_command(['/sbin/ip', 'link', 'set', old_name, 'down'])
151 # if not run_command(['/sbin/ip', 'link', 'set', old_name, 'name', new_name]):
152 # raise Error("Could not rename %s to %s" % (old_name, new_name))
153
154 pifrec = db().get_pif_record(pif)
155 device = pifrec['device']
156 mac = pifrec['MAC']
157
158 # Is there a network device named 'device' at all?
159 device_exists = netdev_exists(device)
160 if device_exists:
161 # Yes. Does it have MAC 'mac'?
162 found_mac = get_netdev_mac(device)
163 if found_mac and mac.lower() == found_mac.lower():
164 # Yes, everything checks out the way we want. Nothing to do.
165 return
166 else:
167 log("No network device %s" % device)
168
169 # What device has MAC 'mac'?
170 cur_device = get_netdev_by_mac(mac)
171 if not cur_device:
172 log("No network device has MAC %s" % mac)
173 return
174
175 # First rename 'device', if it exists, to get it out of the way
176 # for 'cur_device' to replace it.
177 if device_exists:
178 rename_netdev(device, "dev%d" % random.getrandbits(24))
179
180 # Rename 'cur_device' to 'device'.
181 rename_netdev(cur_device, device)
182
183 #
184 # IP Network Devices -- network devices with IP configuration
185 #
186
187 def ifdown(netdev):
188 """Bring down a network interface"""
189 if not netdev_exists(netdev):
190 log("ifdown: device %s does not exist, ignoring" % netdev)
191 return
192 if not os.path.exists("%s/etc/sysconfig/network-scripts/ifcfg-%s" % (root_prefix(), netdev)):
193 log("ifdown: device %s exists but ifcfg-%s does not" % (netdev,netdev))
194 run_command(["/sbin/ip", "link", "set", netdev, 'down'])
195 return
196 run_command(["/sbin/ifdown", netdev])
197
198 def ifup(netdev):
199 """Bring up a network interface"""
200 if not os.path.exists(root_prefix() + "/etc/sysconfig/network-scripts/ifcfg-%s" % netdev):
201 raise Error("ifup: device %s exists but ifcfg-%s does not" % (netdev,netdev))
202 d = os.getenv("DHCLIENTARGS","")
203 if os.path.exists("/etc/firstboot.d/data/firstboot_in_progress"):
204 os.putenv("DHCLIENTARGS", d + " -T 240 " )
205 run_command(["/sbin/ifup", netdev])
206 os.putenv("DHCLIENTARGS", d )
207
208 #
209 #
210 #
211
212 def pif_rename_physical_devices(pif):
213 if pif_is_tunnel(pif):
214 return
215
216 if pif_is_vlan(pif):
217 pif = pif_get_vlan_slave(pif)
218
219 if pif_is_bond(pif):
220 pifs = pif_get_bond_slaves(pif)
221 else:
222 pifs = [pif]
223
224 for pif in pifs:
225 netdev_remap_name(pif)
226
227 #
228 # IP device configuration
229 #
230
231 def ipdev_configure_static_routes(interface, oc, f):
232 """Open a route-<interface> file for static routes.
233
234 Opens the static routes configuration file for interface and writes one
235 line for each route specified in the network's other config "static-routes" value.
236 E.g. if
237 interface ( RO): xenbr1
238 other-config (MRW): static-routes: 172.16.0.0/15/192.168.0.3,172.18.0.0/16/192.168.0.4;...
239
240 Then route-xenbr1 should be
241 172.16.0.0/15 via 192.168.0.3 dev xenbr1
242 172.18.0.0/16 via 192.168.0.4 dev xenbr1
243 """
244 if 'static-routes' in oc:
245 # The key is present - extract comma separates entries
246 lines = oc['static-routes'].split(',')
247 else:
248 # The key is not present, i.e. there are no static routes
249 lines = []
250
251 child = ConfigurationFile("%s/etc/sysconfig/network-scripts/route-%s" % (root_prefix(), interface))
252 child.write("# DO NOT EDIT: This file (%s) was autogenerated by %s\n" % \
253 (os.path.basename(child.path()), os.path.basename(sys.argv[0])))
254
255 try:
256 for l in lines:
257 network, masklen, gateway = l.split('/')
258 child.write("%s/%s via %s dev %s\n" % (network, masklen, gateway, interface))
259
260 f.attach_child(child)
261 child.close()
262
263 except ValueError as e:
264 log("Error in other-config['static-routes'] format for network %s: %s" % (interface, e))
265
266 def ipdev_open_ifcfg(pif):
267 ipdev = pif_ipdev_name(pif)
268
269 log("Writing network configuration for %s" % ipdev)
270
271 f = ConfigurationFile("%s/etc/sysconfig/network-scripts/ifcfg-%s" % (root_prefix(), ipdev))
272
273 f.write("# DO NOT EDIT: This file (%s) was autogenerated by %s\n" % \
274 (os.path.basename(f.path()), os.path.basename(sys.argv[0])))
275 f.write("XEMANAGED=yes\n")
276 f.write("DEVICE=%s\n" % ipdev)
277 f.write("ONBOOT=no\n")
278 f.write("NOZEROCONF=yes\n")
279
280 return f
281
282 def ipdev_configure_network(pif, dp):
283 """Write the configuration file for a network.
284
285 Writes configuration derived from the network object into the relevant
286 ifcfg file. The configuration file is passed in, but if the network is
287 bridgeless it will be ifcfg-<interface>, otherwise it will be ifcfg-<bridge>.
288
289 This routine may also write ifcfg files of the networks corresponding to other PIFs
290 in order to maintain consistency.
291
292 params:
293 pif: Opaque_ref of pif
294 dp: Datapath object
295 """
296
297 pifrec = db().get_pif_record(pif)
298 nw = pifrec['network']
299 nwrec = db().get_network_record(nw)
300
301 ipdev = pif_ipdev_name(pif)
302
303 f = ipdev_open_ifcfg(pif)
304
305 mode = pifrec['ip_configuration_mode']
306 log("Configuring %s using %s configuration" % (ipdev, mode))
307
308 oc = None
309 if 'other_config' in pifrec:
310 oc = pifrec['other_config']
311
312 dp.configure_ipdev(f)
313
314 if pifrec['ip_configuration_mode'] == "DHCP":
315 f.write("BOOTPROTO=dhcp\n")
316 f.write("PERSISTENT_DHCLIENT=yes\n")
317 elif pifrec['ip_configuration_mode'] == "Static":
318 f.write("BOOTPROTO=none\n")
319 f.write("NETMASK=%(netmask)s\n" % pifrec)
320 f.write("IPADDR=%(IP)s\n" % pifrec)
321 f.write("GATEWAY=%(gateway)s\n" % pifrec)
322 elif pifrec['ip_configuration_mode'] == "None":
323 f.write("BOOTPROTO=none\n")
324 else:
325 raise Error("Unknown ip-configuration-mode %s" % pifrec['ip_configuration_mode'])
326
327 if 'other_config' in nwrec:
328 settings,offload = ethtool_settings(nwrec['other_config'])
329 if len(settings):
330 f.write("ETHTOOL_OPTS=\"%s\"\n" % str.join(" ", settings))
331 if len(offload):
332 f.write("ETHTOOL_OFFLOAD_OPTS=\"%s\"\n" % str.join(" ", offload))
333
334 ipdev_configure_static_routes(ipdev, nwrec['other_config'], f)
335
336 mtu = mtu_setting(nw, "Network", nwrec['other_config'])
337 if mtu:
338 f.write("MTU=%s\n" % mtu)
339
340
341 if 'DNS' in pifrec and pifrec['DNS'] != "":
342 ServerList = pifrec['DNS'].split(",")
343 for i in range(len(ServerList)): f.write("DNS%d=%s\n" % (i+1, ServerList[i]))
344 if oc and 'domain' in oc:
345 f.write("DOMAIN='%s'\n" % oc['domain'].replace(',', ' '))
346
347 # There can be only one DNSDEV and one GATEWAYDEV in /etc/sysconfig/network.
348 #
349 # The peerdns pif will be the one with
350 # pif::other-config:peerdns=true, or the mgmt pif if none have
351 # this set.
352 #
353 # The gateway pif will be the one with
354 # pif::other-config:defaultroute=true, or the mgmt pif if none
355 # have this set.
356
357 # Work out which pif on this host should be the DNSDEV and which
358 # should be the GATEWAYDEV
359 #
360 # Note: we prune out the bond master pif (if it exists). This is
361 # because when we are called to bring up an interface with a bond
362 # master, it is implicit that we should bring down that master.
363
364 pifs_on_host = [p for p in db().get_all_pifs() if not p in pif_get_bond_masters(pif)]
365
366 # now prune out bond slaves as they are not connected to the IP
367 # stack and so cannot be used as gateway or DNS devices.
368 pifs_on_host = [ p for p in pifs_on_host if len(pif_get_bond_masters(p)) == 0]
369
370 # loop through all the pifs on this host looking for one with
371 # other-config:peerdns = true, and one with
372 # other-config:default-route=true
373 peerdns_pif = None
374 defaultroute_pif = None
375 for __pif in pifs_on_host:
376 __pifrec = db().get_pif_record(__pif)
377 __oc = __pifrec['other_config']
378 if 'peerdns' in __oc and __oc['peerdns'] == 'true':
379 if peerdns_pif == None:
380 peerdns_pif = __pif
381 else:
382 log('Warning: multiple pifs with "peerdns=true" - choosing %s and ignoring %s' % \
383 (db().get_pif_record(peerdns_pif)['device'], __pifrec['device']))
384 if 'defaultroute' in __oc and __oc['defaultroute'] == 'true':
385 if defaultroute_pif == None:
386 defaultroute_pif = __pif
387 else:
388 log('Warning: multiple pifs with "defaultroute=true" - choosing %s and ignoring %s' % \
389 (db().get_pif_record(defaultroute_pif)['device'], __pifrec['device']))
390
391 # If no pif is explicitly specified then use the mgmt pif for
392 # peerdns/defaultroute.
393 if peerdns_pif == None:
394 peerdns_pif = management_pif
395 if defaultroute_pif == None:
396 defaultroute_pif = management_pif
397
398 is_dnsdev = peerdns_pif == pif
399 is_gatewaydev = defaultroute_pif == pif
400
401 if is_dnsdev or is_gatewaydev:
402 fnetwork = ConfigurationFile(root_prefix() + "/etc/sysconfig/network")
403 for line in fnetwork.readlines():
404 if is_dnsdev and line.lstrip().startswith('DNSDEV='):
405 fnetwork.write('DNSDEV=%s\n' % ipdev)
406 is_dnsdev = False
407 elif is_gatewaydev and line.lstrip().startswith('GATEWAYDEV='):
408 fnetwork.write('GATEWAYDEV=%s\n' % ipdev)
409 is_gatewaydev = False
410 else:
411 fnetwork.write(line)
412
413 if is_dnsdev:
414 fnetwork.write('DNSDEV=%s\n' % ipdev)
415 if is_gatewaydev:
416 fnetwork.write('GATEWAYDEV=%s\n' % ipdev)
417
418 fnetwork.close()
419 f.attach_child(fnetwork)
420
421 return f
422
423 #
424 # Toplevel actions
425 #
426
427 def action_up(pif, force):
428 pifrec = db().get_pif_record(pif)
429
430 ipdev = pif_ipdev_name(pif)
431 dp = DatapathFactory()(pif)
432
433 log("action_up: %s" % ipdev)
434
435 f = ipdev_configure_network(pif, dp)
436
437 dp.preconfigure(f)
438
439 f.close()
440
441 pif_rename_physical_devices(pif)
442
443 # if we are not forcing the interface up then attempt to tear down
444 # any existing devices which might interfere with brinign this one
445 # up.
446 if not force:
447 ifdown(ipdev)
448
449 dp.bring_down_existing()
450
451 try:
452 f.apply()
453
454 dp.configure()
455
456 ifup(ipdev)
457
458 dp.post()
459
460 # Update /etc/issue (which contains the IP address of the management interface)
461 os.system(root_prefix() + "/sbin/update-issue")
462
463 f.commit()
464 except Error as e:
465 log("failed to apply changes: %s" % e.msg)
466 f.revert()
467 raise
468
469 def action_down(pif):
470 ipdev = pif_ipdev_name(pif)
471 dp = DatapathFactory()(pif)
472
473 log("action_down: %s" % ipdev)
474
475 ifdown(ipdev)
476
477 dp.bring_down()
478
479 def action_rewrite():
480 DatapathFactory().rewrite()
481
482 # This is useful for reconfiguring the mgmt interface after having lost connectivity to the pool master
483 def action_force_rewrite(bridge, config):
484 def getUUID():
485 import subprocess
486 uuid,_ = subprocess.Popen(['uuidgen'], stdout = subprocess.PIPE).communicate()
487 return uuid.strip()
488
489 # Notes:
490 # 1. that this assumes the interface is bridged
491 # 2. If --gateway is given it will make that the default gateway for the host
492
493 # extract the configuration
494 try:
495 mode = config['mode']
496 mac = config['mac']
497 interface = config['device']
498 except:
499 raise Usage("Please supply --mode, --mac and --device")
500
501 if mode == 'static':
502 try:
503 netmask = config['netmask']
504 ip = config['ip']
505 except:
506 raise Usage("Please supply --netmask and --ip")
507 try:
508 gateway = config['gateway']
509 except:
510 gateway = None
511 elif mode != 'dhcp':
512 raise Usage("--mode must be either static or dhcp")
513
514 if 'vlan' in config:
515 is_vlan = True
516 vlan_slave, vlan_vid = config['vlan'].split('.')
517 else:
518 is_vlan = False
519
520 if is_vlan:
521 raise Error("Force rewrite of VLAN not implemented")
522
523 log("Configuring %s using %s configuration" % (bridge, mode))
524
525 f = ConfigurationFile(root_prefix() + dbcache_file)
526
527 pif_uuid = getUUID()
528 network_uuid = getUUID()
529
530 f.write('<?xml version="1.0" ?>\n')
531 f.write('<xenserver-network-configuration>\n')
532 f.write('\t<pif ref="OpaqueRef:%s">\n' % pif_uuid)
533 f.write('\t\t<network>OpaqueRef:%s</network>\n' % network_uuid)
534 f.write('\t\t<management>True</management>\n')
535 f.write('\t\t<uuid>%sPif</uuid>\n' % interface)
536 f.write('\t\t<bond_slave_of>OpaqueRef:NULL</bond_slave_of>\n')
537 f.write('\t\t<bond_master_of/>\n')
538 f.write('\t\t<VLAN_slave_of/>\n')
539 f.write('\t\t<VLAN_master_of>OpaqueRef:NULL</VLAN_master_of>\n')
540 f.write('\t\t<VLAN>-1</VLAN>\n')
541 f.write('\t\t<tunnel_access_PIF_of/>\n')
542 f.write('\t\t<tunnel_transport_PIF_of/>\n')
543 f.write('\t\t<device>%s</device>\n' % interface)
544 f.write('\t\t<MAC>%s</MAC>\n' % mac)
545 f.write('\t\t<other_config/>\n')
546 if mode == 'dhcp':
547 f.write('\t\t<ip_configuration_mode>DHCP</ip_configuration_mode>\n')
548 f.write('\t\t<IP></IP>\n')
549 f.write('\t\t<netmask></netmask>\n')
550 f.write('\t\t<gateway></gateway>\n')
551 f.write('\t\t<DNS></DNS>\n')
552 elif mode == 'static':
553 f.write('\t\t<ip_configuration_mode>Static</ip_configuration_mode>\n')
554 f.write('\t\t<IP>%s</IP>\n' % ip)
555 f.write('\t\t<netmask>%s</netmask>\n' % netmask)
556 if gateway is not None:
557 f.write('\t\t<gateway>%s</gateway>\n' % gateway)
558 f.write('\t\t<DNS></DNS>\n')
559 else:
560 raise Error("Unknown mode %s" % mode)
561 f.write('\t</pif>\n')
562
563 f.write('\t<network ref="OpaqueRef:%s">\n' % network_uuid)
564 f.write('\t\t<uuid>InitialManagementNetwork</uuid>\n')
565 f.write('\t\t<PIFs>\n')
566 f.write('\t\t\t<PIF>OpaqueRef:%s</PIF>\n' % pif_uuid)
567 f.write('\t\t</PIFs>\n')
568 f.write('\t\t<bridge>%s</bridge>\n' % bridge)
569 f.write('\t\t<other_config/>\n')
570 f.write('\t</network>\n')
571 f.write('</xenserver-network-configuration>\n')
572
573 f.close()
574
575 try:
576 f.apply()
577 f.commit()
578 except Error as e:
579 log("failed to apply changes: %s" % e.msg)
580 f.revert()
581 raise
582
583 def main(argv=None):
584 global management_pif
585
586 session = None
587 pif_uuid = None
588 pif = None
589
590 force_interface = None
591 force_management = False
592
593 if argv is None:
594 argv = sys.argv
595
596 try:
597 try:
598 shortops = "h"
599 longops = [ "pif=", "pif-uuid=",
600 "session=",
601 "force=",
602 "force-interface=",
603 "management",
604 "mac=", "device=", "mode=", "ip=", "netmask=", "gateway=",
605 "root-prefix=",
606 "no-syslog",
607 "help" ]
608 arglist, args = getopt.gnu_getopt(argv[1:], shortops, longops)
609 except getopt.GetoptError as msg:
610 raise Usage(msg)
611
612 force_rewrite_config = {}
613
614 for o,a in arglist:
615 if o == "--pif":
616 pif = a
617 elif o == "--pif-uuid":
618 pif_uuid = a
619 elif o == "--session":
620 session = a
621 elif o == "--force-interface" or o == "--force":
622 force_interface = a
623 elif o == "--management":
624 force_management = True
625 elif o in ["--mac", "--device", "--mode", "--ip", "--netmask", "--gateway"]:
626 force_rewrite_config[o[2:]] = a
627 elif o == "--root-prefix":
628 set_root_prefix(a)
629 elif o == "--no-syslog":
630 set_log_destination("stderr")
631 elif o == "-h" or o == "--help":
632 print(__doc__ % {'command-name': os.path.basename(argv[0])})
633 return 0
634
635 if get_log_destination() == "syslog":
636 syslog.openlog(os.path.basename(argv[0]))
637 log("Called as " + str.join(" ", argv))
638
639 if len(args) < 1:
640 raise Usage("Required option <action> not present")
641 if len(args) > 1:
642 raise Usage("Too many arguments")
643
644 action = args[0]
645
646 if not action in ["up", "down", "rewrite", "rewrite-configuration"]:
647 raise Usage("Unknown action \"%s\"" % action)
648
649 # backwards compatibility
650 if action == "rewrite-configuration": action = "rewrite"
651
652 if ( session or pif ) and pif_uuid:
653 raise Usage("--session/--pif and --pif-uuid are mutually exclusive.")
654 if ( session and not pif ) or ( not session and pif ):
655 raise Usage("--session and --pif must be used together.")
656 if force_interface and ( session or pif or pif_uuid ):
657 raise Usage("--force is mutually exclusive with --session, --pif and --pif-uuid")
658 if len(force_rewrite_config) and not (force_interface and action == "rewrite"):
659 raise Usage("\"--force rewrite\" needed for --device, --mode, --ip, --netmask, and --gateway")
660 if (action == "rewrite") and (pif or pif_uuid ):
661 raise Usage("rewrite action does not take --pif or --pif-uuid")
662
663 global db
664 if force_interface:
665 log("Force interface %s %s" % (force_interface, action))
666
667 if action == "rewrite":
668 action_force_rewrite(force_interface, force_rewrite_config)
669 elif action in ["up", "down"]:
670 db_init_from_cache(dbcache_file)
671 pif = db().get_pif_by_bridge(force_interface)
672 management_pif = db().get_management_pif()
673
674 if action == "up":
675 action_up(pif, True)
676 elif action == "down":
677 action_down(pif)
678 else:
679 raise Error("Unknown action %s" % action)
680 else:
681 db_init_from_xenapi(session)
682
683 if pif_uuid:
684 pif = db().get_pif_by_uuid(pif_uuid)
685
686 if action == "rewrite":
687 action_rewrite()
688 else:
689 if not pif:
690 raise Usage("No PIF given")
691
692 if force_management:
693 # pif is going to be the management pif
694 management_pif = pif
695 else:
696 # pif is not going to be the management pif.
697 # Search DB cache for pif on same host with management=true
698 pifrec = db().get_pif_record(pif)
699 management_pif = db().get_management_pif()
700
701 log_pif_action(action, pif)
702
703 if not check_allowed(pif):
704 return 0
705
706 if action == "up":
707 action_up(pif, False)
708 elif action == "down":
709 action_down(pif)
710 else:
711 raise Error("Unknown action %s" % action)
712
713 # Save cache.
714 db().save(dbcache_file)
715
716 except Usage as err:
717 sys.stderr.write(err.msg + "\n")
718 sys.stderr.write("For help use --help.\n")
719 sys.stderr.flush()
720 return 2
721 except Error as err:
722 log(err.msg)
723 return 1
724
725 return 0
726
727 if __name__ == "__main__":
728 rc = 1
729 try:
730 rc = main()
731 except:
732 ex = sys.exc_info()
733 err = traceback.format_exception(*ex)
734 for exline in err:
735 log(exline)
736
737 syslog.closelog()
738
739 sys.exit(rc)