Revision df458e0b

b/lib/opcodes.py
36 36
# few public methods:
37 37
# pylint: disable-msg=R0903
38 38

  
39
class OpCode(object):
40
  """Abstract OpCode"""
41
  OP_ID = "OP_ABSTRACT"
39

  
40
class BaseJO(object):
41
  """A simple serializable object.
42

  
43
  This object serves as a parent class for both OpCode and Job since
44
  they are serialized in the same way.
45

  
46
  """
42 47
  __slots__ = []
43 48

  
44 49
  def __init__(self, **kwargs):
45 50
    for key in kwargs:
46 51
      if key not in self.__slots__:
47
        raise TypeError("OpCode %s doesn't support the parameter '%s'" %
52
        raise TypeError("Object %s doesn't support the parameter '%s'" %
48 53
                        (self.__class__.__name__, key))
49 54
      setattr(self, key, kwargs[key])
50 55

  
56
  def __getstate__(self):
57
    state = {}
58
    for name in self.__slots__:
59
      if hasattr(self, name):
60
        state[name] = getattr(self, name)
61
    return state
62

  
63
  def __setstate__(self, state):
64
    if not isinstance(state, dict):
65
      raise ValueError("Invalid data to __setstate__: expected dict, got %s" %
66
                       type(state))
67

  
68
    for name in self.__slots__:
69
      if name not in state:
70
        delattr(self, name)
71

  
72
    for name in state:
73
      setattr(self, name, state[name])
74

  
75

  
76
class Job(BaseJO):
77
  """Job definition structure"""
78
  STATUS_PENDING = 1
79
  STATUS_RUNNING = 2
80
  STATUS_FINISHED = 3
81
  RESULT_OK = 1
82
  RESULT_FAIL = 2
83
  RESULT_ABORT = 3
84

  
85
  __slots__ = ["job_id", "op_list", "status", "result"]
86

  
87
  def __getstate__(self):
88
    """Specialized getstate for jobs
89

  
90
    """
91
    data = BaseJO.__getstate__(self)
92
    if "op_list" in data:
93
      data["op_list"] = [op.__getstate__() for op in data["op_list"]]
94
    return data
95

  
96
  def __setstate__(self, state):
97
    """Specialized setstate for jobs
98

  
99
    """
100
    BaseJO.__setstate__(self, state)
101
    if "op_list" in state:
102
      self.op_list = [OpCode.LoadOpcode(op) for op in state["op_list"]]
103

  
104

  
105
class OpCode(BaseJO):
106
  """Abstract OpCode"""
107
  OP_ID = "OP_ABSTRACT"
108
  __slots__ = []
109

  
110
  def __getstate__(self):
111
    """Specialized getstate for opcodes.
112

  
113
    """
114
    data = BaseJO.__getstate__(self)
115
    data["OP_ID"] = self.OP_ID
116
    return data
117

  
118
  @classmethod
119
  def LoadOpcode(cls, data):
120
    """Generic load opcode method.
121

  
122
    """
123
    if not isinstance(data, dict):
124
      raise ValueError("Invalid data to LoadOpCode (%s)" % type(data))
125
    if "OP_ID" not in data:
126
      raise ValueError("Invalid data to LoadOpcode, missing OP_ID")
127
    op_id = data["OP_ID"]
128
    op_class = None
129
    for item in globals().values():
130
      if (isinstance(item, type) and
131
          issubclass(item, cls) and
132
          hasattr(item, "OP_ID") and
133
          getattr(item, "OP_ID") == op_id):
134
        op_class = item
135
        break
136
    if op_class is None:
137
      raise ValueError("Invalid data to LoadOpCode: OP_ID %s unsupported" %
138
                       op_id)
139
    op = op_class()
140
    new_data = data.copy()
141
    del new_data["OP_ID"]
142
    op.__setstate__(new_data)
143
    return op
144

  
51 145

  
52 146
class OpInitCluster(OpCode):
53 147
  """Initialise the cluster."""

Also available in: Unified diff