blob: 3210e5deaa51df4fcbe242f4c1c54948a8642979 [file] [log] [blame]
Ondrej Smolab57a23b2018-01-24 11:18:24 +01001
2import logging
3from salt.exceptions import CommandExecutionError, SaltInvocationError
4
5LOG = logging.getLogger(__name__)
6
7SIZE = {
8 "M": 1000000,
9 "G": 1000000000,
10 "T": 1000000000000,
11}
12
13RAID = {
14 0: "raid-0",
15 1: "raid-1",
16 5: "raid-5",
17 10: "raid-10",
18}
19
20def __virtual__():
21 '''
22 Load MaaSng module
23 '''
24 return 'maasng'
25
26def disk_layout_present(hostname, layout_type, root_size=None, root_device=None, volume_group=None, volume_name=None, volume_size=None, disk={} , **kwargs):
27 '''
28 Ensure that the disk layout does exist
29
30 :param name: The name of the cloud that should not exist
31 '''
32 ret = {'name': hostname,
33 'changes': {},
34 'result': True,
35 'comment': 'Disk layout "{0}" updated'.format(hostname)}
36
37 machine = __salt__['maasng.get_machine'](hostname)
38 if "error" in machine:
39 ret['comment'] = "State execution failed for machine {0}".format(hostname)
40 ret['result'] = False
41 ret['changes'] = machine
42 return ret
43
44 if machine["status_name"] != "Ready":
45 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
46 return ret
47
48 if __opts__['test']:
49 ret['result'] = None
50 ret['comment'] = 'Disk layout will be updated on {0}, this action will delete current layout.'.format(hostname)
51 return ret
52
53 if layout_type == "flat":
54
55 ret["changes"] = __salt__['maasng.update_disk_layout'](hostname, layout_type, root_size, root_device)
56
57 elif layout_type == "lvm":
58
59 ret["changes"] = __salt__['maasng.update_disk_layout'](hostname, layout_type, root_size, root_device, volume_group, volume_name, volume_size)
60
61 else:
62 ret["comment"] = "Not supported layout provided. Choose flat or lvm"
63 ret['result'] = False
64
65 return ret
66
67def raid_present(hostname, name, level, devices=[], partitions=[], partition_schema={}):
68 '''
69 Ensure that the raid does exist
70
71 :param name: The name of the cloud that should not exist
72 '''
73
74 ret = {'name': name,
75 'changes': {},
76 'result': True,
77 'comment': 'Raid {0} presented on {1}'.format(name, hostname)}
78
79 machine = __salt__['maasng.get_machine'](hostname)
80 if "error" in machine:
81 ret['comment'] = "State execution failed for machine {0}".format(hostname)
82 ret['result'] = False
83 ret['changes'] = machine
84 return ret
85
86 if machine["status_name"] != "Ready":
87 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
88 return ret
89
90 if __opts__['test']:
91 ret['result'] = None
92 ret['comment'] = 'Raid {0} will be updated on {1}'.format(name,hostname)
93 return ret
94
95 #Validate that raid exists
96 ##With correct devices/partition
97 #OR
98 ##Create raid
99
100 ret["changes"] = __salt__['maasng.create_raid'](hostname=hostname, name=name, level=level, disks=devices, partitions=partitions)
101
102 #TODO partitions
103 ret["changes"].update(disk_partition_present(hostname, name, partition_schema)["changes"])
104
105 if "error" in ret["changes"]:
106 ret["result"] = False
107
108 return ret
109
110
111def disk_partition_present(hostname, disk, partition_schema={}):
112 '''
113 Ensure that the disk has correct partititioning schema
114
115 :param name: The name of the cloud that should not exist
116 '''
117
118 #1. Validate that disk has correct values for size and mount
119 #a. validate count of partitions
120 #b. validate size of partitions
121 #2. If not delete all partitions on disk and recreate schema
Ondrej Smola47b56752018-03-06 15:38:27 +0100122 #3. Validate type exists
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100123 #if should not exits
124 #delete mount and unformat
125 #4. Validate mount exists
126 #5. if not enforce umount or mount
127
128 ret = {'name': hostname,
129 'changes': {},
130 'result': True,
131 'comment': 'Disk layout {0} presented'.format(disk)}
132
133 machine = __salt__['maasng.get_machine'](hostname)
134 if "error" in machine:
135 ret['comment'] = "State execution failed for machine {0}".format(hostname)
136 ret['result'] = False
137 ret['changes'] = machine
138 return ret
139
140 if machine["status_name"] != "Ready":
141 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
142 return ret
143
144 if __opts__['test']:
145 ret['result'] = None
146 ret['comment'] = 'Partition schema will be changed on {0}'.format(disk)
147 return ret
148
149 partitions = __salt__['maasng.list_partitions'](hostname, disk)
150
151 ##Calculate actual size in bytes from provided data
152 for part_name, part in partition_schema.iteritems():
153 size, unit = part["size"][:-1], part["size"][-1]
154 part["calc_size"] = int(size) * SIZE[unit]
155
156 if len(partitions) == len(partition_schema):
157
158 for part_name, part in partition_schema.iteritems():
159 LOG.info('validated {0}'.format(part["calc_size"]))
160 LOG.info('validated {0}'.format(int(partitions[disk+"-"+part_name.split("-")[-1]]["size"])))
161 if part["calc_size"] == int(partitions[disk+"-"+part_name.split("-")[-1]]["size"]):
162 LOG.info('validated')
163 #TODO validate size (size from maas is not same as calculate?)
164 #TODO validate mount
165 #TODO validate fs type
166 else:
167 LOG.info('breaking')
168 break
169 return ret
170
171 #DELETE and RECREATE
172 LOG.info('delete')
173 for partition_name, partition in partitions.iteritems():
174 LOG.info(partition)
175 ##TODO IF LVM create ERROR
176 ret["changes"] = __salt__['maasng.delete_partition_by_id'](hostname, disk, partition["id"])
177
178 LOG.info('recreating')
179 for part_name, part in partition_schema.iteritems():
180 LOG.info("partitition for creation")
181 LOG.info(part)
182 if "mount" not in part:
183 part["mount"] = None
184 if "type" not in part:
185 part["type"] = None
186 ret["changes"] = __salt__['maasng.create_partition'](hostname, disk, part["size"], part["type"], part["mount"])
187
188 if "error" in ret["changes"]:
189 ret["result"] = False
190
191 return ret
192
193def volume_group_present(hostname, name, devices=[], partitions=[]):
194 '''
195 Ensure that the disk layout does exist
196
197 :param name: The name of the cloud that should not exist
198 '''
199 ret = {'name': hostname,
200 'changes': {},
201 'result': True,
202 'comment': 'LVM group {0} presented on {1}'.format(name,hostname)}
203
204 machine = __salt__['maasng.get_machine'](hostname)
205 if "error" in machine:
206 ret['comment'] = "State execution failed for machine {0}".format(hostname)
207 ret['result'] = False
208 ret['changes'] = machine
209 return ret
210
211 if machine["status_name"] != "Ready":
212 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
213 return ret
214
215 #TODO validation if exists
216 vgs = __salt__['maasng.list_volume_groups'](hostname)
217
218 if name in vgs:
219 #TODO validation for devices and partitions
220 return ret
221
222 if __opts__['test']:
223 ret['result'] = None
224 ret['comment'] = 'LVM group {0} will be updated on {1}'.format(name,hostname)
225 return ret
226
227 ret["changes"] = __salt__['maasng.create_volume_group'](hostname, name, devices, partitions)
228
229 if "error" in ret["changes"]:
230 ret["result"] = False
231
232 return ret
233
Ondrej Smola47b56752018-03-06 15:38:27 +0100234def volume_present(hostname, name, volume_group_name, size, type=None, mount=None):
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100235 '''
236 Ensure that the disk layout does exist
237
238 :param name: The name of the cloud that should not exist
239 '''
240
241 ret = {'name': hostname,
242 'changes': {},
243 'result': True,
244 'comment': 'LVM group {0} presented on {1}'.format(name,hostname)}
245
246 machine = __salt__['maasng.get_machine'](hostname)
247 if "error" in machine:
248 ret['comment'] = "State execution failed for machine {0}".format(hostname)
249 ret['result'] = False
250 ret['changes'] = machine
251 return ret
252
253 if machine["status_name"] != "Ready":
254 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
255 return ret
256
257 if __opts__['test']:
258 ret['result'] = None
259 ret['comment'] = 'LVM volume {0} will be updated on {1}'.format(name,hostname)
260
261 #TODO validation if exists
262
Ondrej Smola47b56752018-03-06 15:38:27 +0100263 ret["changes"] = __salt__['maasng.create_volume'](hostname, name, volume_group_name, size, type, mount)
Ondrej Smolab57a23b2018-01-24 11:18:24 +0100264
265 return ret
266
267
268def select_boot_disk(hostname, name):
269 '''
270 Select disk that will be used to boot partition
271
272 :param name: The name of disk on machine
273 :param hostname: The hostname of machine
274 '''
275
276 ret = {'name': hostname,
277 'changes': {},
278 'result': True,
279 'comment': 'LVM group {0} presented on {1}'.format(name,hostname)}
280
281 machine = __salt__['maasng.get_machine'](hostname)
282 if "error" in machine:
283 ret['comment'] = "State execution failed for machine {0}".format(hostname)
284 ret['result'] = False
285 ret['changes'] = machine
286 return ret
287
288 if machine["status_name"] != "Ready":
289 ret['comment'] = 'Machine {0} is not in Ready state.'.format(hostname)
290 return ret
291
292 if __opts__['test']:
293 ret['result'] = None
294 ret['comment'] = 'LVM volume {0} will be updated on {1}'.format(name,hostname)
295
296 #TODO disk validation if exists
297
298 ret["changes"] = __salt__['maasng.set_boot_disk'](hostname, name)
299
300 return ret