@@ -20,7 +20,7 @@ def __init__(self, cli_path = '/opt/MegaRAID/MegaCli/MegaCli64'):
20
20
raise RuntimeError ('{0} not found' .format (cli_path ))
21
21
22
22
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 )
24
24
out , err = proc .communicate ()
25
25
if isinstance (out , bytes ):
26
26
out = out .decode ()
@@ -317,29 +317,119 @@ def adapters(self):
317
317
318
318
return ret
319
319
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" )
325
342
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" )
328
345
329
- pds = pds [: - 1 ] + ']'
346
+ cmd . append ( "-R{0}[{1}]" . format ( raid_level , ',' . join ( devices )))
330
347
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" )
332
400
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" )
334
409
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" )
338
427
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' )
341
431
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" )
343
433
344
- return data #No restructuring of data required, just return it
434
+ return self . execute ( "-CfgLdDel {0}" . format ( ' ' . join ( cmd )))
345
435
0 commit comments