root / scripts / gnt-instance @ 2ec08468
History | View | Annotate | Download (18.5 kB)
1 | a8083063 | Iustin Pop | #!/usr/bin/python |
---|---|---|---|
2 | a8083063 | Iustin Pop | # |
3 | a8083063 | Iustin Pop | |
4 | a8083063 | Iustin Pop | # Copyright (C) 2006, 2007 Google Inc. |
5 | a8083063 | Iustin Pop | # |
6 | a8083063 | Iustin Pop | # This program is free software; you can redistribute it and/or modify |
7 | a8083063 | Iustin Pop | # it under the terms of the GNU General Public License as published by |
8 | a8083063 | Iustin Pop | # the Free Software Foundation; either version 2 of the License, or |
9 | a8083063 | Iustin Pop | # (at your option) any later version. |
10 | a8083063 | Iustin Pop | # |
11 | a8083063 | Iustin Pop | # This program is distributed in the hope that it will be useful, but |
12 | a8083063 | Iustin Pop | # WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | a8083063 | Iustin Pop | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | a8083063 | Iustin Pop | # General Public License for more details. |
15 | a8083063 | Iustin Pop | # |
16 | a8083063 | Iustin Pop | # You should have received a copy of the GNU General Public License |
17 | a8083063 | Iustin Pop | # along with this program; if not, write to the Free Software |
18 | a8083063 | Iustin Pop | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
19 | a8083063 | Iustin Pop | # 02110-1301, USA. |
20 | a8083063 | Iustin Pop | |
21 | a8083063 | Iustin Pop | |
22 | a8083063 | Iustin Pop | import sys |
23 | a8083063 | Iustin Pop | import os |
24 | a8083063 | Iustin Pop | from optparse import make_option |
25 | a8083063 | Iustin Pop | from cStringIO import StringIO |
26 | a8083063 | Iustin Pop | |
27 | a8083063 | Iustin Pop | from ganeti.cli import * |
28 | a8083063 | Iustin Pop | from ganeti import opcodes |
29 | a8083063 | Iustin Pop | from ganeti import logger |
30 | a8083063 | Iustin Pop | from ganeti import constants |
31 | a8083063 | Iustin Pop | from ganeti import utils |
32 | a8083063 | Iustin Pop | |
33 | a8083063 | Iustin Pop | |
34 | a8083063 | Iustin Pop | def ListInstances(opts, args): |
35 | a8083063 | Iustin Pop | """List nodes and their properties. |
36 | a8083063 | Iustin Pop | |
37 | a8083063 | Iustin Pop | """ |
38 | a8083063 | Iustin Pop | if opts.output is None: |
39 | a8083063 | Iustin Pop | selected_fields = ["name", "os", "pnode", "admin_state", |
40 | a8083063 | Iustin Pop | "oper_state", "oper_ram"] |
41 | a8083063 | Iustin Pop | else: |
42 | a8083063 | Iustin Pop | selected_fields = opts.output.split(",") |
43 | a8083063 | Iustin Pop | |
44 | a8083063 | Iustin Pop | op = opcodes.OpQueryInstances(output_fields=selected_fields) |
45 | a8083063 | Iustin Pop | output = SubmitOpCode(op) |
46 | a8083063 | Iustin Pop | |
47 | a8083063 | Iustin Pop | if not opts.no_headers: |
48 | 137161c9 | Michael Hanselmann | headers = {"name": "Instance", "os": "OS", "pnode": "Primary_node", |
49 | 137161c9 | Michael Hanselmann | "snodes": "Secondary_Nodes", "admin_state": "Autostart", |
50 | 137161c9 | Michael Hanselmann | "oper_state": "Status", "admin_ram": "Configured_memory", |
51 | 137161c9 | Michael Hanselmann | "oper_ram": "Memory", "disk_template": "Disk_template", |
52 | 137161c9 | Michael Hanselmann | "ip": "IP Address", "mac": "MAC Address", |
53 | 644eeef9 | Iustin Pop | "bridge": "Bridge", |
54 | 644eeef9 | Iustin Pop | "sda_size": "Disk/0", "sdb_size": "Disk/1"} |
55 | 137161c9 | Michael Hanselmann | else: |
56 | 137161c9 | Michael Hanselmann | headers = None |
57 | 137161c9 | Michael Hanselmann | |
58 | 137161c9 | Michael Hanselmann | if opts.human_readable: |
59 | 644eeef9 | Iustin Pop | unitfields = ["admin_ram", "oper_ram", "sda_size", "sdb_size"] |
60 | 137161c9 | Michael Hanselmann | else: |
61 | 137161c9 | Michael Hanselmann | unitfields = None |
62 | 137161c9 | Michael Hanselmann | |
63 | 644eeef9 | Iustin Pop | numfields = ["admin_ram", "oper_ram", "sda_size", "sdb_size"] |
64 | 137161c9 | Michael Hanselmann | |
65 | 16be8703 | Iustin Pop | data = GenerateTable(separator=opts.separator, headers=headers, |
66 | 16be8703 | Iustin Pop | fields=selected_fields, unitfields=unitfields, |
67 | 16be8703 | Iustin Pop | numfields=numfields, data=output) |
68 | 16be8703 | Iustin Pop | |
69 | 16be8703 | Iustin Pop | for line in data: |
70 | 16be8703 | Iustin Pop | logger.ToStdout(line) |
71 | a8083063 | Iustin Pop | |
72 | a8083063 | Iustin Pop | return 0 |
73 | a8083063 | Iustin Pop | |
74 | a8083063 | Iustin Pop | |
75 | a8083063 | Iustin Pop | def AddInstance(opts, args): |
76 | a8083063 | Iustin Pop | """Add an instance to the cluster. |
77 | a8083063 | Iustin Pop | |
78 | a8083063 | Iustin Pop | Args: |
79 | a8083063 | Iustin Pop | opts - class with options as members |
80 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
81 | a8083063 | Iustin Pop | Opts used: |
82 | a8083063 | Iustin Pop | mem - amount of memory to allocate to instance (MiB) |
83 | a8083063 | Iustin Pop | size - amount of disk space to allocate to instance (MiB) |
84 | a8083063 | Iustin Pop | os - which OS to run on instance |
85 | a8083063 | Iustin Pop | node - node to run new instance on |
86 | a8083063 | Iustin Pop | |
87 | a8083063 | Iustin Pop | """ |
88 | a8083063 | Iustin Pop | instance = args[0] |
89 | a8083063 | Iustin Pop | |
90 | a8083063 | Iustin Pop | op = opcodes.OpCreateInstance(instance_name=instance, mem_size=opts.mem, |
91 | a8083063 | Iustin Pop | disk_size=opts.size, swap_size=opts.swap, |
92 | a8083063 | Iustin Pop | disk_template=opts.disk_template, |
93 | a8083063 | Iustin Pop | mode=constants.INSTANCE_CREATE, |
94 | a8083063 | Iustin Pop | os_type=opts.os, pnode=opts.node, |
95 | a8083063 | Iustin Pop | snode=opts.snode, vcpus=opts.vcpus, |
96 | a8083063 | Iustin Pop | ip=opts.ip, bridge=opts.bridge, start=True, |
97 | a8083063 | Iustin Pop | wait_for_sync=opts.wait_for_sync) |
98 | a8083063 | Iustin Pop | SubmitOpCode(op) |
99 | a8083063 | Iustin Pop | return 0 |
100 | a8083063 | Iustin Pop | |
101 | a8083063 | Iustin Pop | |
102 | fe7b0351 | Michael Hanselmann | def ReinstallInstance(opts, args): |
103 | fe7b0351 | Michael Hanselmann | """Reinstall an instance. |
104 | fe7b0351 | Michael Hanselmann | |
105 | fe7b0351 | Michael Hanselmann | Args: |
106 | fe7b0351 | Michael Hanselmann | opts - class with options as members |
107 | fe7b0351 | Michael Hanselmann | args - list containing a single element, the instance name |
108 | fe7b0351 | Michael Hanselmann | |
109 | fe7b0351 | Michael Hanselmann | """ |
110 | fe7b0351 | Michael Hanselmann | instance_name = args[0] |
111 | fe7b0351 | Michael Hanselmann | |
112 | fe7b0351 | Michael Hanselmann | if not opts.force: |
113 | fe7b0351 | Michael Hanselmann | usertext = ("This will reinstall the instance %s and remove " |
114 | fe7b0351 | Michael Hanselmann | "all data. Continue?") % instance_name |
115 | fe7b0351 | Michael Hanselmann | if not opts._ask_user(usertext): |
116 | fe7b0351 | Michael Hanselmann | return 1 |
117 | fe7b0351 | Michael Hanselmann | |
118 | d0834de3 | Michael Hanselmann | op = opcodes.OpReinstallInstance(instance_name=instance_name, |
119 | d0834de3 | Michael Hanselmann | os_type=opts.os) |
120 | fe7b0351 | Michael Hanselmann | SubmitOpCode(op) |
121 | fe7b0351 | Michael Hanselmann | |
122 | fe7b0351 | Michael Hanselmann | return 0 |
123 | fe7b0351 | Michael Hanselmann | |
124 | fe7b0351 | Michael Hanselmann | |
125 | a8083063 | Iustin Pop | def RemoveInstance(opts, args): |
126 | a8083063 | Iustin Pop | """Remove an instance. |
127 | a8083063 | Iustin Pop | |
128 | a8083063 | Iustin Pop | Args: |
129 | a8083063 | Iustin Pop | opts - class with options as members |
130 | a8083063 | Iustin Pop | args - list containing a single element, the instance name |
131 | a8083063 | Iustin Pop | |
132 | a8083063 | Iustin Pop | """ |
133 | a8083063 | Iustin Pop | instance_name = args[0] |
134 | a8083063 | Iustin Pop | force = opts.force |
135 | a8083063 | Iustin Pop | |
136 | a8083063 | Iustin Pop | if not force: |
137 | a8083063 | Iustin Pop | usertext = ("This will remove the volumes of the instance %s" |
138 | a8083063 | Iustin Pop | " (including mirrors), thus removing all the data" |
139 | a8083063 | Iustin Pop | " of the instance. Continue?") % instance_name |
140 | a8083063 | Iustin Pop | if not opts._ask_user(usertext): |
141 | a8083063 | Iustin Pop | return 1 |
142 | a8083063 | Iustin Pop | |
143 | a8083063 | Iustin Pop | op = opcodes.OpRemoveInstance(instance_name=instance_name) |
144 | a8083063 | Iustin Pop | SubmitOpCode(op) |
145 | a8083063 | Iustin Pop | return 0 |
146 | a8083063 | Iustin Pop | |
147 | a8083063 | Iustin Pop | |
148 | a8083063 | Iustin Pop | def ActivateDisks(opts, args): |
149 | a8083063 | Iustin Pop | """Activate an instance's disks. |
150 | a8083063 | Iustin Pop | |
151 | a8083063 | Iustin Pop | This serves two purposes: |
152 | a8083063 | Iustin Pop | - it allows one (as long as the instance is not running) to mount |
153 | a8083063 | Iustin Pop | the disks and modify them from the node |
154 | a8083063 | Iustin Pop | - it repairs inactive secondary drbds |
155 | a8083063 | Iustin Pop | |
156 | a8083063 | Iustin Pop | """ |
157 | a8083063 | Iustin Pop | instance_name = args[0] |
158 | a8083063 | Iustin Pop | op = opcodes.OpActivateInstanceDisks(instance_name=instance_name) |
159 | a8083063 | Iustin Pop | disks_info = SubmitOpCode(op) |
160 | a8083063 | Iustin Pop | for host, iname, nname in disks_info: |
161 | a8083063 | Iustin Pop | print "%s:%s:%s" % (host, iname, nname) |
162 | a8083063 | Iustin Pop | return 0 |
163 | a8083063 | Iustin Pop | |
164 | a8083063 | Iustin Pop | |
165 | a8083063 | Iustin Pop | def DeactivateDisks(opts, args): |
166 | a8083063 | Iustin Pop | """Command-line interface for _ShutdownInstanceBlockDevices. |
167 | a8083063 | Iustin Pop | |
168 | a8083063 | Iustin Pop | This function takes the instance name, looks for its primary node |
169 | a8083063 | Iustin Pop | and the tries to shutdown its block devices on that node. |
170 | a8083063 | Iustin Pop | |
171 | a8083063 | Iustin Pop | """ |
172 | a8083063 | Iustin Pop | instance_name = args[0] |
173 | a8083063 | Iustin Pop | op = opcodes.OpDeactivateInstanceDisks(instance_name=instance_name) |
174 | a8083063 | Iustin Pop | SubmitOpCode(op) |
175 | a8083063 | Iustin Pop | return 0 |
176 | a8083063 | Iustin Pop | |
177 | a8083063 | Iustin Pop | |
178 | a8083063 | Iustin Pop | def StartupInstance(opts, args): |
179 | a8083063 | Iustin Pop | """Shutdown an instance. |
180 | a8083063 | Iustin Pop | |
181 | a8083063 | Iustin Pop | Args: |
182 | a8083063 | Iustin Pop | opts - class with options as members |
183 | a8083063 | Iustin Pop | args - list containing a single element, the instance name |
184 | a8083063 | Iustin Pop | |
185 | a8083063 | Iustin Pop | """ |
186 | a8083063 | Iustin Pop | instance_name = args[0] |
187 | a8083063 | Iustin Pop | op = opcodes.OpStartupInstance(instance_name=instance_name, force=opts.force, |
188 | a8083063 | Iustin Pop | extra_args=opts.extra_args) |
189 | a8083063 | Iustin Pop | SubmitOpCode(op) |
190 | a8083063 | Iustin Pop | return 0 |
191 | a8083063 | Iustin Pop | |
192 | a8083063 | Iustin Pop | |
193 | a8083063 | Iustin Pop | def ShutdownInstance(opts, args): |
194 | a8083063 | Iustin Pop | """Shutdown an instance. |
195 | a8083063 | Iustin Pop | |
196 | a8083063 | Iustin Pop | Args: |
197 | a8083063 | Iustin Pop | opts - class with options as members |
198 | a8083063 | Iustin Pop | args - list containing a single element, the instance name |
199 | a8083063 | Iustin Pop | |
200 | a8083063 | Iustin Pop | """ |
201 | a8083063 | Iustin Pop | instance_name = args[0] |
202 | a8083063 | Iustin Pop | op = opcodes.OpShutdownInstance(instance_name=instance_name) |
203 | a8083063 | Iustin Pop | SubmitOpCode(op) |
204 | a8083063 | Iustin Pop | return 0 |
205 | a8083063 | Iustin Pop | |
206 | a8083063 | Iustin Pop | |
207 | a8083063 | Iustin Pop | def AddMDDRBDComponent(opts, args): |
208 | a8083063 | Iustin Pop | """Add a new component to a remote_raid1 disk. |
209 | a8083063 | Iustin Pop | |
210 | a8083063 | Iustin Pop | Args: |
211 | a8083063 | Iustin Pop | opts - class with options as members |
212 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
213 | a8083063 | Iustin Pop | |
214 | a8083063 | Iustin Pop | """ |
215 | a8083063 | Iustin Pop | op = opcodes.OpAddMDDRBDComponent(instance_name=args[0], |
216 | a8083063 | Iustin Pop | disk_name=opts.disk, |
217 | a8083063 | Iustin Pop | remote_node=opts.node) |
218 | a8083063 | Iustin Pop | SubmitOpCode(op) |
219 | a8083063 | Iustin Pop | return 0 |
220 | a8083063 | Iustin Pop | |
221 | a8083063 | Iustin Pop | |
222 | a8083063 | Iustin Pop | def RemoveMDDRBDComponent(opts, args): |
223 | bdb8c997 | Guido Trotter | """Remove a component from a remote_raid1 disk. |
224 | a8083063 | Iustin Pop | |
225 | a8083063 | Iustin Pop | Args: |
226 | a8083063 | Iustin Pop | opts - class with options as members |
227 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
228 | a8083063 | Iustin Pop | |
229 | a8083063 | Iustin Pop | """ |
230 | a8083063 | Iustin Pop | op = opcodes.OpRemoveMDDRBDComponent(instance_name=args[0], |
231 | a8083063 | Iustin Pop | disk_name=opts.disk, |
232 | a8083063 | Iustin Pop | disk_id=opts.port) |
233 | a8083063 | Iustin Pop | SubmitOpCode(op) |
234 | a8083063 | Iustin Pop | return 0 |
235 | a8083063 | Iustin Pop | |
236 | a8083063 | Iustin Pop | |
237 | a8083063 | Iustin Pop | def ReplaceDisks(opts, args): |
238 | a8083063 | Iustin Pop | """Replace the disks of an instance |
239 | a8083063 | Iustin Pop | |
240 | a8083063 | Iustin Pop | Args: |
241 | a8083063 | Iustin Pop | opts - class with options as members |
242 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
243 | a8083063 | Iustin Pop | |
244 | a8083063 | Iustin Pop | """ |
245 | a8083063 | Iustin Pop | instance_name = args[0] |
246 | a8083063 | Iustin Pop | new_secondary = opts.new_secondary |
247 | a8083063 | Iustin Pop | op = opcodes.OpReplaceDisks(instance_name=args[0], |
248 | a8083063 | Iustin Pop | remote_node=opts.new_secondary) |
249 | a8083063 | Iustin Pop | SubmitOpCode(op) |
250 | a8083063 | Iustin Pop | return 0 |
251 | a8083063 | Iustin Pop | |
252 | a8083063 | Iustin Pop | |
253 | a8083063 | Iustin Pop | def FailoverInstance(opts, args): |
254 | a8083063 | Iustin Pop | """Failover an instance. |
255 | a8083063 | Iustin Pop | |
256 | a8083063 | Iustin Pop | The failover is done by shutting it down on its present node and |
257 | a8083063 | Iustin Pop | starting it on the secondary. |
258 | a8083063 | Iustin Pop | |
259 | a8083063 | Iustin Pop | Args: |
260 | a8083063 | Iustin Pop | opts - class with options as members |
261 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
262 | a8083063 | Iustin Pop | Opts used: |
263 | a8083063 | Iustin Pop | force - whether to failover without asking questions. |
264 | a8083063 | Iustin Pop | |
265 | a8083063 | Iustin Pop | """ |
266 | a8083063 | Iustin Pop | instance_name = args[0] |
267 | a8083063 | Iustin Pop | force = opts.force |
268 | a8083063 | Iustin Pop | |
269 | a8083063 | Iustin Pop | if not force: |
270 | a8083063 | Iustin Pop | usertext = ("Failover will happen to image %s." |
271 | a8083063 | Iustin Pop | " This requires a shutdown of the instance. Continue?" % |
272 | a8083063 | Iustin Pop | (instance_name,)) |
273 | a8083063 | Iustin Pop | if not opts._ask_user(usertext): |
274 | a8083063 | Iustin Pop | return 1 |
275 | a8083063 | Iustin Pop | |
276 | a8083063 | Iustin Pop | op = opcodes.OpFailoverInstance(instance_name=instance_name, |
277 | a8083063 | Iustin Pop | ignore_consistency=opts.ignore_consistency) |
278 | a8083063 | Iustin Pop | SubmitOpCode(op) |
279 | a8083063 | Iustin Pop | return 0 |
280 | a8083063 | Iustin Pop | |
281 | a8083063 | Iustin Pop | |
282 | a8083063 | Iustin Pop | def ConnectToInstanceConsole(opts, args): |
283 | a8083063 | Iustin Pop | """Connect to the console of an instance. |
284 | a8083063 | Iustin Pop | |
285 | a8083063 | Iustin Pop | Args: |
286 | a8083063 | Iustin Pop | opts - class with options as members |
287 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
288 | a8083063 | Iustin Pop | |
289 | a8083063 | Iustin Pop | """ |
290 | a8083063 | Iustin Pop | instance_name = args[0] |
291 | a8083063 | Iustin Pop | |
292 | a8083063 | Iustin Pop | op = opcodes.OpConnectConsole(instance_name=instance_name) |
293 | 82122173 | Iustin Pop | cmd, argv = SubmitOpCode(op) |
294 | a8083063 | Iustin Pop | # drop lock and exec so other commands can run while we have console |
295 | a8083063 | Iustin Pop | utils.Unlock("cmd") |
296 | a8083063 | Iustin Pop | try: |
297 | 82122173 | Iustin Pop | os.execvp(cmd, argv) |
298 | a8083063 | Iustin Pop | finally: |
299 | 82122173 | Iustin Pop | sys.stderr.write("Can't run console command %s with arguments:\n'%s'" % |
300 | 82122173 | Iustin Pop | (cmd, " ".join(argv))) |
301 | a8083063 | Iustin Pop | os._exit(1) |
302 | a8083063 | Iustin Pop | |
303 | a8083063 | Iustin Pop | |
304 | a8083063 | Iustin Pop | def _FormatBlockDevInfo(buf, dev, indent_level): |
305 | a8083063 | Iustin Pop | """Show block device information. |
306 | a8083063 | Iustin Pop | |
307 | a8083063 | Iustin Pop | This is only used by ShowInstanceConfig(), but it's too big to be |
308 | a8083063 | Iustin Pop | left for an inline definition. |
309 | a8083063 | Iustin Pop | |
310 | a8083063 | Iustin Pop | """ |
311 | a8083063 | Iustin Pop | def helper(buf, dtype, status): |
312 | a8083063 | Iustin Pop | """Format one line for phsyical device status.""" |
313 | a8083063 | Iustin Pop | if not status: |
314 | a8083063 | Iustin Pop | buf.write("not active\n") |
315 | a8083063 | Iustin Pop | else: |
316 | a8083063 | Iustin Pop | (path, major, minor, syncp, estt, degr) = status |
317 | a8083063 | Iustin Pop | buf.write("%s (%d:%d)" % (path, major, minor)) |
318 | a8083063 | Iustin Pop | if dtype in ("md_raid1", "drbd"): |
319 | a8083063 | Iustin Pop | if syncp is not None: |
320 | a8083063 | Iustin Pop | sync_text = "*RECOVERING* %5.2f%%," % syncp |
321 | a8083063 | Iustin Pop | if estt: |
322 | a8083063 | Iustin Pop | sync_text += " ETA %ds" % estt |
323 | a8083063 | Iustin Pop | else: |
324 | a8083063 | Iustin Pop | sync_text += " ETA unknown" |
325 | a8083063 | Iustin Pop | else: |
326 | a8083063 | Iustin Pop | sync_text = "in sync" |
327 | a8083063 | Iustin Pop | if degr: |
328 | a8083063 | Iustin Pop | degr_text = "*DEGRADED*" |
329 | a8083063 | Iustin Pop | else: |
330 | a8083063 | Iustin Pop | degr_text = "ok" |
331 | a8083063 | Iustin Pop | buf.write(" %s, status %s" % (sync_text, degr_text)) |
332 | a8083063 | Iustin Pop | buf.write("\n") |
333 | a8083063 | Iustin Pop | |
334 | a8083063 | Iustin Pop | if dev["iv_name"] is not None: |
335 | a8083063 | Iustin Pop | data = " - %s, " % dev["iv_name"] |
336 | a8083063 | Iustin Pop | else: |
337 | a8083063 | Iustin Pop | data = " - " |
338 | a8083063 | Iustin Pop | data += "type: %s" % dev["dev_type"] |
339 | a8083063 | Iustin Pop | if dev["logical_id"] is not None: |
340 | a8083063 | Iustin Pop | data += ", logical_id: %s" % (dev["logical_id"],) |
341 | a8083063 | Iustin Pop | elif dev["physical_id"] is not None: |
342 | a8083063 | Iustin Pop | data += ", physical_id: %s" % (dev["physical_id"],) |
343 | a8083063 | Iustin Pop | buf.write("%*s%s\n" % (2*indent_level, "", data)) |
344 | a8083063 | Iustin Pop | buf.write("%*s primary: " % (2*indent_level, "")) |
345 | a8083063 | Iustin Pop | helper(buf, dev["dev_type"], dev["pstatus"]) |
346 | a8083063 | Iustin Pop | |
347 | a8083063 | Iustin Pop | if dev["sstatus"]: |
348 | a8083063 | Iustin Pop | buf.write("%*s secondary: " % (2*indent_level, "")) |
349 | a8083063 | Iustin Pop | helper(buf, dev["dev_type"], dev["sstatus"]) |
350 | a8083063 | Iustin Pop | |
351 | a8083063 | Iustin Pop | if dev["children"]: |
352 | a8083063 | Iustin Pop | for child in dev["children"]: |
353 | a8083063 | Iustin Pop | _FormatBlockDevInfo(buf, child, indent_level+1) |
354 | a8083063 | Iustin Pop | |
355 | a8083063 | Iustin Pop | |
356 | a8083063 | Iustin Pop | def ShowInstanceConfig(opts, args): |
357 | a8083063 | Iustin Pop | """Compute instance run-time status. |
358 | a8083063 | Iustin Pop | |
359 | a8083063 | Iustin Pop | """ |
360 | a8083063 | Iustin Pop | retcode = 0 |
361 | a8083063 | Iustin Pop | op = opcodes.OpQueryInstanceData(instances=args) |
362 | a8083063 | Iustin Pop | result = SubmitOpCode(op) |
363 | a8083063 | Iustin Pop | |
364 | a8083063 | Iustin Pop | if not result: |
365 | a8083063 | Iustin Pop | logger.ToStdout("No instances.") |
366 | a8083063 | Iustin Pop | return 1 |
367 | a8083063 | Iustin Pop | |
368 | a8083063 | Iustin Pop | buf = StringIO() |
369 | a8083063 | Iustin Pop | retcode = 0 |
370 | a8083063 | Iustin Pop | for instance_name in result: |
371 | a8083063 | Iustin Pop | instance = result[instance_name] |
372 | a8083063 | Iustin Pop | buf.write("Instance name: %s\n" % instance["name"]) |
373 | a8083063 | Iustin Pop | buf.write("State: configured to be %s, actual state is %s\n" % |
374 | a8083063 | Iustin Pop | (instance["config_state"], instance["run_state"])) |
375 | a8083063 | Iustin Pop | buf.write(" Nodes:\n") |
376 | a8083063 | Iustin Pop | buf.write(" - primary: %s\n" % instance["pnode"]) |
377 | a8083063 | Iustin Pop | buf.write(" - secondaries: %s\n" % ", ".join(instance["snodes"])) |
378 | a8083063 | Iustin Pop | buf.write(" Operating system: %s\n" % instance["os"]) |
379 | a8083063 | Iustin Pop | buf.write(" Hardware:\n") |
380 | a8083063 | Iustin Pop | buf.write(" - memory: %dMiB\n" % instance["memory"]) |
381 | a8083063 | Iustin Pop | buf.write(" - NICs: %s\n" % |
382 | a8083063 | Iustin Pop | ", ".join(["{MAC: %s, IP: %s, bridge: %s}" % |
383 | a8083063 | Iustin Pop | (mac, ip, bridge) |
384 | a8083063 | Iustin Pop | for mac, ip, bridge in instance["nics"]])) |
385 | a8083063 | Iustin Pop | buf.write(" Block devices:\n") |
386 | a8083063 | Iustin Pop | |
387 | a8083063 | Iustin Pop | for device in instance["disks"]: |
388 | a8083063 | Iustin Pop | _FormatBlockDevInfo(buf, device, 1) |
389 | a8083063 | Iustin Pop | |
390 | a8083063 | Iustin Pop | logger.ToStdout(buf.getvalue().rstrip('\n')) |
391 | a8083063 | Iustin Pop | return retcode |
392 | a8083063 | Iustin Pop | |
393 | a8083063 | Iustin Pop | |
394 | a8083063 | Iustin Pop | def SetInstanceParms(opts, args): |
395 | a8083063 | Iustin Pop | """Modifies an instance. |
396 | a8083063 | Iustin Pop | |
397 | a8083063 | Iustin Pop | All parameters take effect only at the next restart of the instance. |
398 | a8083063 | Iustin Pop | |
399 | a8083063 | Iustin Pop | Args: |
400 | a8083063 | Iustin Pop | opts - class with options as members |
401 | a8083063 | Iustin Pop | args - list with a single element, the instance name |
402 | a8083063 | Iustin Pop | Opts used: |
403 | a8083063 | Iustin Pop | memory - the new memory size |
404 | a8083063 | Iustin Pop | vcpus - the new number of cpus |
405 | a8083063 | Iustin Pop | |
406 | a8083063 | Iustin Pop | """ |
407 | a8083063 | Iustin Pop | if not opts.mem and not opts.vcpus and not opts.ip and not opts.bridge: |
408 | a8083063 | Iustin Pop | logger.ToStdout("Please give at least one of the parameters.") |
409 | a8083063 | Iustin Pop | return 1 |
410 | a8083063 | Iustin Pop | |
411 | a8083063 | Iustin Pop | op = opcodes.OpSetInstanceParms(instance_name=args[0], mem=opts.mem, |
412 | a8083063 | Iustin Pop | vcpus=opts.vcpus, ip=opts.ip, |
413 | a8083063 | Iustin Pop | bridge=opts.bridge) |
414 | a8083063 | Iustin Pop | result = SubmitOpCode(op) |
415 | a8083063 | Iustin Pop | |
416 | a8083063 | Iustin Pop | if result: |
417 | a8083063 | Iustin Pop | logger.ToStdout("Modified instance %s" % args[0]) |
418 | a8083063 | Iustin Pop | for param, data in result: |
419 | a8083063 | Iustin Pop | logger.ToStdout(" - %-5s -> %s" % (param, data)) |
420 | a8083063 | Iustin Pop | logger.ToStdout("Please don't forget that these parameters take effect" |
421 | a8083063 | Iustin Pop | " only at the next start of the instance.") |
422 | a8083063 | Iustin Pop | return 0 |
423 | a8083063 | Iustin Pop | |
424 | a8083063 | Iustin Pop | |
425 | a8083063 | Iustin Pop | # options used in more than one cmd |
426 | a8083063 | Iustin Pop | node_opt = make_option("-n", "--node", dest="node", help="Target node", |
427 | a8083063 | Iustin Pop | metavar="<node>") |
428 | a8083063 | Iustin Pop | |
429 | d0834de3 | Michael Hanselmann | os_opt = cli_option("-o", "--os-type", dest="os", help="What OS to run", |
430 | 739ecd56 | Michael Hanselmann | metavar="<os>") |
431 | d0834de3 | Michael Hanselmann | |
432 | a8083063 | Iustin Pop | # this is defined separately due to readability only |
433 | a8083063 | Iustin Pop | add_opts = [ |
434 | a8083063 | Iustin Pop | DEBUG_OPT, |
435 | a8083063 | Iustin Pop | node_opt, |
436 | b9ac33e9 | Iustin Pop | cli_option("-s", "--os-size", dest="size", help="Disk size, in MiB unless" |
437 | b9ac33e9 | Iustin Pop | " a suffix is used", |
438 | a8083063 | Iustin Pop | default=20 * 1024, type="unit", metavar="<size>"), |
439 | b9ac33e9 | Iustin Pop | cli_option("--swap-size", dest="swap", help="Swap size, in MiB unless a" |
440 | b9ac33e9 | Iustin Pop | " suffix is used", |
441 | a8083063 | Iustin Pop | default=4 * 1024, type="unit", metavar="<size>"), |
442 | d0834de3 | Michael Hanselmann | os_opt, |
443 | b9ac33e9 | Iustin Pop | cli_option("-m", "--memory", dest="mem", help="Memory size (in MiB)", |
444 | a8083063 | Iustin Pop | default=128, type="unit", metavar="<mem>"), |
445 | a8083063 | Iustin Pop | make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs", |
446 | a8083063 | Iustin Pop | default=1, type="int", metavar="<PROC>"), |
447 | a8083063 | Iustin Pop | make_option("-t", "--disk-template", dest="disk_template", |
448 | a8083063 | Iustin Pop | help="Custom disk setup (diskless, plain, local_raid1 or" |
449 | a8083063 | Iustin Pop | " remote_raid1)", default=None, metavar="TEMPL"), |
450 | a8083063 | Iustin Pop | make_option("-i", "--ip", dest="ip", |
451 | a8083063 | Iustin Pop | help="IP address ('none' [default], 'auto', or specify address)", |
452 | a8083063 | Iustin Pop | default='none', type="string", metavar="<ADDRESS>"), |
453 | a8083063 | Iustin Pop | make_option("--no-wait-for-sync", dest="wait_for_sync", default=True, |
454 | a8083063 | Iustin Pop | action="store_false", help="Don't wait for sync (DANGEROUS!)"), |
455 | a8083063 | Iustin Pop | make_option("--secondary-node", dest="snode", |
456 | a8083063 | Iustin Pop | help="Secondary node for remote_raid1 disk layout", |
457 | a8083063 | Iustin Pop | metavar="<node>"), |
458 | a8083063 | Iustin Pop | make_option("-b", "--bridge", dest="bridge", |
459 | a8083063 | Iustin Pop | help="Bridge to connect this instance to", |
460 | a8083063 | Iustin Pop | default=None, metavar="<bridge>") |
461 | a8083063 | Iustin Pop | ] |
462 | a8083063 | Iustin Pop | |
463 | a8083063 | Iustin Pop | commands = { |
464 | a8083063 | Iustin Pop | 'add': (AddInstance, ARGS_ONE, add_opts, |
465 | a8083063 | Iustin Pop | "[opts...] <name>", |
466 | a8083063 | Iustin Pop | "Creates and adds a new instance to the cluster"), |
467 | a8083063 | Iustin Pop | 'add-mirror': (AddMDDRBDComponent, ARGS_ONE, |
468 | a8083063 | Iustin Pop | [DEBUG_OPT, node_opt, |
469 | a8083063 | Iustin Pop | make_option("-b", "--disk", dest="disk", metavar="sdX", |
470 | a8083063 | Iustin Pop | help=("The name of the instance disk for which to" |
471 | a8083063 | Iustin Pop | " add the mirror"))], |
472 | a8083063 | Iustin Pop | "-n node -b disk <instance>", |
473 | a8083063 | Iustin Pop | "Creates a new mirror for the instance"), |
474 | a8083063 | Iustin Pop | 'console': (ConnectToInstanceConsole, ARGS_ONE, [DEBUG_OPT], |
475 | a8083063 | Iustin Pop | "<instance>", |
476 | a8083063 | Iustin Pop | "Opens a console on the specified instance"), |
477 | a8083063 | Iustin Pop | 'failover': (FailoverInstance, ARGS_ONE, |
478 | fe7b0351 | Michael Hanselmann | [DEBUG_OPT, FORCE_OPT, |
479 | a8083063 | Iustin Pop | make_option("--ignore-consistency", dest="ignore_consistency", |
480 | a8083063 | Iustin Pop | action="store_true", default=False, |
481 | a8083063 | Iustin Pop | help="Ignore the consistency of the disks on" |
482 | a8083063 | Iustin Pop | " the secondary"), |
483 | a8083063 | Iustin Pop | ], |
484 | a8083063 | Iustin Pop | "[-f] <instance>", |
485 | a8083063 | Iustin Pop | "Stops the instance and starts it on the backup node, using" |
486 | a8083063 | Iustin Pop | " the remote mirror (only for instances of type remote_raid1)"), |
487 | a8083063 | Iustin Pop | 'info': (ShowInstanceConfig, ARGS_ANY, [DEBUG_OPT], "[<instance>...]", |
488 | a8083063 | Iustin Pop | "Show information on the specified instance"), |
489 | a8083063 | Iustin Pop | 'list': (ListInstances, ARGS_NONE, |
490 | dcb93971 | Michael Hanselmann | [DEBUG_OPT, NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT], |
491 | a8083063 | Iustin Pop | "", "Lists the instances and their status"), |
492 | d0834de3 | Michael Hanselmann | 'reinstall': (ReinstallInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT, os_opt], |
493 | fe7b0351 | Michael Hanselmann | "[-f] <instance>", "Reinstall the instance"), |
494 | fe7b0351 | Michael Hanselmann | 'remove': (RemoveInstance, ARGS_ONE, [DEBUG_OPT, FORCE_OPT], |
495 | a8083063 | Iustin Pop | "[-f] <instance>", "Shuts down the instance and removes it"), |
496 | a8083063 | Iustin Pop | 'remove-mirror': (RemoveMDDRBDComponent, ARGS_ONE, |
497 | a8083063 | Iustin Pop | [DEBUG_OPT, node_opt, |
498 | a8083063 | Iustin Pop | make_option("-b", "--disk", dest="disk", metavar="sdX", |
499 | a8083063 | Iustin Pop | help=("The name of the instance disk" |
500 | a8083063 | Iustin Pop | " for which to add the mirror")), |
501 | a8083063 | Iustin Pop | make_option("-p", "--port", dest="port", metavar="PORT", |
502 | a8083063 | Iustin Pop | help=("The port of the drbd device" |
503 | a8083063 | Iustin Pop | " which to remove from the mirror"), |
504 | a8083063 | Iustin Pop | type="int"), |
505 | a8083063 | Iustin Pop | ], |
506 | a8083063 | Iustin Pop | "-b disk -p port <instance>", |
507 | a8083063 | Iustin Pop | "Removes a mirror from the instance"), |
508 | a8083063 | Iustin Pop | 'replace-disks': (ReplaceDisks, ARGS_ONE, |
509 | a8083063 | Iustin Pop | [DEBUG_OPT, |
510 | a8083063 | Iustin Pop | make_option("-n", "--new-secondary", dest="new_secondary", |
511 | a8083063 | Iustin Pop | metavar="NODE", |
512 | a8083063 | Iustin Pop | help=("New secondary node (if you want to" |
513 | a8083063 | Iustin Pop | " change the secondary)"))], |
514 | a8083063 | Iustin Pop | "[-n NODE] <instance>", |
515 | a8083063 | Iustin Pop | "Replaces all disks for the instance"), |
516 | a8083063 | Iustin Pop | 'modify': (SetInstanceParms, ARGS_ONE, |
517 | fe7b0351 | Michael Hanselmann | [DEBUG_OPT, FORCE_OPT, |
518 | a8083063 | Iustin Pop | cli_option("-m", "--memory", dest="mem", |
519 | a8083063 | Iustin Pop | help="Memory size", |
520 | a8083063 | Iustin Pop | default=None, type="unit", metavar="<mem>"), |
521 | a8083063 | Iustin Pop | make_option("-p", "--cpu", dest="vcpus", |
522 | a8083063 | Iustin Pop | help="Number of virtual CPUs", |
523 | a8083063 | Iustin Pop | default=None, type="int", metavar="<PROC>"), |
524 | a8083063 | Iustin Pop | make_option("-i", "--ip", dest="ip", |
525 | a8083063 | Iustin Pop | help="IP address ('none' or numeric IP)", |
526 | a8083063 | Iustin Pop | default=None, type="string", metavar="<ADDRESS>"), |
527 | a8083063 | Iustin Pop | make_option("-b", "--bridge", dest="bridge", |
528 | a8083063 | Iustin Pop | help="Bridge to connect this instance to", |
529 | a8083063 | Iustin Pop | default=None, type="string", metavar="<bridge>") |
530 | a8083063 | Iustin Pop | ], |
531 | a8083063 | Iustin Pop | "<instance>", "Alters the parameters of an instance"), |
532 | a8083063 | Iustin Pop | 'shutdown': (ShutdownInstance, ARGS_ONE, [DEBUG_OPT], |
533 | a8083063 | Iustin Pop | "<instance>", "Stops an instance"), |
534 | a8083063 | Iustin Pop | 'startup': (StartupInstance, ARGS_ONE, |
535 | fe7b0351 | Michael Hanselmann | [DEBUG_OPT, FORCE_OPT, |
536 | a8083063 | Iustin Pop | make_option("-e", "--extra", dest="extra_args", |
537 | a8083063 | Iustin Pop | help="Extra arguments for the instance's kernel", |
538 | a8083063 | Iustin Pop | default=None, type="string", metavar="<PARAMS>"), |
539 | a8083063 | Iustin Pop | ], |
540 | a8083063 | Iustin Pop | "<instance>", "Starts an instance"), |
541 | a8083063 | Iustin Pop | 'activate-disks': (ActivateDisks, ARGS_ONE, [DEBUG_OPT], |
542 | a8083063 | Iustin Pop | "<instance>", |
543 | a8083063 | Iustin Pop | "Activate an instance's disks"), |
544 | a8083063 | Iustin Pop | 'deactivate-disks': (DeactivateDisks, ARGS_ONE, [DEBUG_OPT], |
545 | a8083063 | Iustin Pop | "<instance>", |
546 | a8083063 | Iustin Pop | "Deactivate an instance's disks"), |
547 | a8083063 | Iustin Pop | } |
548 | a8083063 | Iustin Pop | |
549 | a8083063 | Iustin Pop | if __name__ == '__main__': |
550 | 3ecf6786 | Iustin Pop | sys.exit(GenericMain(commands)) |