Statistics
| Branch: | Tag: | Revision:

root / lib / cmdlib / instance_utils.py @ 5831baf3

History | View | Annotate | Download (20.1 kB)

1 22b7f6f8 Thomas Thrainer
#
2 22b7f6f8 Thomas Thrainer
#
3 22b7f6f8 Thomas Thrainer
4 22b7f6f8 Thomas Thrainer
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Google Inc.
5 22b7f6f8 Thomas Thrainer
#
6 22b7f6f8 Thomas Thrainer
# This program is free software; you can redistribute it and/or modify
7 22b7f6f8 Thomas Thrainer
# it under the terms of the GNU General Public License as published by
8 22b7f6f8 Thomas Thrainer
# the Free Software Foundation; either version 2 of the License, or
9 22b7f6f8 Thomas Thrainer
# (at your option) any later version.
10 22b7f6f8 Thomas Thrainer
#
11 22b7f6f8 Thomas Thrainer
# This program is distributed in the hope that it will be useful, but
12 22b7f6f8 Thomas Thrainer
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 22b7f6f8 Thomas Thrainer
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 22b7f6f8 Thomas Thrainer
# General Public License for more details.
15 22b7f6f8 Thomas Thrainer
#
16 22b7f6f8 Thomas Thrainer
# You should have received a copy of the GNU General Public License
17 22b7f6f8 Thomas Thrainer
# along with this program; if not, write to the Free Software
18 22b7f6f8 Thomas Thrainer
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 22b7f6f8 Thomas Thrainer
# 02110-1301, USA.
20 22b7f6f8 Thomas Thrainer
21 22b7f6f8 Thomas Thrainer
22 22b7f6f8 Thomas Thrainer
"""Utility function mainly, but not only used by instance LU's."""
23 22b7f6f8 Thomas Thrainer
24 22b7f6f8 Thomas Thrainer
import logging
25 22b7f6f8 Thomas Thrainer
import os
26 22b7f6f8 Thomas Thrainer
27 22b7f6f8 Thomas Thrainer
from ganeti import constants
28 22b7f6f8 Thomas Thrainer
from ganeti import errors
29 22b7f6f8 Thomas Thrainer
from ganeti import locking
30 22b7f6f8 Thomas Thrainer
from ganeti import network
31 22b7f6f8 Thomas Thrainer
from ganeti import objects
32 22b7f6f8 Thomas Thrainer
from ganeti import pathutils
33 22b7f6f8 Thomas Thrainer
from ganeti import utils
34 5eacbcae Thomas Thrainer
from ganeti.cmdlib.common import AnnotateDiskParams, \
35 5eacbcae Thomas Thrainer
  ComputeIPolicyInstanceViolation
36 22b7f6f8 Thomas Thrainer
37 22b7f6f8 Thomas Thrainer
38 5eacbcae Thomas Thrainer
def BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
39 5eacbcae Thomas Thrainer
                         minmem, maxmem, vcpus, nics, disk_template, disks,
40 5eacbcae Thomas Thrainer
                         bep, hvp, hypervisor_name, tags):
41 22b7f6f8 Thomas Thrainer
  """Builds instance related env variables for hooks
42 22b7f6f8 Thomas Thrainer

43 22b7f6f8 Thomas Thrainer
  This builds the hook environment from individual variables.
44 22b7f6f8 Thomas Thrainer

45 22b7f6f8 Thomas Thrainer
  @type name: string
46 22b7f6f8 Thomas Thrainer
  @param name: the name of the instance
47 22b7f6f8 Thomas Thrainer
  @type primary_node: string
48 22b7f6f8 Thomas Thrainer
  @param primary_node: the name of the instance's primary node
49 22b7f6f8 Thomas Thrainer
  @type secondary_nodes: list
50 22b7f6f8 Thomas Thrainer
  @param secondary_nodes: list of secondary nodes as strings
51 22b7f6f8 Thomas Thrainer
  @type os_type: string
52 22b7f6f8 Thomas Thrainer
  @param os_type: the name of the instance's OS
53 22b7f6f8 Thomas Thrainer
  @type status: string
54 22b7f6f8 Thomas Thrainer
  @param status: the desired status of the instance
55 22b7f6f8 Thomas Thrainer
  @type minmem: string
56 22b7f6f8 Thomas Thrainer
  @param minmem: the minimum memory size of the instance
57 22b7f6f8 Thomas Thrainer
  @type maxmem: string
58 22b7f6f8 Thomas Thrainer
  @param maxmem: the maximum memory size of the instance
59 22b7f6f8 Thomas Thrainer
  @type vcpus: string
60 22b7f6f8 Thomas Thrainer
  @param vcpus: the count of VCPUs the instance has
61 22b7f6f8 Thomas Thrainer
  @type nics: list
62 22b7f6f8 Thomas Thrainer
  @param nics: list of tuples (name, uuid, ip, mac, mode, link, net, netinfo)
63 22b7f6f8 Thomas Thrainer
      representing the NICs the instance has
64 22b7f6f8 Thomas Thrainer
  @type disk_template: string
65 22b7f6f8 Thomas Thrainer
  @param disk_template: the disk template of the instance
66 22b7f6f8 Thomas Thrainer
  @type disks: list
67 22b7f6f8 Thomas Thrainer
  @param disks: list of tuples (name, uuid, size, mode)
68 22b7f6f8 Thomas Thrainer
  @type bep: dict
69 22b7f6f8 Thomas Thrainer
  @param bep: the backend parameters for the instance
70 22b7f6f8 Thomas Thrainer
  @type hvp: dict
71 22b7f6f8 Thomas Thrainer
  @param hvp: the hypervisor parameters for the instance
72 22b7f6f8 Thomas Thrainer
  @type hypervisor_name: string
73 22b7f6f8 Thomas Thrainer
  @param hypervisor_name: the hypervisor for the instance
74 22b7f6f8 Thomas Thrainer
  @type tags: list
75 22b7f6f8 Thomas Thrainer
  @param tags: list of instance tags as strings
76 22b7f6f8 Thomas Thrainer
  @rtype: dict
77 22b7f6f8 Thomas Thrainer
  @return: the hook environment for this instance
78 22b7f6f8 Thomas Thrainer

79 22b7f6f8 Thomas Thrainer
  """
80 22b7f6f8 Thomas Thrainer
  env = {
81 22b7f6f8 Thomas Thrainer
    "OP_TARGET": name,
82 22b7f6f8 Thomas Thrainer
    "INSTANCE_NAME": name,
83 22b7f6f8 Thomas Thrainer
    "INSTANCE_PRIMARY": primary_node,
84 22b7f6f8 Thomas Thrainer
    "INSTANCE_SECONDARIES": " ".join(secondary_nodes),
85 22b7f6f8 Thomas Thrainer
    "INSTANCE_OS_TYPE": os_type,
86 22b7f6f8 Thomas Thrainer
    "INSTANCE_STATUS": status,
87 22b7f6f8 Thomas Thrainer
    "INSTANCE_MINMEM": minmem,
88 22b7f6f8 Thomas Thrainer
    "INSTANCE_MAXMEM": maxmem,
89 22b7f6f8 Thomas Thrainer
    # TODO(2.9) remove deprecated "memory" value
90 22b7f6f8 Thomas Thrainer
    "INSTANCE_MEMORY": maxmem,
91 22b7f6f8 Thomas Thrainer
    "INSTANCE_VCPUS": vcpus,
92 22b7f6f8 Thomas Thrainer
    "INSTANCE_DISK_TEMPLATE": disk_template,
93 22b7f6f8 Thomas Thrainer
    "INSTANCE_HYPERVISOR": hypervisor_name,
94 22b7f6f8 Thomas Thrainer
    }
95 22b7f6f8 Thomas Thrainer
  if nics:
96 22b7f6f8 Thomas Thrainer
    nic_count = len(nics)
97 8a348b15 Christos Stavrakakis
    for idx, (name, uuid, ip, mac, mode, link, net, netinfo) in enumerate(nics):
98 22b7f6f8 Thomas Thrainer
      if ip is None:
99 22b7f6f8 Thomas Thrainer
        ip = ""
100 8a348b15 Christos Stavrakakis
      if name:
101 8a348b15 Christos Stavrakakis
        env["INSTANCE_NIC%d_NAME" % idx] = name
102 8a348b15 Christos Stavrakakis
      env["INSTANCE_NIC%d_UUID" % idx] = uuid
103 22b7f6f8 Thomas Thrainer
      env["INSTANCE_NIC%d_IP" % idx] = ip
104 22b7f6f8 Thomas Thrainer
      env["INSTANCE_NIC%d_MAC" % idx] = mac
105 22b7f6f8 Thomas Thrainer
      env["INSTANCE_NIC%d_MODE" % idx] = mode
106 22b7f6f8 Thomas Thrainer
      env["INSTANCE_NIC%d_LINK" % idx] = link
107 22b7f6f8 Thomas Thrainer
      if netinfo:
108 22b7f6f8 Thomas Thrainer
        nobj = objects.Network.FromDict(netinfo)
109 22b7f6f8 Thomas Thrainer
        env.update(nobj.HooksDict("INSTANCE_NIC%d_" % idx))
110 22b7f6f8 Thomas Thrainer
      elif network:
111 22b7f6f8 Thomas Thrainer
        # FIXME: broken network reference: the instance NIC specifies a
112 22b7f6f8 Thomas Thrainer
        # network, but the relevant network entry was not in the config. This
113 22b7f6f8 Thomas Thrainer
        # should be made impossible.
114 22b7f6f8 Thomas Thrainer
        env["INSTANCE_NIC%d_NETWORK_NAME" % idx] = net
115 22b7f6f8 Thomas Thrainer
      if mode == constants.NIC_MODE_BRIDGED:
116 22b7f6f8 Thomas Thrainer
        env["INSTANCE_NIC%d_BRIDGE" % idx] = link
117 22b7f6f8 Thomas Thrainer
  else:
118 22b7f6f8 Thomas Thrainer
    nic_count = 0
119 22b7f6f8 Thomas Thrainer
120 22b7f6f8 Thomas Thrainer
  env["INSTANCE_NIC_COUNT"] = nic_count
121 22b7f6f8 Thomas Thrainer
122 22b7f6f8 Thomas Thrainer
  if disks:
123 22b7f6f8 Thomas Thrainer
    disk_count = len(disks)
124 18aa65d1 Dimitris Aragiorgis
    for idx, (name, uuid, size, mode, info) in enumerate(disks):
125 8a348b15 Christos Stavrakakis
      if name:
126 8a348b15 Christos Stavrakakis
        env["INSTANCE_DISK%d_NAME" % idx] = name
127 8a348b15 Christos Stavrakakis
      env["INSTANCE_DISK%d_UUID" % idx] = uuid
128 22b7f6f8 Thomas Thrainer
      env["INSTANCE_DISK%d_SIZE" % idx] = size
129 22b7f6f8 Thomas Thrainer
      env["INSTANCE_DISK%d_MODE" % idx] = mode
130 18aa65d1 Dimitris Aragiorgis
      env.update(info)
131 22b7f6f8 Thomas Thrainer
  else:
132 22b7f6f8 Thomas Thrainer
    disk_count = 0
133 22b7f6f8 Thomas Thrainer
134 22b7f6f8 Thomas Thrainer
  env["INSTANCE_DISK_COUNT"] = disk_count
135 22b7f6f8 Thomas Thrainer
136 22b7f6f8 Thomas Thrainer
  if not tags:
137 22b7f6f8 Thomas Thrainer
    tags = []
138 22b7f6f8 Thomas Thrainer
139 22b7f6f8 Thomas Thrainer
  env["INSTANCE_TAGS"] = " ".join(tags)
140 22b7f6f8 Thomas Thrainer
141 22b7f6f8 Thomas Thrainer
  for source, kind in [(bep, "BE"), (hvp, "HV")]:
142 22b7f6f8 Thomas Thrainer
    for key, value in source.items():
143 22b7f6f8 Thomas Thrainer
      env["INSTANCE_%s_%s" % (kind, key)] = value
144 22b7f6f8 Thomas Thrainer
145 22b7f6f8 Thomas Thrainer
  return env
146 22b7f6f8 Thomas Thrainer
147 22b7f6f8 Thomas Thrainer
148 5eacbcae Thomas Thrainer
def BuildInstanceHookEnvByObject(lu, instance, override=None):
149 22b7f6f8 Thomas Thrainer
  """Builds instance related env variables for hooks from an object.
150 22b7f6f8 Thomas Thrainer

151 22b7f6f8 Thomas Thrainer
  @type lu: L{LogicalUnit}
152 22b7f6f8 Thomas Thrainer
  @param lu: the logical unit on whose behalf we execute
153 22b7f6f8 Thomas Thrainer
  @type instance: L{objects.Instance}
154 22b7f6f8 Thomas Thrainer
  @param instance: the instance for which we should build the
155 22b7f6f8 Thomas Thrainer
      environment
156 22b7f6f8 Thomas Thrainer
  @type override: dict
157 22b7f6f8 Thomas Thrainer
  @param override: dictionary with key/values that will override
158 22b7f6f8 Thomas Thrainer
      our values
159 22b7f6f8 Thomas Thrainer
  @rtype: dict
160 22b7f6f8 Thomas Thrainer
  @return: the hook environment dictionary
161 22b7f6f8 Thomas Thrainer

162 22b7f6f8 Thomas Thrainer
  """
163 22b7f6f8 Thomas Thrainer
  cluster = lu.cfg.GetClusterInfo()
164 22b7f6f8 Thomas Thrainer
  bep = cluster.FillBE(instance)
165 22b7f6f8 Thomas Thrainer
  hvp = cluster.FillHV(instance)
166 22b7f6f8 Thomas Thrainer
  args = {
167 22b7f6f8 Thomas Thrainer
    "name": instance.name,
168 22b7f6f8 Thomas Thrainer
    "primary_node": instance.primary_node,
169 22b7f6f8 Thomas Thrainer
    "secondary_nodes": instance.secondary_nodes,
170 22b7f6f8 Thomas Thrainer
    "os_type": instance.os,
171 22b7f6f8 Thomas Thrainer
    "status": instance.admin_state,
172 22b7f6f8 Thomas Thrainer
    "maxmem": bep[constants.BE_MAXMEM],
173 22b7f6f8 Thomas Thrainer
    "minmem": bep[constants.BE_MINMEM],
174 22b7f6f8 Thomas Thrainer
    "vcpus": bep[constants.BE_VCPUS],
175 5eacbcae Thomas Thrainer
    "nics": NICListToTuple(lu, instance.nics),
176 22b7f6f8 Thomas Thrainer
    "disk_template": instance.disk_template,
177 18aa65d1 Dimitris Aragiorgis
    "disks": [(disk.name, disk.uuid, disk.size, disk.mode,
178 18aa65d1 Dimitris Aragiorgis
               BuildDiskLogicalIDEnv(instance.disk_template, idx, disk))
179 18aa65d1 Dimitris Aragiorgis
              for idx, disk in enumerate(instance.disks)],
180 22b7f6f8 Thomas Thrainer
    "bep": bep,
181 22b7f6f8 Thomas Thrainer
    "hvp": hvp,
182 22b7f6f8 Thomas Thrainer
    "hypervisor_name": instance.hypervisor,
183 22b7f6f8 Thomas Thrainer
    "tags": instance.tags,
184 22b7f6f8 Thomas Thrainer
  }
185 22b7f6f8 Thomas Thrainer
  if override:
186 22b7f6f8 Thomas Thrainer
    args.update(override)
187 5eacbcae Thomas Thrainer
  return BuildInstanceHookEnv(**args) # pylint: disable=W0142
188 22b7f6f8 Thomas Thrainer
189 22b7f6f8 Thomas Thrainer
190 5eacbcae Thomas Thrainer
def GetClusterDomainSecret():
191 22b7f6f8 Thomas Thrainer
  """Reads the cluster domain secret.
192 22b7f6f8 Thomas Thrainer

193 22b7f6f8 Thomas Thrainer
  """
194 22b7f6f8 Thomas Thrainer
  return utils.ReadOneLineFile(pathutils.CLUSTER_DOMAIN_SECRET_FILE,
195 22b7f6f8 Thomas Thrainer
                               strict=True)
196 22b7f6f8 Thomas Thrainer
197 22b7f6f8 Thomas Thrainer
198 5eacbcae Thomas Thrainer
def CheckNodeNotDrained(lu, node):
199 22b7f6f8 Thomas Thrainer
  """Ensure that a given node is not drained.
200 22b7f6f8 Thomas Thrainer

201 22b7f6f8 Thomas Thrainer
  @param lu: the LU on behalf of which we make the check
202 22b7f6f8 Thomas Thrainer
  @param node: the node to check
203 22b7f6f8 Thomas Thrainer
  @raise errors.OpPrereqError: if the node is drained
204 22b7f6f8 Thomas Thrainer

205 22b7f6f8 Thomas Thrainer
  """
206 22b7f6f8 Thomas Thrainer
  if lu.cfg.GetNodeInfo(node).drained:
207 22b7f6f8 Thomas Thrainer
    raise errors.OpPrereqError("Can't use drained node %s" % node,
208 22b7f6f8 Thomas Thrainer
                               errors.ECODE_STATE)
209 22b7f6f8 Thomas Thrainer
210 22b7f6f8 Thomas Thrainer
211 5eacbcae Thomas Thrainer
def CheckNodeVmCapable(lu, node):
212 763ad5be Thomas Thrainer
  """Ensure that a given node is vm capable.
213 22b7f6f8 Thomas Thrainer

214 763ad5be Thomas Thrainer
  @param lu: the LU on behalf of which we make the check
215 763ad5be Thomas Thrainer
  @param node: the node to check
216 763ad5be Thomas Thrainer
  @raise errors.OpPrereqError: if the node is not vm capable
217 22b7f6f8 Thomas Thrainer

218 22b7f6f8 Thomas Thrainer
  """
219 763ad5be Thomas Thrainer
  if not lu.cfg.GetNodeInfo(node).vm_capable:
220 763ad5be Thomas Thrainer
    raise errors.OpPrereqError("Can't use non-vm_capable node %s" % node,
221 763ad5be Thomas Thrainer
                               errors.ECODE_STATE)
222 22b7f6f8 Thomas Thrainer
223 22b7f6f8 Thomas Thrainer
224 5eacbcae Thomas Thrainer
def RemoveInstance(lu, feedback_fn, instance, ignore_failures):
225 22b7f6f8 Thomas Thrainer
  """Utility function to remove an instance.
226 22b7f6f8 Thomas Thrainer

227 22b7f6f8 Thomas Thrainer
  """
228 22b7f6f8 Thomas Thrainer
  logging.info("Removing block devices for instance %s", instance.name)
229 22b7f6f8 Thomas Thrainer
230 5eacbcae Thomas Thrainer
  if not RemoveDisks(lu, instance, ignore_failures=ignore_failures):
231 22b7f6f8 Thomas Thrainer
    if not ignore_failures:
232 22b7f6f8 Thomas Thrainer
      raise errors.OpExecError("Can't remove instance's disks")
233 22b7f6f8 Thomas Thrainer
    feedback_fn("Warning: can't remove instance's disks")
234 22b7f6f8 Thomas Thrainer
235 22b7f6f8 Thomas Thrainer
  logging.info("Removing instance %s out of cluster config", instance.name)
236 22b7f6f8 Thomas Thrainer
237 22b7f6f8 Thomas Thrainer
  lu.cfg.RemoveInstance(instance.name)
238 22b7f6f8 Thomas Thrainer
239 22b7f6f8 Thomas Thrainer
  assert not lu.remove_locks.get(locking.LEVEL_INSTANCE), \
240 22b7f6f8 Thomas Thrainer
    "Instance lock removal conflict"
241 22b7f6f8 Thomas Thrainer
242 22b7f6f8 Thomas Thrainer
  # Remove lock for the instance
243 22b7f6f8 Thomas Thrainer
  lu.remove_locks[locking.LEVEL_INSTANCE] = instance.name
244 22b7f6f8 Thomas Thrainer
245 22b7f6f8 Thomas Thrainer
246 5eacbcae Thomas Thrainer
def RemoveDisks(lu, instance, target_node=None, ignore_failures=False):
247 22b7f6f8 Thomas Thrainer
  """Remove all disks for an instance.
248 22b7f6f8 Thomas Thrainer

249 22b7f6f8 Thomas Thrainer
  This abstracts away some work from `AddInstance()` and
250 22b7f6f8 Thomas Thrainer
  `RemoveInstance()`. Note that in case some of the devices couldn't
251 22b7f6f8 Thomas Thrainer
  be removed, the removal will continue with the other ones.
252 22b7f6f8 Thomas Thrainer

253 22b7f6f8 Thomas Thrainer
  @type lu: L{LogicalUnit}
254 22b7f6f8 Thomas Thrainer
  @param lu: the logical unit on whose behalf we execute
255 22b7f6f8 Thomas Thrainer
  @type instance: L{objects.Instance}
256 22b7f6f8 Thomas Thrainer
  @param instance: the instance whose disks we should remove
257 22b7f6f8 Thomas Thrainer
  @type target_node: string
258 22b7f6f8 Thomas Thrainer
  @param target_node: used to override the node on which to remove the disks
259 22b7f6f8 Thomas Thrainer
  @rtype: boolean
260 22b7f6f8 Thomas Thrainer
  @return: the success of the removal
261 22b7f6f8 Thomas Thrainer

262 22b7f6f8 Thomas Thrainer
  """
263 22b7f6f8 Thomas Thrainer
  logging.info("Removing block devices for instance %s", instance.name)
264 22b7f6f8 Thomas Thrainer
265 22b7f6f8 Thomas Thrainer
  all_result = True
266 22b7f6f8 Thomas Thrainer
  ports_to_release = set()
267 5eacbcae Thomas Thrainer
  anno_disks = AnnotateDiskParams(instance, instance.disks, lu.cfg)
268 22b7f6f8 Thomas Thrainer
  for (idx, device) in enumerate(anno_disks):
269 22b7f6f8 Thomas Thrainer
    if target_node:
270 22b7f6f8 Thomas Thrainer
      edata = [(target_node, device)]
271 22b7f6f8 Thomas Thrainer
    else:
272 22b7f6f8 Thomas Thrainer
      edata = device.ComputeNodeTree(instance.primary_node)
273 22b7f6f8 Thomas Thrainer
    for node, disk in edata:
274 5831baf3 Dimitris Aragiorgis
      if lu.op.keep_disks and disk.dev_type in constants.DT_EXT:
275 5831baf3 Dimitris Aragiorgis
        continue
276 22b7f6f8 Thomas Thrainer
      lu.cfg.SetDiskID(disk, node)
277 22b7f6f8 Thomas Thrainer
      result = lu.rpc.call_blockdev_remove(node, disk)
278 22b7f6f8 Thomas Thrainer
      if result.fail_msg:
279 22b7f6f8 Thomas Thrainer
        lu.LogWarning("Could not remove disk %s on node %s,"
280 22b7f6f8 Thomas Thrainer
                      " continuing anyway: %s", idx, node, result.fail_msg)
281 22b7f6f8 Thomas Thrainer
        if not (result.offline and node != instance.primary_node):
282 22b7f6f8 Thomas Thrainer
          all_result = False
283 22b7f6f8 Thomas Thrainer
284 22b7f6f8 Thomas Thrainer
    # if this is a DRBD disk, return its port to the pool
285 22b7f6f8 Thomas Thrainer
    if device.dev_type in constants.LDS_DRBD:
286 22b7f6f8 Thomas Thrainer
      ports_to_release.add(device.logical_id[2])
287 22b7f6f8 Thomas Thrainer
288 22b7f6f8 Thomas Thrainer
  if all_result or ignore_failures:
289 22b7f6f8 Thomas Thrainer
    for port in ports_to_release:
290 22b7f6f8 Thomas Thrainer
      lu.cfg.AddTcpUdpPort(port)
291 22b7f6f8 Thomas Thrainer
292 22b7f6f8 Thomas Thrainer
  if instance.disk_template in constants.DTS_FILEBASED:
293 22b7f6f8 Thomas Thrainer
    file_storage_dir = os.path.dirname(instance.disks[0].logical_id[1])
294 22b7f6f8 Thomas Thrainer
    if target_node:
295 22b7f6f8 Thomas Thrainer
      tgt = target_node
296 22b7f6f8 Thomas Thrainer
    else:
297 22b7f6f8 Thomas Thrainer
      tgt = instance.primary_node
298 22b7f6f8 Thomas Thrainer
    result = lu.rpc.call_file_storage_dir_remove(tgt, file_storage_dir)
299 22b7f6f8 Thomas Thrainer
    if result.fail_msg:
300 22b7f6f8 Thomas Thrainer
      lu.LogWarning("Could not remove directory '%s' on node %s: %s",
301 22b7f6f8 Thomas Thrainer
                    file_storage_dir, instance.primary_node, result.fail_msg)
302 22b7f6f8 Thomas Thrainer
      all_result = False
303 22b7f6f8 Thomas Thrainer
304 22b7f6f8 Thomas Thrainer
  return all_result
305 22b7f6f8 Thomas Thrainer
306 22b7f6f8 Thomas Thrainer
307 5eacbcae Thomas Thrainer
def NICToTuple(lu, nic):
308 22b7f6f8 Thomas Thrainer
  """Build a tupple of nic information.
309 22b7f6f8 Thomas Thrainer

310 22b7f6f8 Thomas Thrainer
  @type lu:  L{LogicalUnit}
311 22b7f6f8 Thomas Thrainer
  @param lu: the logical unit on whose behalf we execute
312 22b7f6f8 Thomas Thrainer
  @type nic: L{objects.NIC}
313 22b7f6f8 Thomas Thrainer
  @param nic: nic to convert to hooks tuple
314 22b7f6f8 Thomas Thrainer

315 22b7f6f8 Thomas Thrainer
  """
316 22b7f6f8 Thomas Thrainer
  cluster = lu.cfg.GetClusterInfo()
317 22b7f6f8 Thomas Thrainer
  filled_params = cluster.SimpleFillNIC(nic.nicparams)
318 22b7f6f8 Thomas Thrainer
  mode = filled_params[constants.NIC_MODE]
319 22b7f6f8 Thomas Thrainer
  link = filled_params[constants.NIC_LINK]
320 22b7f6f8 Thomas Thrainer
  netinfo = None
321 22b7f6f8 Thomas Thrainer
  if nic.network:
322 22b7f6f8 Thomas Thrainer
    nobj = lu.cfg.GetNetwork(nic.network)
323 22b7f6f8 Thomas Thrainer
    netinfo = objects.Network.ToDict(nobj)
324 22b7f6f8 Thomas Thrainer
  return (nic.name, nic.uuid, nic.ip, nic.mac, mode, link, nic.network, netinfo)
325 22b7f6f8 Thomas Thrainer
326 22b7f6f8 Thomas Thrainer
327 5eacbcae Thomas Thrainer
def NICListToTuple(lu, nics):
328 22b7f6f8 Thomas Thrainer
  """Build a list of nic information tuples.
329 22b7f6f8 Thomas Thrainer

330 22b7f6f8 Thomas Thrainer
  This list is suitable to be passed to _BuildInstanceHookEnv or as a return
331 22b7f6f8 Thomas Thrainer
  value in LUInstanceQueryData.
332 22b7f6f8 Thomas Thrainer

333 22b7f6f8 Thomas Thrainer
  @type lu:  L{LogicalUnit}
334 22b7f6f8 Thomas Thrainer
  @param lu: the logical unit on whose behalf we execute
335 22b7f6f8 Thomas Thrainer
  @type nics: list of L{objects.NIC}
336 22b7f6f8 Thomas Thrainer
  @param nics: list of nics to convert to hooks tuples
337 22b7f6f8 Thomas Thrainer

338 22b7f6f8 Thomas Thrainer
  """
339 22b7f6f8 Thomas Thrainer
  hooks_nics = []
340 22b7f6f8 Thomas Thrainer
  for nic in nics:
341 5eacbcae Thomas Thrainer
    hooks_nics.append(NICToTuple(lu, nic))
342 22b7f6f8 Thomas Thrainer
  return hooks_nics
343 763ad5be Thomas Thrainer
344 763ad5be Thomas Thrainer
345 5eacbcae Thomas Thrainer
def CopyLockList(names):
346 763ad5be Thomas Thrainer
  """Makes a copy of a list of lock names.
347 763ad5be Thomas Thrainer

348 763ad5be Thomas Thrainer
  Handles L{locking.ALL_SET} correctly.
349 763ad5be Thomas Thrainer

350 763ad5be Thomas Thrainer
  """
351 763ad5be Thomas Thrainer
  if names == locking.ALL_SET:
352 763ad5be Thomas Thrainer
    return locking.ALL_SET
353 763ad5be Thomas Thrainer
  else:
354 763ad5be Thomas Thrainer
    return names[:]
355 763ad5be Thomas Thrainer
356 763ad5be Thomas Thrainer
357 5eacbcae Thomas Thrainer
def ReleaseLocks(lu, level, names=None, keep=None):
358 763ad5be Thomas Thrainer
  """Releases locks owned by an LU.
359 763ad5be Thomas Thrainer

360 763ad5be Thomas Thrainer
  @type lu: L{LogicalUnit}
361 763ad5be Thomas Thrainer
  @param level: Lock level
362 763ad5be Thomas Thrainer
  @type names: list or None
363 763ad5be Thomas Thrainer
  @param names: Names of locks to release
364 763ad5be Thomas Thrainer
  @type keep: list or None
365 763ad5be Thomas Thrainer
  @param keep: Names of locks to retain
366 763ad5be Thomas Thrainer

367 763ad5be Thomas Thrainer
  """
368 763ad5be Thomas Thrainer
  assert not (keep is not None and names is not None), \
369 763ad5be Thomas Thrainer
         "Only one of the 'names' and the 'keep' parameters can be given"
370 763ad5be Thomas Thrainer
371 763ad5be Thomas Thrainer
  if names is not None:
372 763ad5be Thomas Thrainer
    should_release = names.__contains__
373 763ad5be Thomas Thrainer
  elif keep:
374 763ad5be Thomas Thrainer
    should_release = lambda name: name not in keep
375 763ad5be Thomas Thrainer
  else:
376 763ad5be Thomas Thrainer
    should_release = None
377 763ad5be Thomas Thrainer
378 763ad5be Thomas Thrainer
  owned = lu.owned_locks(level)
379 763ad5be Thomas Thrainer
  if not owned:
380 763ad5be Thomas Thrainer
    # Not owning any lock at this level, do nothing
381 763ad5be Thomas Thrainer
    pass
382 763ad5be Thomas Thrainer
383 763ad5be Thomas Thrainer
  elif should_release:
384 763ad5be Thomas Thrainer
    retain = []
385 763ad5be Thomas Thrainer
    release = []
386 763ad5be Thomas Thrainer
387 763ad5be Thomas Thrainer
    # Determine which locks to release
388 763ad5be Thomas Thrainer
    for name in owned:
389 763ad5be Thomas Thrainer
      if should_release(name):
390 763ad5be Thomas Thrainer
        release.append(name)
391 763ad5be Thomas Thrainer
      else:
392 763ad5be Thomas Thrainer
        retain.append(name)
393 763ad5be Thomas Thrainer
394 763ad5be Thomas Thrainer
    assert len(lu.owned_locks(level)) == (len(retain) + len(release))
395 763ad5be Thomas Thrainer
396 763ad5be Thomas Thrainer
    # Release just some locks
397 763ad5be Thomas Thrainer
    lu.glm.release(level, names=release)
398 763ad5be Thomas Thrainer
399 763ad5be Thomas Thrainer
    assert frozenset(lu.owned_locks(level)) == frozenset(retain)
400 763ad5be Thomas Thrainer
  else:
401 763ad5be Thomas Thrainer
    # Release everything
402 763ad5be Thomas Thrainer
    lu.glm.release(level)
403 763ad5be Thomas Thrainer
404 763ad5be Thomas Thrainer
    assert not lu.glm.is_owned(level), "No locks should be owned"
405 763ad5be Thomas Thrainer
406 763ad5be Thomas Thrainer
407 763ad5be Thomas Thrainer
def _ComputeIPolicyNodeViolation(ipolicy, instance, current_group,
408 763ad5be Thomas Thrainer
                                 target_group, cfg,
409 5eacbcae Thomas Thrainer
                                 _compute_fn=ComputeIPolicyInstanceViolation):
410 763ad5be Thomas Thrainer
  """Compute if instance meets the specs of the new target group.
411 763ad5be Thomas Thrainer

412 763ad5be Thomas Thrainer
  @param ipolicy: The ipolicy to verify
413 763ad5be Thomas Thrainer
  @param instance: The instance object to verify
414 763ad5be Thomas Thrainer
  @param current_group: The current group of the instance
415 763ad5be Thomas Thrainer
  @param target_group: The new group of the instance
416 763ad5be Thomas Thrainer
  @type cfg: L{config.ConfigWriter}
417 763ad5be Thomas Thrainer
  @param cfg: Cluster configuration
418 763ad5be Thomas Thrainer
  @param _compute_fn: The function to verify ipolicy (unittest only)
419 5eacbcae Thomas Thrainer
  @see: L{ganeti.cmdlib.common.ComputeIPolicySpecViolation}
420 763ad5be Thomas Thrainer

421 763ad5be Thomas Thrainer
  """
422 763ad5be Thomas Thrainer
  if current_group == target_group:
423 763ad5be Thomas Thrainer
    return []
424 763ad5be Thomas Thrainer
  else:
425 763ad5be Thomas Thrainer
    return _compute_fn(ipolicy, instance, cfg)
426 763ad5be Thomas Thrainer
427 763ad5be Thomas Thrainer
428 5eacbcae Thomas Thrainer
def CheckTargetNodeIPolicy(lu, ipolicy, instance, node, cfg, ignore=False,
429 5eacbcae Thomas Thrainer
                           _compute_fn=_ComputeIPolicyNodeViolation):
430 763ad5be Thomas Thrainer
  """Checks that the target node is correct in terms of instance policy.
431 763ad5be Thomas Thrainer

432 763ad5be Thomas Thrainer
  @param ipolicy: The ipolicy to verify
433 763ad5be Thomas Thrainer
  @param instance: The instance object to verify
434 763ad5be Thomas Thrainer
  @param node: The new node to relocate
435 763ad5be Thomas Thrainer
  @type cfg: L{config.ConfigWriter}
436 763ad5be Thomas Thrainer
  @param cfg: Cluster configuration
437 763ad5be Thomas Thrainer
  @param ignore: Ignore violations of the ipolicy
438 763ad5be Thomas Thrainer
  @param _compute_fn: The function to verify ipolicy (unittest only)
439 5eacbcae Thomas Thrainer
  @see: L{ganeti.cmdlib.common.ComputeIPolicySpecViolation}
440 763ad5be Thomas Thrainer

441 763ad5be Thomas Thrainer
  """
442 763ad5be Thomas Thrainer
  primary_node = lu.cfg.GetNodeInfo(instance.primary_node)
443 763ad5be Thomas Thrainer
  res = _compute_fn(ipolicy, instance, primary_node.group, node.group, cfg)
444 763ad5be Thomas Thrainer
445 763ad5be Thomas Thrainer
  if res:
446 763ad5be Thomas Thrainer
    msg = ("Instance does not meet target node group's (%s) instance"
447 763ad5be Thomas Thrainer
           " policy: %s") % (node.group, utils.CommaJoin(res))
448 763ad5be Thomas Thrainer
    if ignore:
449 763ad5be Thomas Thrainer
      lu.LogWarning(msg)
450 763ad5be Thomas Thrainer
    else:
451 763ad5be Thomas Thrainer
      raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
452 763ad5be Thomas Thrainer
453 763ad5be Thomas Thrainer
454 5eacbcae Thomas Thrainer
def GetInstanceInfoText(instance):
455 763ad5be Thomas Thrainer
  """Compute that text that should be added to the disk's metadata.
456 763ad5be Thomas Thrainer

457 763ad5be Thomas Thrainer
  """
458 763ad5be Thomas Thrainer
  return "originstname+%s" % instance.name
459 87e25be1 Thomas Thrainer
460 87e25be1 Thomas Thrainer
461 5eacbcae Thomas Thrainer
def CheckNodeFreeMemory(lu, node, reason, requested, hypervisor_name):
462 87e25be1 Thomas Thrainer
  """Checks if a node has enough free memory.
463 87e25be1 Thomas Thrainer

464 87e25be1 Thomas Thrainer
  This function checks if a given node has the needed amount of free
465 87e25be1 Thomas Thrainer
  memory. In case the node has less memory or we cannot get the
466 87e25be1 Thomas Thrainer
  information from the node, this function raises an OpPrereqError
467 87e25be1 Thomas Thrainer
  exception.
468 87e25be1 Thomas Thrainer

469 87e25be1 Thomas Thrainer
  @type lu: C{LogicalUnit}
470 87e25be1 Thomas Thrainer
  @param lu: a logical unit from which we get configuration data
471 87e25be1 Thomas Thrainer
  @type node: C{str}
472 87e25be1 Thomas Thrainer
  @param node: the node to check
473 87e25be1 Thomas Thrainer
  @type reason: C{str}
474 87e25be1 Thomas Thrainer
  @param reason: string to use in the error message
475 87e25be1 Thomas Thrainer
  @type requested: C{int}
476 87e25be1 Thomas Thrainer
  @param requested: the amount of memory in MiB to check for
477 87e25be1 Thomas Thrainer
  @type hypervisor_name: C{str}
478 87e25be1 Thomas Thrainer
  @param hypervisor_name: the hypervisor to ask for memory stats
479 87e25be1 Thomas Thrainer
  @rtype: integer
480 87e25be1 Thomas Thrainer
  @return: node current free memory
481 87e25be1 Thomas Thrainer
  @raise errors.OpPrereqError: if the node doesn't have enough memory, or
482 87e25be1 Thomas Thrainer
      we cannot check the node
483 87e25be1 Thomas Thrainer

484 87e25be1 Thomas Thrainer
  """
485 87e25be1 Thomas Thrainer
  nodeinfo = lu.rpc.call_node_info([node], None, [hypervisor_name], False)
486 87e25be1 Thomas Thrainer
  nodeinfo[node].Raise("Can't get data from node %s" % node,
487 87e25be1 Thomas Thrainer
                       prereq=True, ecode=errors.ECODE_ENVIRON)
488 87e25be1 Thomas Thrainer
  (_, _, (hv_info, )) = nodeinfo[node].payload
489 87e25be1 Thomas Thrainer
490 87e25be1 Thomas Thrainer
  free_mem = hv_info.get("memory_free", None)
491 87e25be1 Thomas Thrainer
  if not isinstance(free_mem, int):
492 87e25be1 Thomas Thrainer
    raise errors.OpPrereqError("Can't compute free memory on node %s, result"
493 87e25be1 Thomas Thrainer
                               " was '%s'" % (node, free_mem),
494 87e25be1 Thomas Thrainer
                               errors.ECODE_ENVIRON)
495 87e25be1 Thomas Thrainer
  if requested > free_mem:
496 87e25be1 Thomas Thrainer
    raise errors.OpPrereqError("Not enough memory on node %s for %s:"
497 87e25be1 Thomas Thrainer
                               " needed %s MiB, available %s MiB" %
498 87e25be1 Thomas Thrainer
                               (node, reason, requested, free_mem),
499 87e25be1 Thomas Thrainer
                               errors.ECODE_NORES)
500 87e25be1 Thomas Thrainer
  return free_mem
501 87e25be1 Thomas Thrainer
502 87e25be1 Thomas Thrainer
503 5eacbcae Thomas Thrainer
def CheckInstanceBridgesExist(lu, instance, node=None):
504 87e25be1 Thomas Thrainer
  """Check that the brigdes needed by an instance exist.
505 87e25be1 Thomas Thrainer

506 87e25be1 Thomas Thrainer
  """
507 87e25be1 Thomas Thrainer
  if node is None:
508 87e25be1 Thomas Thrainer
    node = instance.primary_node
509 5eacbcae Thomas Thrainer
  CheckNicsBridgesExist(lu, instance.nics, node)
510 87e25be1 Thomas Thrainer
511 87e25be1 Thomas Thrainer
512 5eacbcae Thomas Thrainer
def CheckNicsBridgesExist(lu, target_nics, target_node):
513 87e25be1 Thomas Thrainer
  """Check that the brigdes needed by a list of nics exist.
514 87e25be1 Thomas Thrainer

515 87e25be1 Thomas Thrainer
  """
516 87e25be1 Thomas Thrainer
  cluster = lu.cfg.GetClusterInfo()
517 87e25be1 Thomas Thrainer
  paramslist = [cluster.SimpleFillNIC(nic.nicparams) for nic in target_nics]
518 87e25be1 Thomas Thrainer
  brlist = [params[constants.NIC_LINK] for params in paramslist
519 87e25be1 Thomas Thrainer
            if params[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED]
520 87e25be1 Thomas Thrainer
  if brlist:
521 87e25be1 Thomas Thrainer
    result = lu.rpc.call_bridges_exist(target_node, brlist)
522 87e25be1 Thomas Thrainer
    result.Raise("Error checking bridges on destination node '%s'" %
523 87e25be1 Thomas Thrainer
                 target_node, prereq=True, ecode=errors.ECODE_ENVIRON)
524 13f6af81 Thomas Thrainer
525 13f6af81 Thomas Thrainer
526 5eacbcae Thomas Thrainer
def CheckNodeHasOS(lu, node, os_name, force_variant):
527 13f6af81 Thomas Thrainer
  """Ensure that a node supports a given OS.
528 13f6af81 Thomas Thrainer

529 13f6af81 Thomas Thrainer
  @param lu: the LU on behalf of which we make the check
530 13f6af81 Thomas Thrainer
  @param node: the node to check
531 13f6af81 Thomas Thrainer
  @param os_name: the OS to query about
532 13f6af81 Thomas Thrainer
  @param force_variant: whether to ignore variant errors
533 13f6af81 Thomas Thrainer
  @raise errors.OpPrereqError: if the node is not supporting the OS
534 13f6af81 Thomas Thrainer

535 13f6af81 Thomas Thrainer
  """
536 13f6af81 Thomas Thrainer
  result = lu.rpc.call_os_get(node, os_name)
537 13f6af81 Thomas Thrainer
  result.Raise("OS '%s' not in supported OS list for node %s" %
538 13f6af81 Thomas Thrainer
               (os_name, node),
539 13f6af81 Thomas Thrainer
               prereq=True, ecode=errors.ECODE_INVAL)
540 13f6af81 Thomas Thrainer
  if not force_variant:
541 13f6af81 Thomas Thrainer
    _CheckOSVariant(result.payload, os_name)
542 13f6af81 Thomas Thrainer
543 13f6af81 Thomas Thrainer
544 13f6af81 Thomas Thrainer
def _CheckOSVariant(os_obj, name):
545 13f6af81 Thomas Thrainer
  """Check whether an OS name conforms to the os variants specification.
546 13f6af81 Thomas Thrainer

547 13f6af81 Thomas Thrainer
  @type os_obj: L{objects.OS}
548 13f6af81 Thomas Thrainer
  @param os_obj: OS object to check
549 13f6af81 Thomas Thrainer
  @type name: string
550 13f6af81 Thomas Thrainer
  @param name: OS name passed by the user, to check for validity
551 13f6af81 Thomas Thrainer

552 13f6af81 Thomas Thrainer
  """
553 13f6af81 Thomas Thrainer
  variant = objects.OS.GetVariant(name)
554 13f6af81 Thomas Thrainer
  if not os_obj.supported_variants:
555 13f6af81 Thomas Thrainer
    if variant:
556 13f6af81 Thomas Thrainer
      raise errors.OpPrereqError("OS '%s' doesn't support variants ('%s'"
557 13f6af81 Thomas Thrainer
                                 " passed)" % (os_obj.name, variant),
558 13f6af81 Thomas Thrainer
                                 errors.ECODE_INVAL)
559 13f6af81 Thomas Thrainer
    return
560 13f6af81 Thomas Thrainer
  if not variant:
561 13f6af81 Thomas Thrainer
    raise errors.OpPrereqError("OS name must include a variant",
562 13f6af81 Thomas Thrainer
                               errors.ECODE_INVAL)
563 13f6af81 Thomas Thrainer
564 13f6af81 Thomas Thrainer
  if variant not in os_obj.supported_variants:
565 13f6af81 Thomas Thrainer
    raise errors.OpPrereqError("Unsupported OS variant", errors.ECODE_INVAL)
566 18aa65d1 Dimitris Aragiorgis
567 18aa65d1 Dimitris Aragiorgis
568 18aa65d1 Dimitris Aragiorgis
def BuildDiskLogicalIDEnv(template_name, idx, disk):
569 18aa65d1 Dimitris Aragiorgis
  if template_name == constants.DT_PLAIN:
570 18aa65d1 Dimitris Aragiorgis
    vg, name = disk.logical_id
571 18aa65d1 Dimitris Aragiorgis
    ret = {
572 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_VG" % idx : vg,
573 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_ID" % idx : name
574 18aa65d1 Dimitris Aragiorgis
      }
575 18aa65d1 Dimitris Aragiorgis
  elif template_name in (constants.DT_FILE, constants.DT_SHARED_FILE):
576 18aa65d1 Dimitris Aragiorgis
    file_driver, name = disk.logical_id
577 18aa65d1 Dimitris Aragiorgis
    ret = {
578 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_DRIVER" % idx : file_driver,
579 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_ID" % idx : name
580 18aa65d1 Dimitris Aragiorgis
      }
581 18aa65d1 Dimitris Aragiorgis
  elif template_name == constants.DT_BLOCK:
582 18aa65d1 Dimitris Aragiorgis
    block_driver, adopt = disk.logical_id
583 18aa65d1 Dimitris Aragiorgis
    ret = {
584 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_DRIVER" % idx : block_driver,
585 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_ID" % idx : adopt
586 18aa65d1 Dimitris Aragiorgis
      }
587 18aa65d1 Dimitris Aragiorgis
  elif template_name == constants.DT_RBD:
588 18aa65d1 Dimitris Aragiorgis
    rbd, name = disk.logical_id
589 18aa65d1 Dimitris Aragiorgis
    ret = {
590 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_DRIVER" % idx : rbd,
591 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_ID" % idx : name
592 18aa65d1 Dimitris Aragiorgis
      }
593 18aa65d1 Dimitris Aragiorgis
  elif template_name == constants.DT_EXT:
594 18aa65d1 Dimitris Aragiorgis
    provider, name = disk.logical_id
595 18aa65d1 Dimitris Aragiorgis
    ret = {
596 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_PROVIDER" % idx : provider,
597 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_ID" % idx : name
598 18aa65d1 Dimitris Aragiorgis
      }
599 18aa65d1 Dimitris Aragiorgis
  elif template_name == constants.DT_DRBD8:
600 18aa65d1 Dimitris Aragiorgis
    pnode, snode, port, pmin, smin, _ = disk.logical_id
601 18aa65d1 Dimitris Aragiorgis
    data, meta = disk.children
602 18aa65d1 Dimitris Aragiorgis
    data_vg, data_name = data.logical_id
603 18aa65d1 Dimitris Aragiorgis
    meta_vg, meta_name = meta.logical_id
604 18aa65d1 Dimitris Aragiorgis
    ret = {
605 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_PNODE" % idx : pnode,
606 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_SNODE" % idx : snode,
607 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_PORT" % idx : port,
608 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_PMINOR" % idx : pmin,
609 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_SMINOR" % idx : smin,
610 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_DATA_VG" % idx : data_vg,
611 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_DATA_ID" % idx : data_name,
612 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_META_VG" % idx : meta_vg,
613 18aa65d1 Dimitris Aragiorgis
      "INSTANCE_DISK%d_META_ID" % idx : meta_name,
614 18aa65d1 Dimitris Aragiorgis
      }
615 18aa65d1 Dimitris Aragiorgis
  elif template_name == constants.DT_DISKLESS:
616 18aa65d1 Dimitris Aragiorgis
    ret = {}
617 18aa65d1 Dimitris Aragiorgis
618 18aa65d1 Dimitris Aragiorgis
  ret.update({
619 18aa65d1 Dimitris Aragiorgis
    "INSTANCE_DISK%d_TEMPLATE_NAME" % idx: template_name
620 18aa65d1 Dimitris Aragiorgis
    })
621 18aa65d1 Dimitris Aragiorgis
622 18aa65d1 Dimitris Aragiorgis
  return ret