igor@0: #!/usr/bin/python igor@0: igor@0: network='eb' igor@0: igor@0: import sys,os igor@0: from commands import mkarg igor@0: igor@0: sys.path.append('/etc/xen') igor@0: try: igor@0: exec 'from %s import *' % (network) igor@0: except: igor@0: print "Can't find or interpret module %s with topology description" %(network) igor@0: sys.exit(1) igor@0: igor@0: domain_create_line="xm create xen-drbd-start network="+network+" domain=%s" igor@0: igor@0: def the_peer_of(node): igor@0: if node == node1: igor@0: another_node=node2 igor@0: else: igor@0: another_node=node1 igor@0: return another_node igor@0: igor@0: he_is=the_peer_of(i_am) igor@0: igor@0: def log_error(error): igor@0: print error igor@0: igor@0: def run_now(command,node=i_am): igor@0: if node == i_am: igor@0: line=command+" > /dev/stderr" igor@0: else: igor@0: line="ssh %s %s < /dev/null > /dev/stderr" % (node,mkarg(command)) igor@0: (p, child_stdout, child_stderr) = os.popen3(line) igor@0: output = child_stderr.read() igor@0: #p = os.popen(line) igor@0: #output = p.read() igor@0: p.close() igor@0: return output igor@0: igor@0: def run(command,node=i_am): igor@0: run_now(command,node) igor@0: # if node == i_am: igor@0: # print command igor@0: # else: igor@0: # print "ssh %s %s < /dev/null > /dev/stderr" % (node,mkarg(command)) igor@0: igor@0: igor@0: def get_drbd_resources(domain): igor@0: disk=[] igor@0: for disk_description in disk_table[domain]: igor@0: if disk_description.find(":") == -1: igor@0: disk.append(domain) igor@0: else: igor@0: disk.append((disk_description.split(':'))[0]) igor@0: return disk igor@0: igor@0: igor@0: def set_drbd_primary(domain, node=i_am): igor@0: drbd_resources=get_drbd_resources(domain) igor@0: for drbd in drbd_resources: igor@0: run("drbdadm primary %s"%(drbd),node) igor@0: igor@0: def set_drbd_secondary(domain, node=i_am): igor@0: drbd_resources=get_drbd_resources(domain) igor@0: for drbd in drbd_resources: igor@0: run("drbdadm secondary %s"%(drbd),node) igor@0: igor@0: def get_domain_id(domain,node=i_am): igor@0: """ igor@0: Returns domain id of the or -1 if the is not running on the igor@0: """ igor@0: res=run_now("xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain, node).rstrip("\n") igor@0: if not res: igor@0: res = -1 igor@0: else: igor@0: res = int(res) igor@0: return res igor@0: igor@0: def get_drbd_id(resource,node=i_am): igor@0: res=run_now("ls -l /dev/drbd/%s 2> /dev/null | awk '{print $10}' | sed s@/dev/drbd@@" %resource, node).rstrip("\n") igor@0: if not res: igor@0: res = -1 igor@0: else: igor@0: res = int(res) igor@0: return res igor@0: igor@0: def get_drbd_state(resource,node=i_am): igor@0: res=run_now("drbdadm state %s | sed s@/.*@@" %resource, node).rstrip("\n") igor@0: if not res: igor@0: res = -1 igor@0: return res igor@0: igor@0: def get_drbd_cstate(resource,node=i_am): igor@0: res=run_now("drbdadm cstate %s " %resource, node).rstrip("\n") igor@0: if not res: igor@0: res = -1 igor@0: return res igor@0: igor@0: igor@0: def start_domain(domain,node=i_am): igor@0: if (get_domain_id(domain,i_am) != -1): igor@0: log_error("Domain %s is running already on the node %s" % (domain,i_am)) igor@0: return -1 igor@0: if (get_domain_id(domain,he_is) != -1): igor@0: log_error("Domain %s is running already on the node %s" % (domain,he_is)) igor@0: return -1 igor@0: another_node=the_peer_of(node) igor@0: set_drbd_secondary(domain,another_node) igor@0: set_drbd_primary(domain,node) igor@0: run(domain_create_line % domain) igor@0: igor@0: def migrate_domain_out(domain,node=i_am): igor@0: if (get_domain_id(domain,node) == -1): igor@0: log_error("Domain %s is not running on the node %s" % (domain,node)) igor@0: return -1 igor@0: another_node=the_peer_of(node) igor@0: print "Migrating the domain <%s> from the node <%s> to the node <%s>" % (domain, node, another_node) igor@0: set_drbd_primary(domain,another_node) igor@0: run("xm migrate %s %s --live" % (domain,another_node),node) igor@0: run("sleep 2") igor@0: set_drbd_secondary(domain,node) igor@0: print "+ Done" igor@0: igor@0: def migrate_domain_in(domain,node=i_am): igor@0: migrate_domain_out(domain,the_peer_of(node)) igor@0: igor@0: def migrate_domain(domain,node): igor@0: migrate_domain_in(domain,node) igor@0: igor@0: def running_domains(node=i_am): igor@0: xm_domains=run_now("xm list | awk '{print $1}'", node).split("\n") igor@0: return filter(lambda x: x in xm_domains, domains) igor@0: igor@0: def migrate_all_out(node=i_am): igor@0: for domain in running_domains(node): igor@0: migrate_domain_out(domain,node) igor@0: igor@0: def migrate_all_in(node=i_am): igor@0: for domain in running_domains(the_peer_of(node)): igor@0: migrate_domain_in(domain,node) igor@0: igor@0: def start_all(node=i_am): igor@0: for domain in domains: igor@0: if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)): igor@0: start_domain(domain,node) igor@0: igor@0: def start_my_domains(node=i_am): igor@0: for domain in domain_home[node]: igor@0: if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)): igor@0: start_domain(domain,node) igor@0: igor@0: def migrate_my_domains_home(node=i_am): igor@0: for domain in domain_home[node]: igor@0: if not domain in running_domains(node) and domain in running_domains(the_peer_of(node)): igor@0: migrate_domain_in(domain,node) igor@0: igor@0: def migrate_and_start_all(node=i_am): igor@0: migrate_my_domains_home(node) igor@0: start_my_domains(node) igor@0: igor@0: def show_usage(): igor@0: print """ igor@0: Usage: igor@0: xen-drbd command [domain] igor@0: igor@0: Commands: igor@0: start domain igor@0: start-all igor@0: start-my-domains igor@0: igor@0: migrate-out domain igor@0: migrate-in domain igor@0: migrate-all-out igor@0: migrate-all-in igor@0: migrate-my-domains-home igor@0: igor@0: migrate-and-start-all igor@0: """ igor@0: igor@0: def test(): igor@0: print "get_drbd_resources(samba)=",get_drbd_resources("samba") igor@0: print "get_domain_id(Domain-0)=",get_domain_id("Domain-0") igor@0: print "get_domain_id(samba)=",get_domain_id("samba") igor@0: print "get_drbd_id(samba)=",get_drbd_id("samba") igor@0: print "get_drbd_id(samba, he_is)=",get_drbd_id("samba",he_is) igor@0: print "get_drbd_id(unknown_resource, he_is)=",get_drbd_id("unknown_resource",he_is) igor@0: print "get_drbd_state(samba, he_is)=",get_drbd_state("samba") igor@0: print "get_drbd_state(samba, he_is)=",get_drbd_state("samba",he_is) igor@0: print "get_drbd_cstate(samba)=",get_drbd_cstate("samba") igor@0: print "get_drbd_cstate(samba, he_is)=",get_drbd_cstate("samba",he_is) igor@0: print "start_domain(samba)" igor@0: start_domain("samba") igor@0: print "migrate_domain_out(samba)" igor@0: 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@0: if len(sys.argv) == 1: igor@0: show_usage() igor@0: sys.exit(0) igor@0: igor@0: command=sys.argv[1] igor@0: if len(sys.argv) == 3: igor@0: domain=sys.argv[2] igor@0: if command == 'start': igor@0: start_domain(domain) igor@0: elif command == 'migrate-out': igor@0: migrate_domain_out(domain) igor@0: elif command == 'migrate-in': igor@0: migrate_domain_in(domain) igor@0: else: igor@0: show_usage() igor@0: sys.exit(0) igor@0: elif len(sys.argv) == 2: igor@0: if command == 'start-all': igor@0: start_all() igor@0: elif command == 'start-my-domains': igor@0: start_my_domains() igor@0: elif command == 'migrate-all-out': igor@0: migrate_all_out() igor@0: elif command == 'migrate-all-in': igor@0: migrate_all_in() igor@0: elif command == 'migrate-my-domains-home': igor@0: migrate_my_domains_home() igor@0: elif command == 'migrate-and-start-all': igor@0: migrate_and_start_all() igor@0: elif command == 'list': igor@0: print running_domains() igor@0: else: igor@0: show_usage() igor@0: sys.exit(0) igor@0: igor@0: igor@0: igor@0: