Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 1c3231aa

History | View | Annotate | Download (6 kB)

1
#
2
#
3

    
4
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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
"""Logical units dealing with tags."""
23

    
24
import re
25

    
26
from ganeti import constants
27
from ganeti import errors
28
from ganeti import locking
29
from ganeti import objects
30
from ganeti import utils
31
from ganeti.cmdlib.base import NoHooksLU
32
from ganeti.cmdlib.common import ExpandNodeUuidAndName, ExpandInstanceName, \
33
  ShareAll
34

    
35

    
36
class TagsLU(NoHooksLU): # pylint: disable=W0223
37
  """Generic tags LU.
38

39
  This is an abstract class which is the parent of all the other tags LUs.
40

41
  """
42
  def ExpandNames(self):
43
    self.group_uuid = None
44
    self.needed_locks = {}
45

    
46
    if self.op.kind == constants.TAG_NODE:
47
      (self.node_uuid, _) = \
48
        ExpandNodeUuidAndName(self.cfg, None, self.op.name)
49
      lock_level = locking.LEVEL_NODE
50
      lock_name = self.node_uuid
51
    elif self.op.kind == constants.TAG_INSTANCE:
52
      self.op.name = ExpandInstanceName(self.cfg, self.op.name)
53
      lock_level = locking.LEVEL_INSTANCE
54
      lock_name = self.op.name
55
    elif self.op.kind == constants.TAG_NODEGROUP:
56
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
57
      lock_level = locking.LEVEL_NODEGROUP
58
      lock_name = self.group_uuid
59
    elif self.op.kind == constants.TAG_NETWORK:
60
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
61
      lock_level = locking.LEVEL_NETWORK
62
      lock_name = self.network_uuid
63
    else:
64
      lock_level = None
65
      lock_name = None
66

    
67
    if lock_level and getattr(self.op, "use_locking", True):
68
      self.needed_locks[lock_level] = lock_name
69

    
70
    # FIXME: Acquire BGL for cluster tag operations (as of this writing it's
71
    # not possible to acquire the BGL based on opcode parameters)
72

    
73
  def CheckPrereq(self):
74
    """Check prerequisites.
75

76
    """
77
    if self.op.kind == constants.TAG_CLUSTER:
78
      self.target = self.cfg.GetClusterInfo()
79
    elif self.op.kind == constants.TAG_NODE:
80
      self.target = self.cfg.GetNodeInfo(self.node_uuid)
81
    elif self.op.kind == constants.TAG_INSTANCE:
82
      self.target = self.cfg.GetInstanceInfo(self.op.name)
83
    elif self.op.kind == constants.TAG_NODEGROUP:
84
      self.target = self.cfg.GetNodeGroup(self.group_uuid)
85
    elif self.op.kind == constants.TAG_NETWORK:
86
      self.target = self.cfg.GetNetwork(self.network_uuid)
87
    else:
88
      raise errors.OpPrereqError("Wrong tag type requested (%s)" %
89
                                 str(self.op.kind), errors.ECODE_INVAL)
90

    
91

    
92
class LUTagsGet(TagsLU):
93
  """Returns the tags of a given object.
94

95
  """
96
  REQ_BGL = False
97

    
98
  def ExpandNames(self):
99
    TagsLU.ExpandNames(self)
100

    
101
    # Share locks as this is only a read operation
102
    self.share_locks = ShareAll()
103

    
104
  def Exec(self, feedback_fn):
105
    """Returns the tag list.
106

107
    """
108
    return list(self.target.GetTags())
109

    
110

    
111
class LUTagsSearch(NoHooksLU):
112
  """Searches the tags for a given pattern.
113

114
  """
115
  REQ_BGL = False
116

    
117
  def ExpandNames(self):
118
    self.needed_locks = {}
119

    
120
  def CheckPrereq(self):
121
    """Check prerequisites.
122

123
    This checks the pattern passed for validity by compiling it.
124

125
    """
126
    try:
127
      self.re = re.compile(self.op.pattern)
128
    except re.error, err:
129
      raise errors.OpPrereqError("Invalid search pattern '%s': %s" %
130
                                 (self.op.pattern, err), errors.ECODE_INVAL)
131

    
132
  def Exec(self, feedback_fn):
133
    """Returns the tag list.
134

135
    """
136
    cfg = self.cfg
137
    tgts = [("/cluster", cfg.GetClusterInfo())]
138
    ilist = cfg.GetAllInstancesInfo().values()
139
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
140
    nlist = cfg.GetAllNodesInfo().values()
141
    tgts.extend([("/nodes/%s" % n.name, n) for n in nlist])
142
    tgts.extend(("/nodegroup/%s" % n.name, n)
143
                for n in cfg.GetAllNodeGroupsInfo().values())
144
    results = []
145
    for path, target in tgts:
146
      for tag in target.GetTags():
147
        if self.re.search(tag):
148
          results.append((path, tag))
149
    return results
150

    
151

    
152
class LUTagsSet(TagsLU):
153
  """Sets a tag on a given object.
154

155
  """
156
  REQ_BGL = False
157

    
158
  def CheckPrereq(self):
159
    """Check prerequisites.
160

161
    This checks the type and length of the tag name and value.
162

163
    """
164
    TagsLU.CheckPrereq(self)
165
    for tag in self.op.tags:
166
      objects.TaggableObject.ValidateTag(tag)
167

    
168
  def Exec(self, feedback_fn):
169
    """Sets the tag.
170

171
    """
172
    try:
173
      for tag in self.op.tags:
174
        self.target.AddTag(tag)
175
    except errors.TagError, err:
176
      raise errors.OpExecError("Error while setting tag: %s" % str(err))
177
    self.cfg.Update(self.target, feedback_fn)
178

    
179

    
180
class LUTagsDel(TagsLU):
181
  """Delete a list of tags from a given object.
182

183
  """
184
  REQ_BGL = False
185

    
186
  def CheckPrereq(self):
187
    """Check prerequisites.
188

189
    This checks that we have the given tag.
190

191
    """
192
    TagsLU.CheckPrereq(self)
193
    for tag in self.op.tags:
194
      objects.TaggableObject.ValidateTag(tag)
195
    del_tags = frozenset(self.op.tags)
196
    cur_tags = self.target.GetTags()
197

    
198
    diff_tags = del_tags - cur_tags
199
    if diff_tags:
200
      diff_names = ("'%s'" % i for i in sorted(diff_tags))
201
      raise errors.OpPrereqError("Tag(s) %s not found" %
202
                                 (utils.CommaJoin(diff_names), ),
203
                                 errors.ECODE_NOENT)
204

    
205
  def Exec(self, feedback_fn):
206
    """Remove the tag from the object.
207

208
    """
209
    for tag in self.op.tags:
210
      self.target.RemoveTag(tag)
211
    self.cfg.Update(self.target, feedback_fn)