Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ da4a52a3

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, \
33
  ExpandInstanceUuidAndName, 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.inst_uuid, inst_name) = \
53
        ExpandInstanceUuidAndName(self.cfg, None, self.op.name)
54
      lock_level = locking.LEVEL_INSTANCE
55
      lock_name = inst_name
56
    elif self.op.kind == constants.TAG_NODEGROUP:
57
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
58
      lock_level = locking.LEVEL_NODEGROUP
59
      lock_name = self.group_uuid
60
    elif self.op.kind == constants.TAG_NETWORK:
61
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
62
      lock_level = locking.LEVEL_NETWORK
63
      lock_name = self.network_uuid
64
    else:
65
      lock_level = None
66
      lock_name = None
67

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

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

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

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

    
92

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

96
  """
97
  REQ_BGL = False
98

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

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

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

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

    
111

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

115
  """
116
  REQ_BGL = False
117

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

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

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

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

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

136
    """
137
    tgts = [("/cluster", self.cfg.GetClusterInfo())]
138
    ilist = self.cfg.GetAllInstancesInfo().values()
139
    tgts.extend([("/instances/%s" % i.name, i) for i in ilist])
140
    nlist = self.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 self.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)