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@26
|
120 print run(domain_create_line % domain)
|
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@0
|
144 def migrate_all_out(node=i_am):
|
igor@2
|
145 for domain in running_domains(node):
|
igor@2
|
146 migrate_domain_out(domain,node)
|
igor@0
|
147
|
igor@0
|
148 def migrate_all_in(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@2
|
260 elif command == 'migrate-all-out':
|
igor@2
|
261 migrate_all_out()
|
igor@2
|
262 elif command == 'migrate-all-in':
|
igor@2
|
263 migrate_all_in()
|
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
|