igor@0: #!/usr/bin/python igor@0: igor@0: igor@0: def the_peer_of(node): igor@2: if node == node1: igor@2: another_node=node2 igor@2: else: igor@2: another_node=node1 igor@2: return another_node igor@0: igor@0: igor@0: def log_error(error): igor@2: print error igor@0: igor@37: def run_now(command,node): igor@2: if node == i_am: igor@26: line=command+" > /dev/stderr 2>&1" igor@2: else: igor@26: line="ssh %s %s < /dev/null > /dev/stderr 2>&1" % (node,mkarg(command)) igor@26: if debug > 2: igor@26: print "debug:", line igor@2: (p, child_stdout, child_stderr) = os.popen3(line) igor@2: output = child_stderr.read() igor@2: #p = os.popen(line) igor@2: #output = p.read() igor@2: p.close() igor@2: return output igor@0: igor@37: def run(command,node): igor@25: return run_now(command,node) igor@25: #if node == i_am: igor@25: # print command igor@25: #else: igor@25: # print "ssh %s %s < /dev/null > /dev/stderr" % (node,mkarg(command)) igor@0: igor@0: igor@0: def get_drbd_resources(domain): igor@2: disk=[] igor@2: for disk_description in disk_table[domain]: igor@2: if disk_description.find(":") == -1: igor@2: disk.append(domain) igor@2: else: igor@25: disk.append((disk_description.split(':'))[1]) igor@2: return disk igor@0: igor@37: def set_drbd_primary(domain, node): igor@26: res="" igor@2: drbd_resources=get_drbd_resources(domain) igor@2: for drbd in drbd_resources: igor@26: res += run("drbdadm primary %s"%(drbd),node) igor@26: print "DRBD resource <%s> on the node <%s> is <%s> now" % (drbd,node,get_drbd_state(drbd,node)) igor@26: return res igor@0: igor@37: def set_drbd_secondary(domain, node): igor@26: res="" igor@2: drbd_resources=get_drbd_resources(domain) igor@2: for drbd in drbd_resources: igor@27: res += run("until drbdadm secondary %s; do echo Trying to siwtch resource <%s> on the node <%s> to secondary state; sleep 5; done"%(drbd,drbd,node),node) igor@26: print "DRBD resource <%s> on the node <%s> is <%s> now" % (drbd,node,get_drbd_state(drbd,node)) igor@26: return res igor@0: igor@37: def get_domain_id(domain,node): igor@2: """ igor@2: Returns domain id of the or -1 if the is not running on the igor@2: """ igor@2: res=run_now("xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain, node).rstrip("\n") igor@2: if not res: igor@2: res = -1 igor@2: else: igor@2: res = int(res) igor@2: return res igor@0: igor@37: def get_drbd_id(resource,node): igor@2: res=run_now("ls -l /dev/drbd/%s 2> /dev/null | awk '{print $10}' | sed s@/dev/drbd@@" %resource, node).rstrip("\n") igor@2: if not res: igor@2: res = -1 igor@2: else: igor@2: res = int(res) igor@2: return res igor@0: igor@37: def get_drbd_state(resource,node): igor@60: #before DRBD 8.3.0: res=run_now("drbdadm state %s | sed s@/.*@@" %resource, node).rstrip("\n") igor@60: res=run_now("drbdadm role %s | sed s@/.*@@" %resource, node).rstrip("\n") igor@2: if not res: igor@2: res = -1 igor@2: return res igor@0: igor@37: def get_drbd_cstate(resource,node): igor@2: res=run_now("drbdadm cstate %s " %resource, node).rstrip("\n") igor@2: if not res: igor@2: res = -1 igor@2: return res igor@0: igor@37: def start_domain(domain,node): igor@2: if (get_domain_id(domain,i_am) != -1): igor@2: log_error("Domain %s is running already on the node %s" % (domain,i_am)) igor@2: return -1 igor@2: if (get_domain_id(domain,he_is) != -1): igor@2: log_error("Domain %s is running already on the node %s" % (domain,he_is)) igor@2: return -1 igor@2: another_node=the_peer_of(node) igor@26: print set_drbd_secondary(domain,another_node) igor@26: print set_drbd_primary(domain,node) igor@29: print run(domain_create_line % domain, node) igor@0: igor@37: def migrate_domain_out(domain,node): igor@2: if (get_domain_id(domain,node) == -1): igor@2: log_error("Domain %s is not running on the node %s" % (domain,node)) igor@2: return -1 igor@2: another_node=the_peer_of(node) igor@2: print "Migrating the domain <%s> from the node <%s> to the node <%s>" % (domain, node, another_node) igor@2: set_drbd_primary(domain,another_node) igor@2: run("xm migrate %s %s --live" % (domain,another_node),node) igor@42: run("sleep 2", node) igor@2: set_drbd_secondary(domain,node) igor@2: print "+ Done" igor@2: igor@37: def migrate_domain_in(domain,node): igor@2: migrate_domain_out(domain,the_peer_of(node)) igor@0: igor@0: def migrate_domain(domain,node): igor@2: migrate_domain_in(domain,node) igor@0: igor@37: def running_domains(node): igor@2: xm_domains=run_now("xm list | awk '{print $1}'", node).split("\n") igor@2: return filter(lambda x: x in xm_domains, domains) igor@0: igor@37: def migrate_out_all(node): igor@2: for domain in running_domains(node): igor@2: migrate_domain_out(domain,node) igor@0: igor@37: def migrate_in_all(node): igor@2: for domain in running_domains(the_peer_of(node)): igor@2: migrate_domain_in(domain,node) igor@0: igor@37: def start_all(node): igor@2: for domain in domains: igor@2: if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)): igor@2: start_domain(domain,node) igor@0: igor@37: def start_my_domains(node): igor@2: for domain in domain_home[node]: igor@2: if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)): igor@2: start_domain(domain,node) igor@0: igor@37: def migrate_my_domains_home(node): igor@2: for domain in domain_home[node]: igor@2: if not domain in running_domains(node) and domain in running_domains(the_peer_of(node)): igor@2: migrate_domain_in(domain,node) igor@28: igor@37: def migrate_and_start_my_domains(node): igor@28: migrate_my_domains_home(node) igor@28: start_my_domains(node) igor@2: igor@37: def migrate_and_start_all(node): igor@2: migrate_my_domains_home(node) igor@2: start_my_domains(node) igor@28: migrate_my_domains_home(the_peer_of(node)) igor@28: start_my_domains(the_peer_of(node)) igor@2: igor@2: def do_import(name, source): igor@2: module = imp.new_module(name) igor@2: sys.modules[name] = module igor@2: exec source in vars(module) igor@2: return module igor@2: igor@2: def load_file(file): igor@2: f=open(file) igor@2: result=f.read() igor@2: return result igor@2: igor@2: def dump_config(domain): igor@2: xen_domain=load_file(xen_drbd_start) igor@2: xen_domain="domain=\"%s\"\n" % (domain) + xen_domain igor@2: xen_domain="network=\"%s\"\n" % (network) + xen_domain igor@2: do_import('xen_domain_module',xen_domain) igor@38: #print "domain=\"%s\"\n" % (domain) igor@38: #print "network=\"%s\"\n" % (network) igor@2: import xen_domain_module igor@2: xen_domain_module.print_config() igor@0: igor@0: def show_usage(): igor@2: print """ igor@0: Usage: igor@37: xen-drbd [options] command [domain] igor@0: igor@0: Commands: igor@2: start domain igor@2: start-all igor@2: start-my-domains igor@0: igor@2: migrate-out domain igor@2: migrate-in domain root@55: migrate-out-all root@55: migrate-in-all igor@2: migrate-my-domains-home igor@28: migrate-and-start-my-domains igor@2: migrate-and-start-all igor@0: igor@2: dump-config domain igor@37: igor@37: Options: igor@37: --help (-h) -- show usage information root@55: --network=name (-n) -- the network descriptions is in the file name (default: ''network'') igor@37: igor@37: igor@2: """ igor@0: igor@0: def test(): igor@2: print "get_drbd_resources(samba)=",get_drbd_resources("samba") igor@2: print "get_domain_id(Domain-0)=",get_domain_id("Domain-0") igor@2: print "get_domain_id(samba)=",get_domain_id("samba") igor@2: print "get_drbd_id(samba)=",get_drbd_id("samba") igor@2: print "get_drbd_id(samba, he_is)=",get_drbd_id("samba",he_is) igor@2: print "get_drbd_id(unknown_resource, he_is)=",get_drbd_id("unknown_resource",he_is) igor@2: print "get_drbd_state(samba, he_is)=",get_drbd_state("samba") igor@2: print "get_drbd_state(samba, he_is)=",get_drbd_state("samba",he_is) igor@2: print "get_drbd_cstate(samba)=",get_drbd_cstate("samba") igor@2: print "get_drbd_cstate(samba, he_is)=",get_drbd_cstate("samba",he_is) igor@2: print "start_domain(samba)" igor@2: start_domain("samba") igor@2: print "migrate_domain_out(samba)" igor@2: migrate_domain_in("samba") igor@0: igor@0: igor@0: #print "get_domain_id(samba,node2)=",get_domain_id("samba",node2) igor@0: #sys.exit(0) igor@0: igor@37: network='network' igor@37: import sys,os,imp,getopt igor@37: from commands import mkarg igor@37: igor@37: try: igor@37: opts, args = getopt.getopt(sys.argv[1:], "hn:", ["help", "network="]) igor@37: except getopt.GetoptError, err: igor@38: print str(err) igor@37: usage() igor@37: sys.exit(2) igor@37: igor@37: for o, a in opts: igor@37: if o in ("-h", "--help"): igor@37: show_usage() igor@37: sys.exit() igor@37: elif o in ("-n", "--network"): igor@37: network = a igor@37: else: igor@37: assert False, "unhandled option" igor@37: igor@37: igor@37: debug=2 igor@37: igor@38: if len(args) == 2: igor@38: domain=args[1] igor@37: igor@37: sys.path.append('/etc/xen') igor@37: try: igor@39: execfile('/etc/xen/'+network) igor@38: except IOError: igor@38: print "Network configuration file <%s> not found " % network igor@38: if network == 'network': igor@38: print "You can use -n option to specify network filename" igor@38: sys.exit(2) igor@38: except NameError: igor@38: domain=domains[0] igor@40: execfile('/etc/xen/'+network) igor@37: igor@37: xen_drbd_start="/etc/xen/xen-drbd-start" igor@37: domain_create_line="xm create "+xen_drbd_start+" network="+network+" domain=%s" igor@37: igor@37: if len(args) == 0: igor@2: show_usage() igor@2: sys.exit(0) igor@0: igor@37: he_is=the_peer_of(i_am) igor@37: igor@37: command=args[0] igor@37: if len(args) == 2: igor@37: domain=args[1] igor@2: if command == 'start': igor@37: start_domain(domain, i_am) igor@2: elif command == 'migrate-out': igor@37: migrate_domain_out(domain, i_am) igor@2: elif command == 'migrate-in': igor@37: migrate_domain_in(domain, i_am) igor@2: elif command == 'dump-config': igor@2: dump_config(domain) igor@2: else: igor@2: show_usage() igor@2: sys.exit(0) igor@37: elif len(args) == 1: igor@2: if command == 'start-all': igor@37: start_all(i_am) igor@2: elif command == 'start-my-domains': igor@37: start_my_domains(i_am) igor@31: elif command == 'migrate-out-all': igor@37: migrate_out_all(i_am) igor@31: elif command == 'migrate-in-all': igor@37: migrate_in_all(i_am) igor@2: elif command == 'migrate-my-domains-home': igor@37: migrate_my_domains_home(i_am) igor@28: elif command == 'migrate-and-start-my-domains': igor@37: migrate_and_start_my_domains(i_am) igor@2: elif command == 'migrate-and-start-all': igor@37: migrate_and_start_all(i_am) igor@2: elif command == 'list': igor@37: print running_domains(i_am) igor@2: else: igor@2: show_usage() igor@2: sys.exit(0) igor@0: igor@0: igor@0: igor@0: