xen-drbd

annotate xen-drbd.py @ 60:dd23766a87c6

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