Statistics
| Branch: | Tag: | Revision:

root / lib / opcodes.py.in_before @ 355d1f32

History | View | Annotate | Download (6.9 kB)

1 580b1fdd Jose A. Lopes
#
2 580b1fdd Jose A. Lopes
#
3 580b1fdd Jose A. Lopes
4 580b1fdd Jose A. Lopes
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 580b1fdd Jose A. Lopes
#
6 580b1fdd Jose A. Lopes
# This program is free software; you can redistribute it and/or modify
7 580b1fdd Jose A. Lopes
# it under the terms of the GNU General Public License as published by
8 580b1fdd Jose A. Lopes
# the Free Software Foundation; either version 2 of the License, or
9 580b1fdd Jose A. Lopes
# (at your option) any later version.
10 580b1fdd Jose A. Lopes
#
11 580b1fdd Jose A. Lopes
# This program is distributed in the hope that it will be useful, but
12 580b1fdd Jose A. Lopes
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 580b1fdd Jose A. Lopes
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 580b1fdd Jose A. Lopes
# General Public License for more details.
15 580b1fdd Jose A. Lopes
#
16 580b1fdd Jose A. Lopes
# You should have received a copy of the GNU General Public License
17 580b1fdd Jose A. Lopes
# along with this program; if not, write to the Free Software
18 580b1fdd Jose A. Lopes
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 580b1fdd Jose A. Lopes
# 02110-1301, USA.
20 580b1fdd Jose A. Lopes
21 580b1fdd Jose A. Lopes
22 580b1fdd Jose A. Lopes
"""OpCodes module
23 580b1fdd Jose A. Lopes
24 580b1fdd Jose A. Lopes
Note that this file is autogenerated using @src/hs2py@ with a header
25 580b1fdd Jose A. Lopes
from @lib/opcodes.py.in_before@ and a footer from @lib/opcodes.py.in_after@.
26 580b1fdd Jose A. Lopes
27 580b1fdd Jose A. Lopes
This module implements part of the data structures which define the
28 580b1fdd Jose A. Lopes
cluster operations - the so-called opcodes.
29 580b1fdd Jose A. Lopes
30 580b1fdd Jose A. Lopes
Every operation which modifies the cluster state is expressed via
31 580b1fdd Jose A. Lopes
opcodes.
32 580b1fdd Jose A. Lopes
33 580b1fdd Jose A. Lopes
"""
34 580b1fdd Jose A. Lopes
35 580b1fdd Jose A. Lopes
# this are practically structures, so disable the message about too
36 580b1fdd Jose A. Lopes
# few public methods:
37 580b1fdd Jose A. Lopes
# pylint: disable=R0903
38 580b1fdd Jose A. Lopes
# pylint: disable=C0301
39 580b1fdd Jose A. Lopes
40 580b1fdd Jose A. Lopes
from ganeti import constants
41 580b1fdd Jose A. Lopes
from ganeti import ht
42 580b1fdd Jose A. Lopes
43 580b1fdd Jose A. Lopes
from ganeti import opcodes_base
44 580b1fdd Jose A. Lopes
45 580b1fdd Jose A. Lopes
46 580b1fdd Jose A. Lopes
class OpCode(opcodes_base.BaseOpCode):
47 580b1fdd Jose A. Lopes
  """Abstract OpCode.
48 580b1fdd Jose A. Lopes
49 580b1fdd Jose A. Lopes
  This is the root of the actual OpCode hierarchy. All clases derived
50 580b1fdd Jose A. Lopes
  from this class should override OP_ID.
51 580b1fdd Jose A. Lopes
52 580b1fdd Jose A. Lopes
  @cvar OP_ID: The ID of this opcode. This should be unique amongst all
53 580b1fdd Jose A. Lopes
               children of this class.
54 580b1fdd Jose A. Lopes
  @cvar OP_DSC_FIELD: The name of a field whose value will be included in the
55 580b1fdd Jose A. Lopes
                      string returned by Summary(); see the docstring of that
56 580b1fdd Jose A. Lopes
                      method for details).
57 580b1fdd Jose A. Lopes
  @cvar OP_DSC_FORMATTER: A callable that should format the OP_DSC_FIELD; if
58 580b1fdd Jose A. Lopes
                          not present, then the field will be simply converted
59 580b1fdd Jose A. Lopes
                          to string
60 580b1fdd Jose A. Lopes
  @cvar OP_PARAMS: List of opcode attributes, the default values they should
61 580b1fdd Jose A. Lopes
                   get if not already defined, and types they must match.
62 580b1fdd Jose A. Lopes
  @cvar OP_RESULT: Callable to verify opcode result
63 580b1fdd Jose A. Lopes
  @cvar WITH_LU: Boolean that specifies whether this should be included in
64 580b1fdd Jose A. Lopes
      mcpu's dispatch table
65 580b1fdd Jose A. Lopes
  @ivar dry_run: Whether the LU should be run in dry-run mode, i.e. just
66 580b1fdd Jose A. Lopes
                 the check steps
67 580b1fdd Jose A. Lopes
  @ivar priority: Opcode priority for queue
68 580b1fdd Jose A. Lopes
69 580b1fdd Jose A. Lopes
  """
70 580b1fdd Jose A. Lopes
  # pylint: disable=E1101
71 580b1fdd Jose A. Lopes
  # as OP_ID is dynamically defined
72 580b1fdd Jose A. Lopes
  WITH_LU = True
73 580b1fdd Jose A. Lopes
  OP_PARAMS = [
74 580b1fdd Jose A. Lopes
    ("dry_run", None, ht.TMaybe(ht.TBool), "Run checks only, don't execute"),
75 580b1fdd Jose A. Lopes
    ("debug_level", None, ht.TMaybe(ht.TNonNegative(ht.TInt)), "Debug level"),
76 580b1fdd Jose A. Lopes
    ("priority", constants.OP_PRIO_DEFAULT,
77 580b1fdd Jose A. Lopes
     ht.TElemOf(constants.OP_PRIO_SUBMIT_VALID), "Opcode priority"),
78 580b1fdd Jose A. Lopes
    (opcodes_base.DEPEND_ATTR, None, opcodes_base.BuildJobDepCheck(True),
79 580b1fdd Jose A. Lopes
     "Job dependencies; if used through ``SubmitManyJobs`` relative (negative)"
80 580b1fdd Jose A. Lopes
     " job IDs can be used; see :doc:`design document <design-chained-jobs>`"
81 580b1fdd Jose A. Lopes
     " for details"),
82 580b1fdd Jose A. Lopes
    (opcodes_base.COMMENT_ATTR, None, ht.TMaybe(ht.TString),
83 580b1fdd Jose A. Lopes
     "Comment describing the purpose of the opcode"),
84 580b1fdd Jose A. Lopes
    (constants.OPCODE_REASON, None, ht.TMaybe(ht.TListOf(ht.TAny)),
85 580b1fdd Jose A. Lopes
     "The reason trail, describing why the OpCode is executed"),
86 580b1fdd Jose A. Lopes
    ]
87 580b1fdd Jose A. Lopes
  OP_RESULT = None
88 580b1fdd Jose A. Lopes
89 580b1fdd Jose A. Lopes
  def __getstate__(self):
90 580b1fdd Jose A. Lopes
    """Specialized getstate for opcodes.
91 580b1fdd Jose A. Lopes
92 580b1fdd Jose A. Lopes
    This method adds to the state dictionary the OP_ID of the class,
93 580b1fdd Jose A. Lopes
    so that on unload we can identify the correct class for
94 580b1fdd Jose A. Lopes
    instantiating the opcode.
95 580b1fdd Jose A. Lopes
96 580b1fdd Jose A. Lopes
    @rtype:   C{dict}
97 580b1fdd Jose A. Lopes
    @return:  the state as a dictionary
98 580b1fdd Jose A. Lopes
99 580b1fdd Jose A. Lopes
    """
100 580b1fdd Jose A. Lopes
    data = opcodes_base.BaseOpCode.__getstate__(self)
101 580b1fdd Jose A. Lopes
    data["OP_ID"] = self.OP_ID
102 580b1fdd Jose A. Lopes
    return data
103 580b1fdd Jose A. Lopes
104 580b1fdd Jose A. Lopes
  @classmethod
105 580b1fdd Jose A. Lopes
  def LoadOpCode(cls, data):
106 580b1fdd Jose A. Lopes
    """Generic load opcode method.
107 580b1fdd Jose A. Lopes
108 580b1fdd Jose A. Lopes
    The method identifies the correct opcode class from the dict-form
109 580b1fdd Jose A. Lopes
    by looking for a OP_ID key, if this is not found, or its value is
110 580b1fdd Jose A. Lopes
    not available in this module as a child of this class, we fail.
111 580b1fdd Jose A. Lopes
112 580b1fdd Jose A. Lopes
    @type data:  C{dict}
113 580b1fdd Jose A. Lopes
    @param data: the serialized opcode
114 580b1fdd Jose A. Lopes
115 580b1fdd Jose A. Lopes
    """
116 580b1fdd Jose A. Lopes
    if not isinstance(data, dict):
117 580b1fdd Jose A. Lopes
      raise ValueError("Invalid data to LoadOpCode (%s)" % type(data))
118 580b1fdd Jose A. Lopes
    if "OP_ID" not in data:
119 580b1fdd Jose A. Lopes
      raise ValueError("Invalid data to LoadOpcode, missing OP_ID")
120 580b1fdd Jose A. Lopes
    op_id = data["OP_ID"]
121 580b1fdd Jose A. Lopes
    op_class = None
122 580b1fdd Jose A. Lopes
    if op_id in OP_MAPPING:
123 580b1fdd Jose A. Lopes
      op_class = OP_MAPPING[op_id]
124 580b1fdd Jose A. Lopes
    else:
125 580b1fdd Jose A. Lopes
      raise ValueError("Invalid data to LoadOpCode: OP_ID %s unsupported" %
126 580b1fdd Jose A. Lopes
                       op_id)
127 580b1fdd Jose A. Lopes
    op = op_class()
128 580b1fdd Jose A. Lopes
    new_data = data.copy()
129 580b1fdd Jose A. Lopes
    del new_data["OP_ID"]
130 580b1fdd Jose A. Lopes
    op.__setstate__(new_data)
131 580b1fdd Jose A. Lopes
    return op
132 580b1fdd Jose A. Lopes
133 580b1fdd Jose A. Lopes
  def Summary(self):
134 580b1fdd Jose A. Lopes
    """Generates a summary description of this opcode.
135 580b1fdd Jose A. Lopes
136 580b1fdd Jose A. Lopes
    The summary is the value of the OP_ID attribute (without the "OP_"
137 580b1fdd Jose A. Lopes
    prefix), plus the value of the OP_DSC_FIELD attribute, if one was
138 580b1fdd Jose A. Lopes
    defined; this field should allow to easily identify the operation
139 580b1fdd Jose A. Lopes
    (for an instance creation job, e.g., it would be the instance
140 580b1fdd Jose A. Lopes
    name).
141 580b1fdd Jose A. Lopes
142 580b1fdd Jose A. Lopes
    """
143 580b1fdd Jose A. Lopes
    assert self.OP_ID is not None and len(self.OP_ID) > 3
144 580b1fdd Jose A. Lopes
    # all OP_ID start with OP_, we remove that
145 580b1fdd Jose A. Lopes
    txt = self.OP_ID[3:]
146 580b1fdd Jose A. Lopes
    field_name = getattr(self, "OP_DSC_FIELD", None)
147 580b1fdd Jose A. Lopes
    if field_name:
148 580b1fdd Jose A. Lopes
      field_value = getattr(self, field_name, None)
149 580b1fdd Jose A. Lopes
      field_formatter = getattr(self, "OP_DSC_FORMATTER", None)
150 580b1fdd Jose A. Lopes
      if callable(field_formatter):
151 580b1fdd Jose A. Lopes
        field_value = field_formatter(field_value)
152 580b1fdd Jose A. Lopes
      elif isinstance(field_value, (list, tuple)):
153 580b1fdd Jose A. Lopes
        field_value = ",".join(str(i) for i in field_value)
154 580b1fdd Jose A. Lopes
      txt = "%s(%s)" % (txt, field_value)
155 580b1fdd Jose A. Lopes
    return txt
156 580b1fdd Jose A. Lopes
157 580b1fdd Jose A. Lopes
  def TinySummary(self):
158 580b1fdd Jose A. Lopes
    """Generates a compact summary description of the opcode.
159 580b1fdd Jose A. Lopes
160 580b1fdd Jose A. Lopes
    """
161 580b1fdd Jose A. Lopes
    assert self.OP_ID.startswith("OP_")
162 580b1fdd Jose A. Lopes
163 580b1fdd Jose A. Lopes
    text = self.OP_ID[3:]
164 580b1fdd Jose A. Lopes
165 580b1fdd Jose A. Lopes
    for (prefix, supplement) in opcodes_base.SUMMARY_PREFIX.items():
166 580b1fdd Jose A. Lopes
      if text.startswith(prefix):
167 580b1fdd Jose A. Lopes
        return supplement + text[len(prefix):]
168 580b1fdd Jose A. Lopes
169 580b1fdd Jose A. Lopes
    return text
170 580b1fdd Jose A. Lopes
171 580b1fdd Jose A. Lopes
172 580b1fdd Jose A. Lopes
class OpInstanceMultiAllocBase(OpCode):
173 580b1fdd Jose A. Lopes
  """Allocates multiple instances.
174 580b1fdd Jose A. Lopes
175 580b1fdd Jose A. Lopes
  """
176 580b1fdd Jose A. Lopes
  def __getstate__(self):
177 580b1fdd Jose A. Lopes
    """Generic serializer.
178 580b1fdd Jose A. Lopes
179 580b1fdd Jose A. Lopes
    """
180 580b1fdd Jose A. Lopes
    state = OpCode.__getstate__(self)
181 580b1fdd Jose A. Lopes
    if hasattr(self, "instances"):
182 580b1fdd Jose A. Lopes
      # pylint: disable=E1101
183 580b1fdd Jose A. Lopes
      state["instances"] = [inst.__getstate__() for inst in self.instances]
184 580b1fdd Jose A. Lopes
    return state
185 580b1fdd Jose A. Lopes
186 580b1fdd Jose A. Lopes
  def __setstate__(self, state):
187 580b1fdd Jose A. Lopes
    """Generic unserializer.
188 580b1fdd Jose A. Lopes
189 580b1fdd Jose A. Lopes
    This method just restores from the serialized state the attributes
190 580b1fdd Jose A. Lopes
    of the current instance.
191 580b1fdd Jose A. Lopes
192 580b1fdd Jose A. Lopes
    @param state: the serialized opcode data
193 580b1fdd Jose A. Lopes
    @type state: C{dict}
194 580b1fdd Jose A. Lopes
195 580b1fdd Jose A. Lopes
    """
196 580b1fdd Jose A. Lopes
    if not isinstance(state, dict):
197 580b1fdd Jose A. Lopes
      raise ValueError("Invalid data to __setstate__: expected dict, got %s" %
198 580b1fdd Jose A. Lopes
                       type(state))
199 580b1fdd Jose A. Lopes
200 580b1fdd Jose A. Lopes
    if "instances" in state:
201 580b1fdd Jose A. Lopes
      state["instances"] = map(OpCode.LoadOpCode, state["instances"])
202 580b1fdd Jose A. Lopes
203 580b1fdd Jose A. Lopes
    return OpCode.__setstate__(self, state)
204 580b1fdd Jose A. Lopes
205 580b1fdd Jose A. Lopes
  def Validate(self, set_defaults):
206 580b1fdd Jose A. Lopes
    """Validates this opcode.
207 580b1fdd Jose A. Lopes
208 580b1fdd Jose A. Lopes
    We do this recursively.
209 580b1fdd Jose A. Lopes
210 580b1fdd Jose A. Lopes
    """
211 580b1fdd Jose A. Lopes
    OpCode.Validate(self, set_defaults)
212 580b1fdd Jose A. Lopes
213 580b1fdd Jose A. Lopes
    for inst in self.instances: # pylint: disable=E1101
214 580b1fdd Jose A. Lopes
      inst.Validate(set_defaults)