Newer
Older
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#
# Copyright (C) 2006, 2007 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""OpCodes module
This module implements the data structures which define the cluster
operations - the so-called opcodes.
This module implements the logic for doing operations in the cluster. There
are two kinds of classes defined:
- opcodes, which are small classes only holding data for the task at hand
- logical units, which know how to deal with their specific opcode only
"""
# this are practically structures, so disable the message about too
# few public methods:
# pylint: disable-msg=R0903
class OpCode(object):
"""Abstract OpCode"""
OP_ID = "OP_ABSTRACT"
__slots__ = []
def __init__(self, **kwargs):
for key in kwargs:
if key not in self.__slots__:
raise TypeError("OpCode %s doesn't support the parameter '%s'" %
(self.__class__.__name__, key))
setattr(self, key, kwargs[key])
class OpInitCluster(OpCode):
"""Initialise the cluster."""
OP_ID = "OP_CLUSTER_INIT"
__slots__ = ["cluster_name", "secondary_ip", "hypervisor_type",
"vg_name", "mac_prefix", "def_bridge", "master_netdev",
"file_storage_dir"]
class OpDestroyCluster(OpCode):
"""Destroy the cluster."""
OP_ID = "OP_CLUSTER_DESTROY"
__slots__ = []
class OpQueryClusterInfo(OpCode):
OP_ID = "OP_CLUSTER_QUERY"
__slots__ = []
class OpClusterCopyFile(OpCode):
OP_ID = "OP_CLUSTER_COPYFILE"
__slots__ = ["nodes", "filename"]
class OpRunClusterCommand(OpCode):
OP_ID = "OP_CLUSTER_RUNCOMMAND"
__slots__ = ["nodes", "command"]
class OpVerifyCluster(OpCode):
class OpVerifyDisks(OpCode):
"""Verify the cluster disks.
Parameters: none
Result: two lists:
- list of node names with bad data returned (unreachable, etc.)
- dist of node names with broken volume groups (values: error msg)
- list of instances with degraded disks (that should be activated)
- dict of instances with missing logical volumes (values: (node, vol)
pairs with details about the missing volumes)
In normal operation, all lists should be empty. A non-empty instance
list (3rd element of the result) is still ok (errors were fixed) but
non-empty node list means some node is down, and probably there are
unfixable drbd errors.
Note that only instances that are drbd-based are taken into
consideration. This might need to be revisited in the future.
"""
OP_ID = "OP_CLUSTER_VERIFY_DISKS"
__slots__ = []
OP_ID = "OP_CLUSTER_MASTERFAILOVER"
__slots__ = []
class OpDumpClusterConfig(OpCode):
class OpRenameCluster(OpCode):
"""Rename the cluster."""
OP_ID = "OP_CLUSTER_RENAME"
__slots__ = ["name"]
# node opcodes
class OpRemoveNode(OpCode):
"""Remove a node."""
OP_ID = "OP_NODE_REMOVE"
__slots__ = ["node_name"]
class OpAddNode(OpCode):
"""Add a node."""
OP_ID = "OP_NODE_ADD"
__slots__ = ["node_name", "primary_ip", "secondary_ip"]
class OpQueryNodes(OpCode):
"""Compute the list of nodes."""
OP_ID = "OP_NODE_QUERY"
__slots__ = ["output_fields", "names"]
class OpQueryNodeVolumes(OpCode):
"""Get list of volumes on node."""
OP_ID = "OP_NODE_QUERYVOLS"
__slots__ = ["nodes", "output_fields"]
__slots__ = [
"instance_name", "mem_size", "disk_size", "os_type", "pnode",
"disk_template", "snode", "swap_size", "mode",
"vcpus", "ip", "bridge", "src_node", "src_path", "start",
"wait_for_sync", "ip_check", "mac",
"kernel_path", "initrd_path", "hvm_boot_order",
__slots__ = ["instance_name", "os_type"]
class OpRemoveInstance(OpCode):
"""Remove an instance."""
OP_ID = "OP_INSTANCE_REMOVE"
__slots__ = ["instance_name", "ignore_failures"]
class OpRenameInstance(OpCode):
"""Rename an instance."""
OP_ID = "OP_INSTANCE_RENAME"
__slots__ = ["instance_name", "ignore_ip", "new_name"]
OP_ID = "OP_INSTANCE_STARTUP"
__slots__ = ["instance_name", "force", "extra_args"]
class OpShutdownInstance(OpCode):
OP_ID = "OP_INSTANCE_SHUTDOWN"
__slots__ = ["instance_name"]
class OpRebootInstance(OpCode):
"""Reboot an instance."""
__slots__ = ["instance_name", "reboot_type", "extra_args",
"ignore_secondaries" ]
class OpAddMDDRBDComponent(OpCode):
"""Add a MD-DRBD component."""
OP_ID = "OP_INSTANCE_ADD_MDDRBD"
__slots__ = ["instance_name", "remote_node", "disk_name"]
class OpRemoveMDDRBDComponent(OpCode):
"""Remove a MD-DRBD component."""
OP_ID = "OP_INSTANCE_REMOVE_MDDRBD"
__slots__ = ["instance_name", "disk_name", "disk_id"]
class OpReplaceDisks(OpCode):
__slots__ = ["instance_name", "remote_node", "mode", "disks"]
class OpFailoverInstance(OpCode):
"""Failover an instance."""
OP_ID = "OP_INSTANCE_FAILOVER"
__slots__ = ["instance_name", "ignore_consistency"]
class OpConnectConsole(OpCode):
OP_ID = "OP_INSTANCE_CONSOLE"
__slots__ = ["instance_name"]
class OpActivateInstanceDisks(OpCode):
OP_ID = "OP_INSTANCE_ACTIVATE_DISKS"
__slots__ = ["instance_name"]
class OpDeactivateInstanceDisks(OpCode):
OP_ID = "OP_INSTANCE_DEACTIVATE_DISKS"
__slots__ = ["instance_name"]
class OpQueryInstances(OpCode):
"""Compute the list of instances."""
OP_ID = "OP_INSTANCE_QUERY"
__slots__ = ["output_fields", "names"]
class OpQueryInstanceData(OpCode):
"""Compute the run-time status of instances."""
OP_ID = "OP_INSTANCE_QUERY_DATA"
__slots__ = ["instances"]
class OpSetInstanceParms(OpCode):
"""Change the parameters of an instance."""
OP_ID = "OP_INSTANCE_SET_PARMS"
__slots__ = [
"instance_name", "mem", "vcpus", "ip", "bridge", "mac",
"kernel_path", "initrd_path", "hvm_boot_order",
# OS opcodes
class OpDiagnoseOS(OpCode):
"""Compute the list of guest operating systems."""
OP_ID = "OP_OS_DIAGNOSE"
__slots__ = []
# Exports opcodes
class OpQueryExports(OpCode):
"""Compute the list of exported images."""
OP_ID = "OP_BACKUP_QUERY"
__slots__ = ["nodes"]
class OpExportInstance(OpCode):
"""Export an instance."""
OP_ID = "OP_BACKUP_EXPORT"
__slots__ = ["instance_name", "target_node", "shutdown"]
# Tags opcodes
class OpGetTags(OpCode):
"""Returns the tags of the given object."""
OP_ID = "OP_TAGS_GET"
__slots__ = ["kind", "name"]
class OpSearchTags(OpCode):
"""Searches the tags in the cluster for a given pattern."""
OP_ID = "OP_TAGS_SEARCH"
__slots__ = ["pattern"]
class OpAddTags(OpCode):
"""Add a list of tags on a given object."""
OP_ID = "OP_TAGS_SET"
__slots__ = ["kind", "name", "tags"]
class OpDelTags(OpCode):
"""Remove a list of tags from a given object."""
OP_ID = "OP_TAGS_DEL"
__slots__ = ["kind", "name", "tags"]
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# Test opcodes
class OpTestDelay(OpCode):
"""Sleeps for a configured amount of time.
This is used just for debugging and testing.
Parameters:
- duration: the time to sleep
- on_master: if true, sleep on the master
- on_nodes: list of nodes in which to sleep
If the on_master parameter is true, it will execute a sleep on the
master (before any node sleep).
If the on_nodes list is not empty, it will sleep on those nodes
(after the sleep on the master, if that is enabled).
As an additional feature, the case of duration < 0 will be reported
as an execution error, so this opcode can be used as a failure
generator. The case of duration == 0 will not be treated specially.
"""
OP_ID = "OP_TEST_DELAY"
__slots__ = ["duration", "on_master", "on_nodes"]