Check HVM device type on instance modify as well.
[ganeti-local] / lib / opcodes.py
1 #
2 #
3
4 # Copyright (C) 2006, 2007 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """OpCodes module
23
24 This module implements the data structures which define the cluster
25 operations - the so-called opcodes.
26
27
28 This module implements the logic for doing operations in the cluster. There
29 are two kinds of classes defined:
30   - opcodes, which are small classes only holding data for the task at hand
31   - logical units, which know how to deal with their specific opcode only
32
33 """
34
35 # this are practically structures, so disable the message about too
36 # few public methods:
37 # pylint: disable-msg=R0903
38
39 class OpCode(object):
40   """Abstract OpCode"""
41   OP_ID = "OP_ABSTRACT"
42   __slots__ = []
43
44   def __init__(self, **kwargs):
45     for key in kwargs:
46       if key not in self.__slots__:
47         raise TypeError("OpCode %s doesn't support the parameter '%s'" %
48                         (self.__class__.__name__, key))
49       setattr(self, key, kwargs[key])
50
51
52 class OpInitCluster(OpCode):
53   """Initialise the cluster."""
54   OP_ID = "OP_CLUSTER_INIT"
55   __slots__ = ["cluster_name", "secondary_ip", "hypervisor_type",
56                "vg_name", "mac_prefix", "def_bridge", "master_netdev"]
57
58
59 class OpDestroyCluster(OpCode):
60   """Destroy the cluster."""
61   OP_ID = "OP_CLUSTER_DESTROY"
62   __slots__ = []
63
64
65 class OpQueryClusterInfo(OpCode):
66   """Query cluster information."""
67   OP_ID = "OP_CLUSTER_QUERY"
68   __slots__ = []
69
70
71 class OpClusterCopyFile(OpCode):
72   """Copy a file to multiple nodes."""
73   OP_ID = "OP_CLUSTER_COPYFILE"
74   __slots__ = ["nodes", "filename"]
75
76
77 class OpRunClusterCommand(OpCode):
78   """Run a command on multiple nodes."""
79   OP_ID = "OP_CLUSTER_RUNCOMMAND"
80   __slots__ = ["nodes", "command"]
81
82
83 class OpVerifyCluster(OpCode):
84   """Verify the cluster state."""
85   OP_ID = "OP_CLUSTER_VERIFY"
86   __slots__ = ["skip_checks"]
87
88
89 class OpVerifyDisks(OpCode):
90   """Verify the cluster disks.
91
92   Parameters: none
93
94   Result: two lists:
95     - list of node names with bad data returned (unreachable, etc.)
96     - dist of node names with broken volume groups (values: error msg)
97     - list of instances with degraded disks (that should be activated)
98     - dict of instances with missing logical volumes (values: (node, vol)
99       pairs with details about the missing volumes)
100
101   In normal operation, all lists should be empty. A non-empty instance
102   list (3rd element of the result) is still ok (errors were fixed) but
103   non-empty node list means some node is down, and probably there are
104   unfixable drbd errors.
105
106   Note that only instances that are drbd-based are taken into
107   consideration. This might need to be revisited in the future.
108
109   """
110   OP_ID = "OP_CLUSTER_VERIFY_DISKS"
111   __slots__ = []
112
113
114 class OpMasterFailover(OpCode):
115   """Do a master failover."""
116   OP_ID = "OP_CLUSTER_MASTERFAILOVER"
117   __slots__ = []
118
119
120 class OpDumpClusterConfig(OpCode):
121   """Dump the cluster configuration."""
122   OP_ID = "OP_CLUSTER_DUMPCONFIG"
123   __slots__ = []
124
125
126 class OpRenameCluster(OpCode):
127   """Rename the cluster."""
128   OP_ID = "OP_CLUSTER_RENAME"
129   __slots__ = ["name"]
130
131
132 # node opcodes
133
134 class OpRemoveNode(OpCode):
135   """Remove a node."""
136   OP_ID = "OP_NODE_REMOVE"
137   __slots__ = ["node_name"]
138
139
140 class OpAddNode(OpCode):
141   """Add a node."""
142   OP_ID = "OP_NODE_ADD"
143   __slots__ = ["node_name", "primary_ip", "secondary_ip", "readd"]
144
145
146 class OpQueryNodes(OpCode):
147   """Compute the list of nodes."""
148   OP_ID = "OP_NODE_QUERY"
149   __slots__ = ["output_fields", "names"]
150
151
152 class OpQueryNodeVolumes(OpCode):
153   """Get list of volumes on node."""
154   OP_ID = "OP_NODE_QUERYVOLS"
155   __slots__ = ["nodes", "output_fields"]
156
157
158 # instance opcodes
159
160 class OpCreateInstance(OpCode):
161   """Create an instance."""
162   OP_ID = "OP_INSTANCE_CREATE"
163   __slots__ = [
164     "instance_name", "mem_size", "disk_size", "os_type", "pnode",
165     "disk_template", "snode", "swap_size", "mode",
166     "vcpus", "ip", "bridge", "src_node", "src_path", "start",
167     "wait_for_sync", "ip_check", "mac",
168     "kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
169     "hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
170     "iallocator", "hvm_nic_type", "hvm_disk_type",
171     ]
172
173
174 class OpReinstallInstance(OpCode):
175   """Reinstall an instance's OS."""
176   OP_ID = "OP_INSTANCE_REINSTALL"
177   __slots__ = ["instance_name", "os_type"]
178
179
180 class OpRemoveInstance(OpCode):
181   """Remove an instance."""
182   OP_ID = "OP_INSTANCE_REMOVE"
183   __slots__ = ["instance_name", "ignore_failures"]
184
185
186 class OpRenameInstance(OpCode):
187   """Rename an instance."""
188   OP_ID = "OP_INSTANCE_RENAME"
189   __slots__ = ["instance_name", "ignore_ip", "new_name"]
190
191
192 class OpStartupInstance(OpCode):
193   """Startup an instance."""
194   OP_ID = "OP_INSTANCE_STARTUP"
195   __slots__ = ["instance_name", "force", "extra_args"]
196
197
198 class OpShutdownInstance(OpCode):
199   """Shutdown an instance."""
200   OP_ID = "OP_INSTANCE_SHUTDOWN"
201   __slots__ = ["instance_name"]
202
203
204 class OpRebootInstance(OpCode):
205   """Reboot an instance."""
206   OP_ID = "OP_INSTANCE_REBOOT"
207   __slots__ = ["instance_name", "reboot_type", "extra_args",
208                "ignore_secondaries" ]
209
210
211 class OpAddMDDRBDComponent(OpCode):
212   """Add a MD-DRBD component."""
213   OP_ID = "OP_INSTANCE_ADD_MDDRBD"
214   __slots__ = ["instance_name", "remote_node", "disk_name"]
215
216
217 class OpRemoveMDDRBDComponent(OpCode):
218   """Remove a MD-DRBD component."""
219   OP_ID = "OP_INSTANCE_REMOVE_MDDRBD"
220   __slots__ = ["instance_name", "disk_name", "disk_id"]
221
222
223 class OpReplaceDisks(OpCode):
224   """Replace the disks of an instance."""
225   OP_ID = "OP_INSTANCE_REPLACE_DISKS"
226   __slots__ = ["instance_name", "remote_node", "mode", "disks", "iallocator"]
227
228
229 class OpFailoverInstance(OpCode):
230   """Failover an instance."""
231   OP_ID = "OP_INSTANCE_FAILOVER"
232   __slots__ = ["instance_name", "ignore_consistency"]
233
234
235 class OpMigrateInstance(OpCode):
236   """Migrate an instance.
237
238   This migrates (without shutting down an instance) to its secondary
239   node.
240
241   Parameters:
242     - instance_name: the name of the instance
243
244   """
245   OP_ID = "OP_INSTANCE_MIGRATE"
246   __slots__ = ["instance_name", "live", "cleanup"]
247
248
249 class OpConnectConsole(OpCode):
250   """Connect to an instance's console."""
251   OP_ID = "OP_INSTANCE_CONSOLE"
252   __slots__ = ["instance_name"]
253
254
255 class OpActivateInstanceDisks(OpCode):
256   """Activate an instance's disks."""
257   OP_ID = "OP_INSTANCE_ACTIVATE_DISKS"
258   __slots__ = ["instance_name"]
259
260
261 class OpDeactivateInstanceDisks(OpCode):
262   """Deactivate an instance's disks."""
263   OP_ID = "OP_INSTANCE_DEACTIVATE_DISKS"
264   __slots__ = ["instance_name"]
265
266
267 class OpQueryInstances(OpCode):
268   """Compute the list of instances."""
269   OP_ID = "OP_INSTANCE_QUERY"
270   __slots__ = ["output_fields", "names"]
271
272
273 class OpQueryInstanceData(OpCode):
274   """Compute the run-time status of instances."""
275   OP_ID = "OP_INSTANCE_QUERY_DATA"
276   __slots__ = ["instances"]
277
278
279 class OpSetInstanceParms(OpCode):
280   """Change the parameters of an instance."""
281   OP_ID = "OP_INSTANCE_SET_PARMS"
282   __slots__ = [
283     "instance_name", "mem", "vcpus", "ip", "bridge", "mac",
284     "kernel_path", "initrd_path", "hvm_boot_order", "hvm_acpi",
285     "hvm_pae", "hvm_cdrom_image_path", "vnc_bind_address",
286     "hvm_nic_type", "hvm_disk_type"
287     ]
288
289
290 class OpGrowDisk(OpCode):
291   """Grow a disk of an instance."""
292   OP_ID = "OP_INSTANCE_GROW_DISK"
293   __slots__ = ["instance_name", "disk", "amount", "wait_for_sync"]
294
295
296 # OS opcodes
297 class OpDiagnoseOS(OpCode):
298   """Compute the list of guest operating systems."""
299   OP_ID = "OP_OS_DIAGNOSE"
300   __slots__ = ["output_fields", "names"]
301
302 # Exports opcodes
303 class OpQueryExports(OpCode):
304   """Compute the list of exported images."""
305   OP_ID = "OP_BACKUP_QUERY"
306   __slots__ = ["nodes"]
307
308 class OpExportInstance(OpCode):
309   """Export an instance."""
310   OP_ID = "OP_BACKUP_EXPORT"
311   __slots__ = ["instance_name", "target_node", "shutdown"]
312
313 class OpRemoveExport(OpCode):
314   """Remove an instance's export."""
315   OP_ID = "OP_BACKUP_REMOVE"
316   __slots__ = ["instance_name"]
317
318 # Tags opcodes
319 class OpGetTags(OpCode):
320   """Returns the tags of the given object."""
321   OP_ID = "OP_TAGS_GET"
322   __slots__ = ["kind", "name"]
323
324
325 class OpSearchTags(OpCode):
326   """Searches the tags in the cluster for a given pattern."""
327   OP_ID = "OP_TAGS_SEARCH"
328   __slots__ = ["pattern"]
329
330
331 class OpAddTags(OpCode):
332   """Add a list of tags on a given object."""
333   OP_ID = "OP_TAGS_SET"
334   __slots__ = ["kind", "name", "tags"]
335
336
337 class OpDelTags(OpCode):
338   """Remove a list of tags from a given object."""
339   OP_ID = "OP_TAGS_DEL"
340   __slots__ = ["kind", "name", "tags"]
341
342
343 # Test opcodes
344 class OpTestDelay(OpCode):
345   """Sleeps for a configured amount of time.
346
347   This is used just for debugging and testing.
348
349   Parameters:
350     - duration: the time to sleep
351     - on_master: if true, sleep on the master
352     - on_nodes: list of nodes in which to sleep
353
354   If the on_master parameter is true, it will execute a sleep on the
355   master (before any node sleep).
356
357   If the on_nodes list is not empty, it will sleep on those nodes
358   (after the sleep on the master, if that is enabled).
359
360   As an additional feature, the case of duration < 0 will be reported
361   as an execution error, so this opcode can be used as a failure
362   generator. The case of duration == 0 will not be treated specially.
363
364   """
365   OP_ID = "OP_TEST_DELAY"
366   __slots__ = ["duration", "on_master", "on_nodes"]
367
368
369 class OpTestAllocator(OpCode):
370   """Allocator framework testing.
371
372   This opcode has two modes:
373     - gather and return allocator input for a given mode (allocate new
374       or replace secondary) and a given instance definition (direction
375       'in')
376     - run a selected allocator for a given operation (as above) and
377       return the allocator output (direction 'out')
378
379   """
380   OP_ID = "OP_TEST_ALLOCATOR"
381   __slots__ = [
382     "direction", "mode", "allocator", "name",
383     "mem_size", "disks", "disk_template",
384     "os", "tags", "nics", "vcpus",
385     ]