1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 """Logical units dealing with instance operations (start/stop/...).
32
33 Those operations have in common that they affect the operating system in a
34 running instance directly.
35
36 """
37
38 import logging
39
40 from ganeti import constants
41 from ganeti import errors
42 from ganeti import hypervisor
43 from ganeti import locking
44 from ganeti import objects
45 from ganeti import utils
46 from ganeti.cmdlib.base import LogicalUnit, NoHooksLU
47 from ganeti.cmdlib.common import INSTANCE_ONLINE, INSTANCE_DOWN, \
48 CheckHVParams, CheckInstanceState, CheckNodeOnline, GetUpdatedParams, \
49 CheckOSParams, ShareAll
50 from ganeti.cmdlib.instance_storage import StartInstanceDisks, \
51 ShutdownInstanceDisks
52 from ganeti.cmdlib.instance_utils import BuildInstanceHookEnvByObject, \
53 CheckInstanceBridgesExist, CheckNodeFreeMemory, CheckNodeHasOS
54
55
57 """Starts an instance.
58
59 """
60 HPATH = "instance-start"
61 HTYPE = constants.HTYPE_INSTANCE
62 REQ_BGL = False
63
70
74
78
80 """Build hooks env.
81
82 This runs on master, primary and secondary nodes of the instance.
83
84 """
85 env = {
86 "FORCE": self.op.force,
87 }
88
89 env.update(BuildInstanceHookEnvByObject(self, self.instance))
90
91 return env
92
99
101 """Check prerequisites.
102
103 This checks that the instance is in the cluster.
104
105 """
106 self.instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
107 assert self.instance is not None, \
108 "Cannot retrieve locked instance %s" % self.op.instance_name
109
110 cluster = self.cfg.GetClusterInfo()
111
112 if self.op.hvparams:
113
114 utils.ForceDictType(self.op.hvparams, constants.HVS_PARAMETER_TYPES)
115 filled_hvp = cluster.FillHV(self.instance)
116 filled_hvp.update(self.op.hvparams)
117 hv_type = hypervisor.GetHypervisorClass(self.instance.hypervisor)
118 hv_type.CheckParameterSyntax(filled_hvp)
119 CheckHVParams(self, self.instance.all_nodes, self.instance.hypervisor,
120 filled_hvp)
121
122 CheckInstanceState(self, self.instance, INSTANCE_ONLINE)
123
124 self.primary_offline = \
125 self.cfg.GetNodeInfo(self.instance.primary_node).offline
126
127 if self.primary_offline and self.op.ignore_offline_nodes:
128 self.LogWarning("Ignoring offline primary node")
129
130 if self.op.hvparams or self.op.beparams:
131 self.LogWarning("Overridden parameters are ignored")
132 else:
133 CheckNodeOnline(self, self.instance.primary_node)
134
135 bep = self.cfg.GetClusterInfo().FillBE(self.instance)
136 bep.update(self.op.beparams)
137
138
139 CheckInstanceBridgesExist(self, self.instance)
140
141 remote_info = self.rpc.call_instance_info(
142 self.instance.primary_node, self.instance.name,
143 self.instance.hypervisor, cluster.hvparams[self.instance.hypervisor])
144 remote_info.Raise("Error checking node %s" %
145 self.cfg.GetNodeName(self.instance.primary_node),
146 prereq=True, ecode=errors.ECODE_ENVIRON)
147 if not remote_info.payload:
148 CheckNodeFreeMemory(
149 self, self.instance.primary_node,
150 "starting instance %s" % self.instance.name,
151 bep[constants.BE_MINMEM], self.instance.hypervisor,
152 self.cfg.GetClusterInfo().hvparams[self.instance.hypervisor])
153
154 - def Exec(self, feedback_fn):
176
177
179 """Shutdown an instance.
180
181 """
182 HPATH = "instance-stop"
183 HTYPE = constants.HTYPE_INSTANCE
184 REQ_BGL = False
185
188
190 """Build hooks env.
191
192 This runs on master, primary and secondary nodes of the instance.
193
194 """
195 env = BuildInstanceHookEnvByObject(self, self.instance)
196 env["TIMEOUT"] = self.op.timeout
197 return env
198
205
207 """Check prerequisites.
208
209 This checks that the instance is in the cluster.
210
211 """
212 self.instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
213 assert self.instance is not None, \
214 "Cannot retrieve locked instance %s" % self.op.instance_name
215
216 if not self.op.force:
217 CheckInstanceState(self, self.instance, INSTANCE_ONLINE)
218 else:
219 self.LogWarning("Ignoring offline instance check")
220
221 self.primary_offline = \
222 self.cfg.GetNodeInfo(self.instance.primary_node).offline
223
224 if self.primary_offline and self.op.ignore_offline_nodes:
225 self.LogWarning("Ignoring offline primary node")
226 else:
227 CheckNodeOnline(self, self.instance.primary_node)
228
229 - def Exec(self, feedback_fn):
251
252
254 """Reinstall an instance.
255
256 """
257 HPATH = "instance-reinstall"
258 HTYPE = constants.HTYPE_INSTANCE
259 REQ_BGL = False
260
263
271
278
280 """Check prerequisites.
281
282 This checks that the instance is in the cluster and is not running.
283
284 """
285 instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
286 assert instance is not None, \
287 "Cannot retrieve locked instance %s" % self.op.instance_name
288 CheckNodeOnline(self, instance.primary_node, "Instance primary node"
289 " offline, cannot reinstall")
290
291 if instance.disk_template == constants.DT_DISKLESS:
292 raise errors.OpPrereqError("Instance '%s' has no disks" %
293 self.op.instance_name,
294 errors.ECODE_INVAL)
295 CheckInstanceState(self, instance, INSTANCE_DOWN, msg="cannot reinstall")
296
297 if self.op.os_type is not None:
298
299 CheckNodeHasOS(self, instance.primary_node, self.op.os_type,
300 self.op.force_variant)
301 instance_os = self.op.os_type
302 else:
303 instance_os = instance.os
304
305 node_uuids = list(instance.all_nodes)
306
307 if self.op.osparams:
308 i_osdict = GetUpdatedParams(instance.osparams, self.op.osparams)
309 CheckOSParams(self, True, node_uuids, instance_os, i_osdict)
310 self.os_inst = i_osdict
311 else:
312 self.os_inst = None
313
314 self.instance = instance
315
316 - def Exec(self, feedback_fn):
338
339
341 """Reboot an instance.
342
343 """
344 HPATH = "instance-reboot"
345 HTYPE = constants.HTYPE_INSTANCE
346 REQ_BGL = False
347
350
352 """Build hooks env.
353
354 This runs on master, primary and secondary nodes of the instance.
355
356 """
357 env = {
358 "IGNORE_SECONDARIES": self.op.ignore_secondaries,
359 "REBOOT_TYPE": self.op.reboot_type,
360 "SHUTDOWN_TIMEOUT": self.op.shutdown_timeout,
361 }
362
363 env.update(BuildInstanceHookEnvByObject(self, self.instance))
364
365 return env
366
373
388
389 - def Exec(self, feedback_fn):
390 """Reboot the instance.
391
392 """
393 cluster = self.cfg.GetClusterInfo()
394 remote_info = self.rpc.call_instance_info(
395 self.instance.primary_node, self.instance.name,
396 self.instance.hypervisor, cluster.hvparams[self.instance.hypervisor])
397 remote_info.Raise("Error checking node %s" %
398 self.cfg.GetNodeName(self.instance.primary_node))
399 instance_running = bool(remote_info.payload)
400
401 current_node_uuid = self.instance.primary_node
402
403 if instance_running and \
404 self.op.reboot_type in [constants.INSTANCE_REBOOT_SOFT,
405 constants.INSTANCE_REBOOT_HARD]:
406 result = self.rpc.call_instance_reboot(current_node_uuid, self.instance,
407 self.op.reboot_type,
408 self.op.shutdown_timeout,
409 self.op.reason)
410 result.Raise("Could not reboot instance")
411 else:
412 if instance_running:
413 result = self.rpc.call_instance_shutdown(current_node_uuid,
414 self.instance,
415 self.op.shutdown_timeout,
416 self.op.reason)
417 result.Raise("Could not shutdown instance for full reboot")
418 ShutdownInstanceDisks(self, self.instance)
419 else:
420 self.LogInfo("Instance %s was already stopped, starting now",
421 self.instance.name)
422 StartInstanceDisks(self, self.instance, self.op.ignore_secondaries)
423 result = self.rpc.call_instance_start(current_node_uuid,
424 (self.instance, None, None), False,
425 self.op.reason)
426 msg = result.fail_msg
427 if msg:
428 ShutdownInstanceDisks(self, self.instance)
429 raise errors.OpExecError("Could not start instance for"
430 " full reboot: %s" % msg)
431
432 self.cfg.MarkInstanceUp(self.instance.uuid)
433
434
455
456
458 """Connect to an instance's console.
459
460 This is somewhat special in that it returns the command line that
461 you need to run on the master node in order to connect to the
462 console.
463
464 """
465 REQ_BGL = False
466
470
472 """Check prerequisites.
473
474 This checks that the instance is in the cluster.
475
476 """
477 self.instance = self.cfg.GetInstanceInfo(self.op.instance_uuid)
478 assert self.instance is not None, \
479 "Cannot retrieve locked instance %s" % self.op.instance_name
480 CheckNodeOnline(self, self.instance.primary_node)
481
482 - def Exec(self, feedback_fn):
510