#!/usr/bin/python # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # # Sun Storage 7000 size calculator version 1.1 # # Note that this script is unsupported, and makes use of unsupported XML-RPC # interfaces. # # For more information, check this blog post: # http://blogs.sun.com/ahl/entry/sun_storage_7410_space_calculator # import xmlrpclib import sys from copy import deepcopy def usage(): print 'usage: ' + sys.argv[0] + ' [-h ]' + \ ' ' print print '\tdisplays available configurations with raw capacity in TB' print '\t(1000^4 = 1,000,000,000,000 bytes) and usable capacity in TiB' print '\t(1024^4 = 1,099,511,627,776 bytes).' sys.exit(2) nhjbods = 0; if len(sys.argv) > 1: if sys.argv[1] == '-h': if len(sys.argv) < 3: usage() nhjbods = int(sys.argv[2]) del sys.argv[1] del sys.argv[1] if len(sys.argv) < 4: usage() server = xmlrpclib.ServerProxy('https://' + sys.argv[1] + ':215/ak') nfjbods = int(sys.argv[3]) njbods = nfjbods + nhjbods; if njbods <= 0: print 'zero jbods specified' sys.exit(2) if len(sys.argv) - 4 > njbods: print 'more logzillas specified than jbods' sys.exit(2) mirror = { 'type': 'mirror', 'disktype': 'data', 'modelOnly': True, 'nspf': False } mirror_n = { 'type': 'mirror', 'disktype': 'data', 'modelOnly': True, 'nspf': True } raidz1 = { 'type': 'raidz1', 'disktype': 'data', 'modelOnly': True, 'nspf': False } raidz1_n = { 'type': 'raidz1', 'disktype': 'data', 'modelOnly': True, 'nspf': True } raidz2 = { 'type': 'raidz2', 'disktype': 'data', 'modelOnly': True, 'nspf': False } raidz2_n = { 'type': 'raidz2', 'disktype': 'data', 'modelOnly': True, 'nspf': True } raidz2_wide = { 'type': 'raidz2', 'maximize': True, 'disktype': 'data', 'modelOnly': True, 'nspf': False } raidz2_n_wide = { 'type': 'raidz2', 'maximize': True, 'disktype': 'data', 'modelOnly': True, 'nspf': True } stripe = { 'type': 'stripe', 'disktype': 'data', 'modelOnly': True } options = [ raidz2, raidz2_n, raidz2_wide, raidz2_n_wide, mirror, mirror_n, stripe, raidz1, raidz1_n ] jbod = { 'akch_disk': [] } for n in xrange(0, 24): jbod['akch_disk'].append({ 'akch_type': 'data', 'akch_size': 1, 'akch_device': 'none', 'akch_faulted': False, 'akch_present': True, }) hjbod = { 'akch_disk': [] } for n in xrange(0, 12): hjbod['akch_disk'].append({ 'akch_type': 'data', 'akch_size': 1, 'akch_device': 'none', 'akch_faulted': False, 'akch_present': True, }) config = { 'akch_chassis': [] } ndrives = 0; for n in xrange(0, nfjbods): config['akch_chassis'].append(deepcopy(jbod)) ndrives += 24 for n in xrange(0, nhjbods): config['akch_chassis'].append(deepcopy(hjbod)) ndrives += 12 for i in xrange(0, len(sys.argv) - 4): for j in xrange(0, int(sys.argv[i + 4])): config['akch_chassis'][i]['akch_disk'][j]['akch_type'] = 'log' ndrives -= 1 args = [ { 'methodName': 'system.login', 'params': [ { 'username': 'root', 'password': sys.argv[2] } ] }, { 'methodName': 'system.push', 'params': [ config ] } ] for i in xrange(0, len(options)): args.append({ 'methodName': 'storage.poolConfig', 'methodParams': [ { 'quote': options[i] }, { 'peek': [] } ] }) args.append({ 'methodName': 'system.logout', 'params': [] }) result = server.system.multicall(args) del result[0] del result[0] result.pop() sys.stdout.write("\033[1m%-11s%7s%7s%7s%13s%15s%15s\033[0;0m\n" % ('type', 'NSPF', 'width', 'spares', 'data drives', 'raw (TB)', 'usable (TiB)')) for i in xrange(0, len(result)): if isinstance(result[i], type([])): nspf = False if options[i].has_key('nspf'): nspf = options[i]['nspf'] name = options[i]['type'] if options[i].has_key('maximize'): name = name + ' wide' r = result[i][0]['configurations'][0] # # Calculate the total usable capacity in Tebibytes (binary. # adjusted = r['capacity'] * (1000.0/1024.0) ** 4 * 63.0 / 64.0 sys.stdout.write("%-11s%7s%7d%7d%13d%15.2f%15.2f\n" % (name, nspf, r['width'], r['nspares'], ndrives - r['nspares'], r['capacity'], adjusted)) sys.exit(0)