Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 8aa8f6b1

History | View | Annotate | Download (5.9 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 _ExpandNodeName, _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.op.name = _ExpandNodeName(self.cfg, self.op.name)
48
      lock_level = locking.LEVEL_NODE
49
      lock_name = self.op.name
50
    elif self.op.kind == constants.TAG_INSTANCE:
51
      self.op.name = _ExpandInstanceName(self.cfg, self.op.name)
52
      lock_level = locking.LEVEL_INSTANCE
53
      lock_name = self.op.name
54
    elif self.op.kind == constants.TAG_NODEGROUP:
55
      self.group_uuid = self.cfg.LookupNodeGroup(self.op.name)
56
      lock_level = locking.LEVEL_NODEGROUP
57
      lock_name = self.group_uuid
58
    elif self.op.kind == constants.TAG_NETWORK:
59
      self.network_uuid = self.cfg.LookupNetwork(self.op.name)
60
      lock_level = locking.LEVEL_NETWORK
61
      lock_name = self.network_uuid
62
    else:
63
      lock_level = None
64
      lock_name = None
65

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

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

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

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

    
90

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

94
  """
95
  REQ_BGL = False
96

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

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

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

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

    
109

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

113
  """
114
  REQ_BGL = False
115

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

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

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

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

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

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

    
150

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

154
  """
155
  REQ_BGL = False
156

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

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

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

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

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

    
178

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

182
  """
183
  REQ_BGL = False
184

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

188
    This checks that we have the given tag.
189

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

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

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

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