Skip to content

Commit 09c5b81

Browse files
author
Matteo Cerutti
committed
cleaned create_ld and remove_ld interface.
1 parent 267ce4c commit 09c5b81

File tree

1 file changed

+108
-18
lines changed

1 file changed

+108
-18
lines changed

megacli/__init__.py

Lines changed: 108 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def __init__(self, cli_path = '/opt/MegaRAID/MegaCli/MegaCli64'):
2020
raise RuntimeError('{0} not found'.format(cli_path))
2121

2222
def execute(self, cmd):
23-
proc = subprocess.Popen("{0} {1}".format(self.cli_path, cmd), shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
23+
proc = subprocess.Popen("{0} {1} -NoLog".format(self.cli_path, cmd), shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
2424
out, err = proc.communicate()
2525
if isinstance(out, bytes):
2626
out = out.decode()
@@ -317,29 +317,119 @@ def adapters(self):
317317

318318
return ret
319319

320-
def createld(self, raidlevel, devices, adapter, otherargs = ''):
321-
#devices should be an array of strings, ['enclosure_id:device_id']
322-
#adapter should be a number (will be cast to string)
323-
#otherargs should be general MegaCli arguments such as WT, NORA, Direct, etc. example: 'WT RA CachedBadBBU'
324-
pds = '['
320+
def create_ld(self, raid_level, devices, adapter, write_policy = None, read_policy = None, cache_policy = None, cached_bad_bbu = None, size = None, stripe_size = None, hot_spares = [], after_ld = None, force = False):
321+
"""
322+
Create a new logical drive
323+
@param raid_level: type string, specifies the RAID level. Valid arguments: 0, 1, 5 or 6.
324+
@param devices: type list, specifies the drive enclosures and slot numbers to construct the drive group. E.g.: ['E0:S1', E1:S1, ..]
325+
@param write_policy: type string, specifies the device write policy. Valid arguments: WT (write through) or WB (write back)
326+
@param read_policy: type string, specifies the device read policy. Valid arguments: NORA (no read ahead), RA (read ahead), ADRA (adaptive read ahead).
327+
@param cache_policy: type string, specifies the device cache policy. Valid arguments: Direct, Cached.
328+
@param cached_bad_bbu: type bool, specifies whether to use write cache when BBU is bad.
329+
@param size: type int, specifies the capacity for the virtual drive in MB.
330+
@param stripe_size: type int, specifies the stripe size. Valid arguments: 8, 16, 32, 64, 128, 256, 512, or 1024.
331+
@param hot_spares: type list, specifies the device hot spares. E.g.: ['E5:S5', ..]
332+
@param after_ld: type string, specifies which free slot should be used.
333+
@param force: type bool, whether to force or not the creation of the logical device
334+
"""
335+
cmd = []
336+
337+
if isinstance(raid_level, int):
338+
if raid_level not in [0, 1, 5, 6]:
339+
raise ValueError("Logical drive's RAID level must be one of 0, 1, 5 or 6")
340+
else:
341+
raise ValueError("Logical drive's RAID level must be type int")
325342

326-
for device in devices:
327-
pds = pds + device + ','
343+
if not isinstance(devices, list):
344+
raise ValueError("Logical drive's devices must be type list")
328345

329-
pds = pds[:-1] + ']'
346+
cmd.append("-R{0}[{1}]".format(raid_level, ','.join(devices)))
330347

331-
data = self.execute("-CfgLDAdd -R" + str(raidlevel) + " " + pds + " " + otherargs + " -a" + str(adapter))
348+
if isinstance(adapter, int):
349+
cmd.append('-a{0}'.format(adapter))
350+
else:
351+
raise ValueError("Logical drive's adapter ID must be type int")
352+
353+
if write_policy:
354+
if write_policy not in ['WT', 'WB']:
355+
raise ValueError("Logical drive's write policy must be either WT (write through) or WB (write back)")
356+
else:
357+
cmd.append(write_policy)
358+
359+
if read_policy:
360+
if read_policy not in ['NORA', 'RA', 'ADRA']:
361+
raise ValueError("Logical drive's read policy must be one of NORA (no read ahead), RA (read ahead) or ADRA (adaptive read ahead)")
362+
else:
363+
cmd.append(read_policy)
364+
365+
if cache_policy:
366+
if cache_policy not in ['Direct', 'Cached']:
367+
raise ValueError("Logical drive's cache policy can be either Direct or Cached")
368+
else:
369+
cmd.append(cache_policy)
370+
371+
if cached_bad_bbu is not None:
372+
if isinstance(cached_bad_bbu, bool):
373+
if cached_bad_bbu:
374+
cmd.append('CachedBadBBU')
375+
else:
376+
cmd.append('NoCachedBadBBU')
377+
else:
378+
raise ValueError("Logical drive's cached bad bbu flag must be type bool")
379+
380+
if size:
381+
if isinstance(size, int):
382+
cmd.append("-sz{0}".format(size))
383+
else:
384+
raise ValueError("Logical drive's size must be type int")
385+
386+
if stripe_size:
387+
if isinstance(stripe_size, int):
388+
if stripe_size in [8, 16, 32, 64, 128, 256, 512, 1024]:
389+
cmd.append("-strpsz{0}".format(stripe_size))
390+
else:
391+
raise ValueError("Logical drive's stripe size must be one of 8, 16, 32, 64, 128, 256, 512, 1024")
392+
else:
393+
raise ValueError("Logical drive's stripe size must be type int")
394+
395+
if isinstance(hot_spares, list):
396+
if len(hot_spares) > 0:
397+
cmd.append("-Hsp[{0}]".format(','.join(hot_spares)))
398+
else:
399+
raise ValueError("Logical drive's hot spares must be type list")
332400

333-
return data #No restructuring of data required, just return it
401+
if after_ld:
402+
cmd.append("-afterLd {0}".format(after_ld))
403+
404+
if isinstance(force, bool):
405+
if force:
406+
cmd.append('-Force')
407+
else:
408+
raise ValueError("Logical drive's force flag must be type bool")
334409

335-
def removeld(self, device, adapter, force=False):
336-
#device should be a number (will be cast to string)
337-
#adapter should be a number (will be cast to string)
410+
return self.execute("-CfgLDAdd {0}".format(' '.join(cmd)))
411+
412+
def remove_ld(self, drive, adapter, force = False):
413+
"""
414+
Delete a logical drive
415+
@param drive: type int, specifies the drive to remove
416+
@param adapter: type int, specifies the drive's controller
417+
@param force: type bool, specifies whether to force or not the removal of the drive
418+
"""
419+
cmd = []
420+
421+
cmd.append("-L{0}".format(device))
422+
423+
if isinstance(adapter, int):
424+
cmd.append('-a{0}'.format(adapter))
425+
else:
426+
raise ValueError("Logical drive's adapter ID must be type int")
338427

339-
if not force:
340-
data = self.execute("-CfgLdDel -L" + str(device) + " -a" + str(adapter))
428+
if isinstance(force, bool):
429+
if force:
430+
cmd.append('-Force')
341431
else:
342-
data = self.execute("-CfgLdDel -L" + str(device) + " -Force -a" + str(adapter))
432+
raise ValueError("Logical drive's force flag must be type bool")
343433

344-
return data #No restructuring of data required, just return it
434+
return self.execute("-CfgLdDel {0}".format(' '.join(cmd)))
345435

0 commit comments

Comments
 (0)