Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / tags.py @ 3f3ea14c

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, ShareAll
33

    
34

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

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

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

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

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

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

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

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

    
89

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

93
  """
94
  REQ_BGL = False
95

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

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

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

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

    
108

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

112
  """
113
  REQ_BGL = False
114

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

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

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

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

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

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

    
149

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

153
  """
154
  REQ_BGL = False
155

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

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

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

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

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

    
177

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

181
  """
182
  REQ_BGL = False
183

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

187
    This checks that we have the given tag.
188

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

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

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

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