xen-drbd

annotate xen-drbd.py @ 36:44efea4507ac

Virtual disk name can be secified after = sign (e.g.: drbd1=sda1:dns:2G )
author igor@manas.xt.vpn
date Sat Aug 30 11:14:50 2008 +0300 (2008-08-30)
parents 311e9fe76a04
children e80bdf496aa2
rev   line source
igor@0 1 #!/usr/bin/python
igor@0 2
igor@23 3 network='od'
igor@26 4 debug=2
igor@0 5
igor@2 6 import sys,os,imp
igor@0 7 from commands import mkarg
igor@0 8
eb@1 9
igor@0 10 sys.path.append('/etc/xen')
igor@0 11 try:
igor@0 12 exec 'from %s import *' % (network)
igor@23 13 except ImportError:
igor@0 14 print "Can't find or interpret module %s with topology description" %(network)
igor@0 15 sys.exit(1)
igor@0 16
eb@5 17 xen_drbd_start="/etc/xen/xen-drbd-start"
igor@2 18 domain_create_line="xm create "+xen_drbd_start+" network="+network+" domain=%s"
igor@0 19
igor@0 20 def the_peer_of(node):
igor@2 21 if node == node1:
igor@2 22 another_node=node2
igor@2 23 else:
igor@2 24 another_node=node1
igor@2 25 return another_node
igor@0 26
igor@0 27 he_is=the_peer_of(i_am)
igor@0 28
igor@0 29 def log_error(error):
igor@2 30 print error
igor@0 31
igor@0 32 def run_now(command,node=i_am):
igor@2 33 if node == i_am:
igor@26 34 line=command+" > /dev/stderr 2>&1"
igor@2 35 else:
igor@26 36 line="ssh %s %s < /dev/null > /dev/stderr 2>&1" % (node,mkarg(command))
igor@26 37 if debug > 2:
igor@26 38 print "debug:", line
igor@2 39 (p, child_stdout, child_stderr) = os.popen3(line)
igor@2 40 output = child_stderr.read()
igor@2 41 #p = os.popen(line)
igor@2 42 #output = p.read()
igor@2 43 p.close()
igor@2 44 return output
igor@0 45
igor@0 46 def run(command,node=i_am):
igor@25 47 return run_now(command,node)
igor@25 48 #if node == i_am:
igor@25 49 # print command
igor@25 50 #else:
igor@25 51 # print "ssh %s %s < /dev/null > /dev/stderr" % (node,mkarg(command))
igor@0 52
igor@0 53
igor@0 54 def get_drbd_resources(domain):
igor@2 55 disk=[]
igor@2 56 for disk_description in disk_table[domain]:
igor@2 57 if disk_description.find(":") == -1:
igor@2 58 disk.append(domain)
igor@2 59 else:
igor@25 60 disk.append((disk_description.split(':'))[1])
igor@2 61 return disk
igor@0 62
igor@0 63 def set_drbd_primary(domain, node=i_am):
igor@26 64 res=""
igor@2 65 drbd_resources=get_drbd_resources(domain)
igor@2 66 for drbd in drbd_resources:
igor@26 67 res += run("drbdadm primary %s"%(drbd),node)
igor@26 68 print "DRBD resource <%s> on the node <%s> is <%s> now" % (drbd,node,get_drbd_state(drbd,node))
igor@26 69 return res
igor@0 70
igor@0 71 def set_drbd_secondary(domain, node=i_am):
igor@26 72 res=""
igor@2 73 drbd_resources=get_drbd_resources(domain)
igor@2 74 for drbd in drbd_resources:
igor@27 75 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 76 print "DRBD resource <%s> on the node <%s> is <%s> now" % (drbd,node,get_drbd_state(drbd,node))
igor@26 77 return res
igor@0 78
igor@0 79 def get_domain_id(domain,node=i_am):
igor@2 80 """
igor@2 81 Returns domain id of the <domain> or -1 if the <domain> is not running on the <node>
igor@2 82 """
igor@2 83 res=run_now("xm list | awk '{if ($1 == \"'%s'\") print $2}'" % domain, node).rstrip("\n")
igor@2 84 if not res:
igor@2 85 res = -1
igor@2 86 else:
igor@2 87 res = int(res)
igor@2 88 return res
igor@0 89
igor@0 90 def get_drbd_id(resource,node=i_am):
igor@2 91 res=run_now("ls -l /dev/drbd/%s 2> /dev/null | awk '{print $10}' | sed s@/dev/drbd@@" %resource, node).rstrip("\n")
igor@2 92 if not res:
igor@2 93 res = -1
igor@2 94 else:
igor@2 95 res = int(res)
igor@2 96 return res
igor@0 97
igor@0 98 def get_drbd_state(resource,node=i_am):
igor@2 99 res=run_now("drbdadm state %s | sed s@/.*@@" %resource, node).rstrip("\n")
igor@2 100 if not res:
igor@2 101 res = -1
igor@2 102 return res
igor@0 103
igor@0 104 def get_drbd_cstate(resource,node=i_am):
igor@2 105 res=run_now("drbdadm cstate %s " %resource, node).rstrip("\n")
igor@2 106 if not res:
igor@2 107 res = -1
igor@2 108 return res
igor@0 109
igor@0 110 def start_domain(domain,node=i_am):
igor@2 111 if (get_domain_id(domain,i_am) != -1):
igor@2 112 log_error("Domain %s is running already on the node %s" % (domain,i_am))
igor@2 113 return -1
igor@2 114 if (get_domain_id(domain,he_is) != -1):
igor@2 115 log_error("Domain %s is running already on the node %s" % (domain,he_is))
igor@2 116 return -1
igor@2 117 another_node=the_peer_of(node)
igor@26 118 print set_drbd_secondary(domain,another_node)
igor@26 119 print set_drbd_primary(domain,node)
igor@29 120 print run(domain_create_line % domain, node)
igor@0 121
igor@0 122 def migrate_domain_out(domain,node=i_am):
igor@2 123 if (get_domain_id(domain,node) == -1):
igor@2 124 log_error("Domain %s is not running on the node %s" % (domain,node))
igor@2 125 return -1
igor@2 126 another_node=the_peer_of(node)
igor@2 127 print "Migrating the domain <%s> from the node <%s> to the node <%s>" % (domain, node, another_node)
igor@2 128 set_drbd_primary(domain,another_node)
igor@2 129 run("xm migrate %s %s --live" % (domain,another_node),node)
igor@2 130 run("sleep 2")
igor@2 131 set_drbd_secondary(domain,node)
igor@2 132 print "+ Done"
igor@2 133
igor@0 134 def migrate_domain_in(domain,node=i_am):
igor@2 135 migrate_domain_out(domain,the_peer_of(node))
igor@0 136
igor@0 137 def migrate_domain(domain,node):
igor@2 138 migrate_domain_in(domain,node)
igor@0 139
igor@0 140 def running_domains(node=i_am):
igor@2 141 xm_domains=run_now("xm list | awk '{print $1}'", node).split("\n")
igor@2 142 return filter(lambda x: x in xm_domains, domains)
igor@0 143
igor@31 144 def migrate_out_all(node=i_am):
igor@2 145 for domain in running_domains(node):
igor@2 146 migrate_domain_out(domain,node)
igor@0 147
igor@31 148 def migrate_in_all(node=i_am):
igor@2 149 for domain in running_domains(the_peer_of(node)):
igor@2 150 migrate_domain_in(domain,node)
igor@0 151
igor@0 152 def start_all(node=i_am):
igor@2 153 for domain in domains:
igor@2 154 if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)):
igor@2 155 start_domain(domain,node)
igor@0 156
igor@0 157 def start_my_domains(node=i_am):
igor@2 158 for domain in domain_home[node]:
igor@2 159 if not domain in running_domains(node) and not domain in running_domains(the_peer_of(node)):
igor@2 160 start_domain(domain,node)
igor@0 161
igor@0 162 def migrate_my_domains_home(node=i_am):
igor@2 163 for domain in domain_home[node]:
igor@2 164 if not domain in running_domains(node) and domain in running_domains(the_peer_of(node)):
igor@2 165 migrate_domain_in(domain,node)
igor@28 166
igor@28 167 def migrate_and_start_my_domains(node=i_am):
igor@28 168 migrate_my_domains_home(node)
igor@28 169 start_my_domains(node)
igor@2 170
igor@0 171 def migrate_and_start_all(node=i_am):
igor@2 172 migrate_my_domains_home(node)
igor@2 173 start_my_domains(node)
igor@28 174 migrate_my_domains_home(the_peer_of(node))
igor@28 175 start_my_domains(the_peer_of(node))
igor@2 176
igor@2 177 def do_import(name, source):
igor@2 178 module = imp.new_module(name)
igor@2 179 sys.modules[name] = module
igor@2 180 exec source in vars(module)
igor@2 181 return module
igor@2 182
igor@2 183 def load_file(file):
igor@2 184 f=open(file)
igor@2 185 result=f.read()
igor@2 186 return result
igor@2 187
igor@2 188 def dump_config(domain):
igor@2 189 xen_domain=load_file(xen_drbd_start)
igor@2 190 xen_domain="domain=\"%s\"\n" % (domain) + xen_domain
igor@2 191 xen_domain="network=\"%s\"\n" % (network) + xen_domain
igor@2 192 do_import('xen_domain_module',xen_domain)
igor@2 193 import xen_domain_module
igor@2 194 xen_domain_module.print_config()
igor@0 195
igor@0 196 def show_usage():
igor@2 197 print """
igor@0 198 Usage:
igor@2 199 xen-drbd command [domain]
igor@0 200
igor@0 201 Commands:
igor@2 202 start domain
igor@2 203 start-all
igor@2 204 start-my-domains
igor@0 205
igor@2 206 migrate-out domain
igor@2 207 migrate-in domain
igor@2 208 migrate-all-out
igor@2 209 migrate-all-in
igor@2 210 migrate-my-domains-home
igor@28 211 migrate-and-start-my-domains
igor@2 212 migrate-and-start-all
igor@0 213
igor@2 214 dump-config domain
igor@2 215 """
igor@0 216
igor@0 217 def test():
igor@2 218 print "get_drbd_resources(samba)=",get_drbd_resources("samba")
igor@2 219 print "get_domain_id(Domain-0)=",get_domain_id("Domain-0")
igor@2 220 print "get_domain_id(samba)=",get_domain_id("samba")
igor@2 221 print "get_drbd_id(samba)=",get_drbd_id("samba")
igor@2 222 print "get_drbd_id(samba, he_is)=",get_drbd_id("samba",he_is)
igor@2 223 print "get_drbd_id(unknown_resource, he_is)=",get_drbd_id("unknown_resource",he_is)
igor@2 224 print "get_drbd_state(samba, he_is)=",get_drbd_state("samba")
igor@2 225 print "get_drbd_state(samba, he_is)=",get_drbd_state("samba",he_is)
igor@2 226 print "get_drbd_cstate(samba)=",get_drbd_cstate("samba")
igor@2 227 print "get_drbd_cstate(samba, he_is)=",get_drbd_cstate("samba",he_is)
igor@2 228 print "start_domain(samba)"
igor@2 229 start_domain("samba")
igor@2 230 print "migrate_domain_out(samba)"
igor@2 231 migrate_domain_in("samba")
igor@0 232
igor@0 233
igor@0 234 #print "get_domain_id(samba,node2)=",get_domain_id("samba",node2)
igor@0 235 #sys.exit(0)
igor@0 236
igor@0 237 if len(sys.argv) == 1:
igor@2 238 show_usage()
igor@2 239 sys.exit(0)
igor@0 240
igor@0 241 command=sys.argv[1]
igor@0 242 if len(sys.argv) == 3:
igor@2 243 domain=sys.argv[2]
igor@2 244 if command == 'start':
igor@2 245 start_domain(domain)
igor@2 246 elif command == 'migrate-out':
igor@2 247 migrate_domain_out(domain)
igor@2 248 elif command == 'migrate-in':
igor@2 249 migrate_domain_in(domain)
igor@2 250 elif command == 'dump-config':
igor@2 251 dump_config(domain)
igor@2 252 else:
igor@2 253 show_usage()
igor@2 254 sys.exit(0)
igor@0 255 elif len(sys.argv) == 2:
igor@2 256 if command == 'start-all':
igor@2 257 start_all()
igor@2 258 elif command == 'start-my-domains':
igor@2 259 start_my_domains()
igor@31 260 elif command == 'migrate-out-all':
igor@31 261 migrate_out_all()
igor@31 262 elif command == 'migrate-in-all':
igor@31 263 migrate_in_all()
igor@2 264 elif command == 'migrate-my-domains-home':
igor@2 265 migrate_my_domains_home()
igor@28 266 elif command == 'migrate-and-start-my-domains':
igor@28 267 migrate_and_start_my_domains()
igor@2 268 elif command == 'migrate-and-start-all':
igor@2 269 migrate_and_start_all()
igor@2 270 elif command == 'list':
igor@2 271 print running_domains()
igor@2 272 else:
igor@2 273 show_usage()
igor@2 274 sys.exit(0)
igor@0 275
igor@0 276
igor@0 277
igor@0 278