xen-drbd

view xen-drbd.py @ 45:a91c91c166c4

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