162 lines
4.9 KiB
Python
162 lines
4.9 KiB
Python
#!/usr/bin/env python
|
|
import argparse
|
|
import ast
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import tempfile
|
|
import time
|
|
|
|
|
|
# Default flavor json directory
|
|
FLAVOR_DIR = './flavor_dir'
|
|
CLI_PATH = '../ormcli/orm'
|
|
FID = None
|
|
FILE_NAME = None
|
|
FLAVOR_NAME = None
|
|
REGION_NAME = None
|
|
|
|
|
|
def get_flavor_type(path):
|
|
# The last directory name is the flavor type (e.g., 'medium')
|
|
return path.split('/')[-2]
|
|
|
|
|
|
def get_region_list(regions):
|
|
global REGION_NAME
|
|
result = []
|
|
for region in regions:
|
|
REGION_NAME = region
|
|
res, output = sh('get_region')
|
|
if not res:
|
|
result_region = json.loads(output)
|
|
result.append({'name': result_region['name'],
|
|
'designType': result_region['designType']})
|
|
else:
|
|
print 'Failed to get region %s, aborting...' % (region,)
|
|
exit(1)
|
|
|
|
return result
|
|
|
|
|
|
def create_command(cli_command):
|
|
if cli_command == 'add_region':
|
|
cmd = 'python %s fms add_region %s %s' % (CLI_PATH, FID, FILE_NAME,)
|
|
elif cli_command == 'get_flavor':
|
|
cmd = 'python %s fms get_flavor test %s' % (CLI_PATH, FLAVOR_NAME,)
|
|
elif cli_command == 'get_region':
|
|
cmd = 'python %s rms get_region %s' % (CLI_PATH, REGION_NAME,)
|
|
else:
|
|
raise ValueError('Received an unknown command: %s' % (cli_command,))
|
|
|
|
if ';' in cmd or '&&' in cmd:
|
|
raise Exception("Violation of command injection, cmd is " + cmd)
|
|
return cmd
|
|
|
|
|
|
def read_jsonfile(file):
|
|
return json.loads(open(file).read())
|
|
|
|
|
|
def calculate_name(flavor):
|
|
flavor_name = "{0}.c{1}r{2}d{3}".format(flavor['series'], flavor['vcpus'],
|
|
int(flavor['ram']) / 1024,
|
|
flavor['disk'])
|
|
if 'ephemeral' in flavor and int(flavor['ephemeral']) != 0:
|
|
flavor_name += 'e{0}'.format(flavor['ephemeral'])
|
|
|
|
return flavor_name
|
|
|
|
|
|
def sh(cli_command):
|
|
# run a shell command, echoing output, painting error lines red,
|
|
# print runtime and status
|
|
# return status and output
|
|
|
|
cmd = create_command(cli_command)
|
|
print '>> Starting: ' + cmd
|
|
start = time.time()
|
|
output = ''
|
|
errpat = re.compile('error', re.I)
|
|
p = subprocess.Popen(cmd.split(), shell=False, stdout=subprocess.PIPE)
|
|
for line in iter(p.stdout.readline, b''):
|
|
out = line.rstrip()
|
|
print(">>> " + out)
|
|
output += out
|
|
end = time.time()
|
|
span = end - start
|
|
retcode = p.wait()
|
|
print '>> Ended: %s [%s, %d:%02d]' % (cmd, retcode, span / 60, span % 60)
|
|
return retcode, output
|
|
|
|
|
|
parser = argparse.ArgumentParser(prog='regionator',
|
|
description='batch add region to flavor')
|
|
parser.add_argument('regions',
|
|
type=str,
|
|
default='',
|
|
help='<comma-separated regions to add, e.g. region1,'
|
|
'region2>')
|
|
parser.add_argument('series',
|
|
type=str,
|
|
default='',
|
|
nargs='?',
|
|
help='<comma-separated flavor series to add, e.g. nd,gv>')
|
|
args = parser.parse_args()
|
|
|
|
regions = args.regions.split(',')
|
|
series_list = args.series.split(',')
|
|
if not regions:
|
|
print "Must specify at least one region"
|
|
exit(1)
|
|
|
|
# Get all regions from RMS
|
|
region_list = get_region_list(regions)
|
|
any_update = False
|
|
|
|
for file in [os.path.join(dp, f) for dp, dn, fn in
|
|
os.walk(os.path.expanduser(FLAVOR_DIR)) for f in fn]:
|
|
try:
|
|
f = read_jsonfile(file)
|
|
except ValueError:
|
|
continue
|
|
|
|
updated = False
|
|
flavor_type = get_flavor_type(file)
|
|
if not series_list or series_list == [''] or f['series'] in series_list:
|
|
data = {'regions': []}
|
|
for region in region_list:
|
|
# Take only the regions whose design type matches the flavor's
|
|
if flavor_type.lower() == region['designType'].lower():
|
|
data['regions'].append({'name': region['name']})
|
|
updated = True
|
|
any_update = True
|
|
|
|
if updated:
|
|
# Create the json file
|
|
fh, file_name = tempfile.mkstemp()
|
|
FILE_NAME = file_name
|
|
os.write(fh, json.dumps(data))
|
|
os.close(fh)
|
|
|
|
FLAVOR_NAME = calculate_name(f)
|
|
res, output = sh('get_flavor')
|
|
if not res:
|
|
flavor = ast.literal_eval(output)
|
|
FID = flavor['flavor']['id']
|
|
print 'fid: ' + FID
|
|
res, output = sh('add_region')
|
|
|
|
os.unlink(FILE_NAME)
|
|
|
|
if not any_update:
|
|
if not args.series:
|
|
exp = 'design type of any of the regions:[{}]'.format(args.regions)
|
|
else:
|
|
exp = 'combination of regions:[{}] and series:[{}]'.format(
|
|
args.regions, args.series)
|
|
|
|
print('No flavor was updated, please make sure that the {} matches any '
|
|
'flavor under the flavor directory'.format(exp))
|