root / qa / qa_instance_utils.py @ 31d3b918
History | View | Annotate | Download (6.7 kB)
1 | 8fada090 | Michele Tartara | #
|
---|---|---|---|
2 | 8fada090 | Michele Tartara | #
|
3 | 8fada090 | Michele Tartara | |
4 | 8fada090 | Michele Tartara | # Copyright (C) 2013 Google Inc.
|
5 | 8fada090 | Michele Tartara | #
|
6 | 8fada090 | Michele Tartara | # This program is free software; you can redistribute it and/or modify
|
7 | 8fada090 | Michele Tartara | # it under the terms of the GNU General Public License as published by
|
8 | 8fada090 | Michele Tartara | # the Free Software Foundation; either version 2 of the License, or
|
9 | 8fada090 | Michele Tartara | # (at your option) any later version.
|
10 | 8fada090 | Michele Tartara | #
|
11 | 8fada090 | Michele Tartara | # This program is distributed in the hope that it will be useful, but
|
12 | 8fada090 | Michele Tartara | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 8fada090 | Michele Tartara | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 8fada090 | Michele Tartara | # General Public License for more details.
|
15 | 8fada090 | Michele Tartara | #
|
16 | 8fada090 | Michele Tartara | # You should have received a copy of the GNU General Public License
|
17 | 8fada090 | Michele Tartara | # along with this program; if not, write to the Free Software
|
18 | 8fada090 | Michele Tartara | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 8fada090 | Michele Tartara | # 02110-1301, USA.
|
20 | 8fada090 | Michele Tartara | |
21 | 8fada090 | Michele Tartara | |
22 | 8fada090 | Michele Tartara | """QA utility functions for managing instances
|
23 | 8fada090 | Michele Tartara |
|
24 | 8fada090 | Michele Tartara | """
|
25 | 8fada090 | Michele Tartara | |
26 | 8fada090 | Michele Tartara | import operator |
27 | 8fada090 | Michele Tartara | |
28 | 8fada090 | Michele Tartara | from ganeti import utils |
29 | 8fada090 | Michele Tartara | from ganeti import constants |
30 | 8fada090 | Michele Tartara | from ganeti import pathutils |
31 | 8fada090 | Michele Tartara | |
32 | 8fada090 | Michele Tartara | import qa_config |
33 | 345d395d | Bernardo Dal Seno | import qa_error |
34 | 8fada090 | Michele Tartara | import qa_utils |
35 | 8fada090 | Michele Tartara | |
36 | 8fada090 | Michele Tartara | from qa_utils import AssertIn, AssertCommand |
37 | 8fada090 | Michele Tartara | |
38 | 8fada090 | Michele Tartara | |
39 | 8fada090 | Michele Tartara | def RemoveInstance(instance): |
40 | 8fada090 | Michele Tartara | AssertCommand(["gnt-instance", "remove", "-f", instance.name]) |
41 | 8fada090 | Michele Tartara | |
42 | 8fada090 | Michele Tartara | |
43 | 8fada090 | Michele Tartara | def GetGenericAddParameters(inst, disk_template, force_mac=None): |
44 | 8fada090 | Michele Tartara | params = ["-B"]
|
45 | 8fada090 | Michele Tartara | params.append("%s=%s,%s=%s" % (constants.BE_MINMEM,
|
46 | 8fada090 | Michele Tartara | qa_config.get(constants.BE_MINMEM), |
47 | 8fada090 | Michele Tartara | constants.BE_MAXMEM, |
48 | 8fada090 | Michele Tartara | qa_config.get(constants.BE_MAXMEM))) |
49 | 8fada090 | Michele Tartara | |
50 | 8fada090 | Michele Tartara | if disk_template != constants.DT_DISKLESS:
|
51 | 8fada090 | Michele Tartara | for idx, disk in enumerate(qa_config.GetDiskOptions()): |
52 | 8fada090 | Michele Tartara | size = disk.get("size")
|
53 | 8fada090 | Michele Tartara | name = disk.get("name")
|
54 | 8fada090 | Michele Tartara | diskparams = "%s:size=%s" % (idx, size)
|
55 | 8fada090 | Michele Tartara | if name:
|
56 | 8fada090 | Michele Tartara | diskparams += ",name=%s" % name
|
57 | 345d395d | Bernardo Dal Seno | if qa_config.AreSpindlesSupported():
|
58 | 345d395d | Bernardo Dal Seno | spindles = disk.get("spindles")
|
59 | 345d395d | Bernardo Dal Seno | if spindles is None: |
60 | 95155a8c | Bernardo Dal Seno | raise qa_error.Error("'spindles' is a required parameter for disks" |
61 | 95155a8c | Bernardo Dal Seno | " when you enable exclusive storage tests")
|
62 | 345d395d | Bernardo Dal Seno | diskparams += ",spindles=%s" % spindles
|
63 | 8fada090 | Michele Tartara | params.extend(["--disk", diskparams])
|
64 | 8fada090 | Michele Tartara | |
65 | 8fada090 | Michele Tartara | # Set static MAC address if configured
|
66 | 8fada090 | Michele Tartara | if force_mac:
|
67 | 8fada090 | Michele Tartara | nic0_mac = force_mac |
68 | 8fada090 | Michele Tartara | else:
|
69 | 8fada090 | Michele Tartara | nic0_mac = inst.GetNicMacAddr(0, None) |
70 | 8fada090 | Michele Tartara | |
71 | 8fada090 | Michele Tartara | if nic0_mac:
|
72 | 8fada090 | Michele Tartara | params.extend(["--net", "0:mac=%s" % nic0_mac]) |
73 | 8fada090 | Michele Tartara | |
74 | 8fada090 | Michele Tartara | return params
|
75 | 8fada090 | Michele Tartara | |
76 | 8fada090 | Michele Tartara | |
77 | 8fada090 | Michele Tartara | def _CreateInstanceByDiskTemplateRaw(nodes_spec, disk_template, fail=False): |
78 | 8fada090 | Michele Tartara | """Creates an instance with the given disk template on the given nodes(s).
|
79 | 8fada090 | Michele Tartara | Note that this function does not check if enough nodes are given for
|
80 | 8fada090 | Michele Tartara | the respective disk template.
|
81 | 8fada090 | Michele Tartara |
|
82 | 8fada090 | Michele Tartara | @type nodes_spec: string
|
83 | 8fada090 | Michele Tartara | @param nodes_spec: string specification of one node (by node name) or several
|
84 | 8fada090 | Michele Tartara | nodes according to the requirements of the disk template
|
85 | 8fada090 | Michele Tartara | @type disk_template: string
|
86 | 8fada090 | Michele Tartara | @param disk_template: the disk template to be used by the instance
|
87 | 8fada090 | Michele Tartara | @return: the created instance
|
88 | 8fada090 | Michele Tartara |
|
89 | 8fada090 | Michele Tartara | """
|
90 | 8fada090 | Michele Tartara | instance = qa_config.AcquireInstance() |
91 | 8fada090 | Michele Tartara | try:
|
92 | 8fada090 | Michele Tartara | cmd = (["gnt-instance", "add", |
93 | 8fada090 | Michele Tartara | "--os-type=%s" % qa_config.get("os"), |
94 | 8fada090 | Michele Tartara | "--disk-template=%s" % disk_template,
|
95 | 8fada090 | Michele Tartara | "--node=%s" % nodes_spec] +
|
96 | 8fada090 | Michele Tartara | GetGenericAddParameters(instance, disk_template)) |
97 | 8fada090 | Michele Tartara | cmd.append(instance.name) |
98 | 8fada090 | Michele Tartara | |
99 | 8fada090 | Michele Tartara | AssertCommand(cmd, fail=fail) |
100 | 8fada090 | Michele Tartara | |
101 | 8fada090 | Michele Tartara | if not fail: |
102 | 8fada090 | Michele Tartara | CheckSsconfInstanceList(instance.name) |
103 | 8fada090 | Michele Tartara | instance.SetDiskTemplate(disk_template) |
104 | 8fada090 | Michele Tartara | |
105 | 8fada090 | Michele Tartara | return instance
|
106 | 8fada090 | Michele Tartara | except:
|
107 | 8fada090 | Michele Tartara | instance.Release() |
108 | 8fada090 | Michele Tartara | raise
|
109 | 8fada090 | Michele Tartara | |
110 | 8fada090 | Michele Tartara | # Handle the case where creation is expected to fail
|
111 | 8fada090 | Michele Tartara | assert fail
|
112 | 8fada090 | Michele Tartara | instance.Release() |
113 | 8fada090 | Michele Tartara | return None |
114 | 8fada090 | Michele Tartara | |
115 | 8fada090 | Michele Tartara | |
116 | 8fada090 | Michele Tartara | def CreateInstanceDrbd8(nodes, fail=False): |
117 | 8fada090 | Michele Tartara | """Creates an instance using disk template 'drbd' on the given nodes.
|
118 | 8fada090 | Michele Tartara |
|
119 | 8fada090 | Michele Tartara | @type nodes: list of nodes
|
120 | 8fada090 | Michele Tartara | @param nodes: nodes to be used by the instance
|
121 | 8fada090 | Michele Tartara | @return: the created instance
|
122 | 8fada090 | Michele Tartara |
|
123 | 8fada090 | Michele Tartara | """
|
124 | 8fada090 | Michele Tartara | assert len(nodes) > 1 |
125 | 8fada090 | Michele Tartara | return _CreateInstanceByDiskTemplateRaw(
|
126 | 8fada090 | Michele Tartara | ":".join(map(operator.attrgetter("primary"), nodes)), |
127 | 8fada090 | Michele Tartara | constants.DT_DRBD8, fail=fail) |
128 | 8fada090 | Michele Tartara | |
129 | 8fada090 | Michele Tartara | |
130 | 8fada090 | Michele Tartara | def CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=False): |
131 | 8fada090 | Michele Tartara | """Creates an instance using the given disk template for disk templates
|
132 | 8fada090 | Michele Tartara | for which one given node is sufficient. These templates are for example:
|
133 | 8fada090 | Michele Tartara | plain, diskless, file, sharedfile, blockdev, rados.
|
134 | 8fada090 | Michele Tartara |
|
135 | 8fada090 | Michele Tartara | @type nodes: list of nodes
|
136 | 8fada090 | Michele Tartara | @param nodes: a list of nodes, whose first element is used to create the
|
137 | 8fada090 | Michele Tartara | instance
|
138 | 8fada090 | Michele Tartara | @type disk_template: string
|
139 | 8fada090 | Michele Tartara | @param disk_template: the disk template to be used by the instance
|
140 | 8fada090 | Michele Tartara | @return: the created instance
|
141 | 8fada090 | Michele Tartara |
|
142 | 8fada090 | Michele Tartara | """
|
143 | 8fada090 | Michele Tartara | assert len(nodes) > 0 |
144 | 8fada090 | Michele Tartara | return _CreateInstanceByDiskTemplateRaw(nodes[0].primary, disk_template, |
145 | 8fada090 | Michele Tartara | fail=fail) |
146 | 8fada090 | Michele Tartara | |
147 | 8fada090 | Michele Tartara | |
148 | 8fada090 | Michele Tartara | def CreateInstanceByDiskTemplate(nodes, disk_template, fail=False): |
149 | 8fada090 | Michele Tartara | """Given a disk template, this function creates an instance using
|
150 | 8fada090 | Michele Tartara | the template. It uses the required number of nodes depending on
|
151 | 8fada090 | Michele Tartara | the disk template. This function is intended to be used by tests
|
152 | 8fada090 | Michele Tartara | that don't care about the specifics of the instance other than
|
153 | 8fada090 | Michele Tartara | that it uses the given disk template.
|
154 | 8fada090 | Michele Tartara |
|
155 | 8fada090 | Michele Tartara | Note: If you use this function, make sure to call
|
156 | 8fada090 | Michele Tartara | 'TestInstanceRemove' at the end of your tests to avoid orphaned
|
157 | 8fada090 | Michele Tartara | instances hanging around and interfering with the following tests.
|
158 | 8fada090 | Michele Tartara |
|
159 | 8fada090 | Michele Tartara | @type nodes: list of nodes
|
160 | 8fada090 | Michele Tartara | @param nodes: the list of the nodes on which the instance will be placed;
|
161 | 8fada090 | Michele Tartara | it needs to have sufficiently many elements for the given
|
162 | 8fada090 | Michele Tartara | disk template
|
163 | 8fada090 | Michele Tartara | @type disk_template: string
|
164 | 8fada090 | Michele Tartara | @param disk_template: the disk template to be used by the instance
|
165 | 8fada090 | Michele Tartara | @return: the created instance
|
166 | 8fada090 | Michele Tartara |
|
167 | 8fada090 | Michele Tartara | """
|
168 | 8fada090 | Michele Tartara | if disk_template == constants.DT_DRBD8:
|
169 | 8fada090 | Michele Tartara | return CreateInstanceDrbd8(nodes, fail=fail)
|
170 | 8fada090 | Michele Tartara | elif disk_template in [constants.DT_DISKLESS, constants.DT_PLAIN, |
171 | 8fada090 | Michele Tartara | constants.DT_FILE]: |
172 | 8fada090 | Michele Tartara | return CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=fail)
|
173 | 8fada090 | Michele Tartara | else:
|
174 | 8fada090 | Michele Tartara | # FIXME: This assumes that for all other disk templates, we only need one
|
175 | 8fada090 | Michele Tartara | # node and no disk template specific parameters. This else-branch is
|
176 | 8fada090 | Michele Tartara | # currently only used in cases where we expect failure. Extend it when
|
177 | 8fada090 | Michele Tartara | # QA needs for these templates change.
|
178 | 8fada090 | Michele Tartara | return CreateInstanceByDiskTemplateOneNode(nodes, disk_template, fail=fail)
|
179 | 8fada090 | Michele Tartara | |
180 | 8fada090 | Michele Tartara | |
181 | 8fada090 | Michele Tartara | def _ReadSsconfInstanceList(): |
182 | 8fada090 | Michele Tartara | """Reads ssconf_instance_list from the master node.
|
183 | 8fada090 | Michele Tartara |
|
184 | 8fada090 | Michele Tartara | """
|
185 | 8fada090 | Michele Tartara | master = qa_config.GetMasterNode() |
186 | 8fada090 | Michele Tartara | |
187 | 8fada090 | Michele Tartara | ssconf_path = utils.PathJoin(pathutils.DATA_DIR, |
188 | 8fada090 | Michele Tartara | "ssconf_%s" % constants.SS_INSTANCE_LIST)
|
189 | 8fada090 | Michele Tartara | |
190 | 8fada090 | Michele Tartara | cmd = ["cat", qa_utils.MakeNodePath(master, ssconf_path)]
|
191 | 8fada090 | Michele Tartara | |
192 | 8fada090 | Michele Tartara | return qa_utils.GetCommandOutput(master.primary,
|
193 | 8fada090 | Michele Tartara | utils.ShellQuoteArgs(cmd)).splitlines() |
194 | 8fada090 | Michele Tartara | |
195 | 8fada090 | Michele Tartara | |
196 | 8fada090 | Michele Tartara | def CheckSsconfInstanceList(instance): |
197 | 8fada090 | Michele Tartara | """Checks if a certain instance is in the ssconf instance list.
|
198 | 8fada090 | Michele Tartara |
|
199 | 8fada090 | Michele Tartara | @type instance: string
|
200 | 8fada090 | Michele Tartara | @param instance: Instance name
|
201 | 8fada090 | Michele Tartara |
|
202 | 8fada090 | Michele Tartara | """
|
203 | 8fada090 | Michele Tartara | AssertIn(qa_utils.ResolveInstanceName(instance), |
204 | 8fada090 | Michele Tartara | _ReadSsconfInstanceList()) |