Refactor and fix pep8 failures.
Create a utils.py file, and move all common code there Add flake8 checking to Makefile (requires "pip install flake8") Fixed all flake8 failures (except XenAPI.py, which is excluded) Change-Id: I5ca50930ffadcb021719f746b7750d7af9839844
This commit is contained in:
parent
ec49295492
commit
b772bc52ef
11
Makefile
11
Makefile
|
@ -1,6 +1,8 @@
|
|||
BRANDING=branding.inc
|
||||
|
||||
include ${BRANDING}
|
||||
OPENSTACK_RELEASE:=mitaka
|
||||
|
||||
PLUGIN_VERSION:=$(shell ./get_plugin_version.sh ${BRANDING} | cut -d' ' -f1)
|
||||
PLUGIN_REVISION:=$(shell ./get_plugin_version.sh ${BRANDING} | cut -d' ' -f2)
|
||||
|
||||
|
@ -17,8 +19,10 @@ rpm: output/${RPM_NAME}
|
|||
|
||||
docs: $(DOC_NAMES:%=output/${PLUGIN_NAME}-${PLUGIN_VERSION}-%.pdf)
|
||||
|
||||
iso: plugin_source/deployment_scripts/patchset/xenhost
|
||||
suppack/build-xenserver-suppack.sh
|
||||
iso: suppack/xenapi-plugins-${OPENSTACK_RELEASE}.iso
|
||||
|
||||
suppack/xenapi-plugins-${OPENSTACK_RELEASE}.iso: plugin_source/deployment_scripts/patchset/xenhost
|
||||
suppack/build-xenserver-suppack.sh ${OPENSTACK_RELEASE}
|
||||
|
||||
${BUILDROOT}/${PLUGIN_NAME}: ${BRANDING} iso
|
||||
mkdir -p ${BUILDROOT}/${PLUGIN_NAME}
|
||||
|
@ -44,6 +48,7 @@ ${BUILDROOT}/doc/source ${BUILDROOT}/doc/Makefile: ${BRANDING}
|
|||
|
||||
output/${RPM_NAME}: ${BUILDROOT}/${PLUGIN_NAME}
|
||||
mkdir -p output
|
||||
(cd ${BUILDROOT}; which flake8 > /dev/null && flake8 ${PLUGIN_NAME}/deployment_scripts --exclude=XenAPI.py)
|
||||
(cd ${BUILDROOT}; fpb --check ${PLUGIN_NAME})
|
||||
(cd ${BUILDROOT}; fpb --build ${PLUGIN_NAME})
|
||||
cp ${BUILDROOT}/${PLUGIN_NAME}/${RPM_NAME} $@
|
||||
|
@ -56,4 +61,4 @@ output/${PLUGIN_NAME}-${PLUGIN_VERSION}-%.pdf: ${BUILDROOT}/doc/build/latex/%.pd
|
|||
cp $^ $@
|
||||
|
||||
clean:
|
||||
rm -rf ${BUILDROOT} output
|
||||
rm -rf ${BUILDROOT} output suppack/xenapi-plugins-${OPENSTACK_RELEASE}* suppack/build
|
||||
|
|
|
@ -7,126 +7,25 @@ import os
|
|||
import re
|
||||
from socket import inet_ntoa
|
||||
from struct import pack
|
||||
import subprocess # nosec
|
||||
import sys
|
||||
import stat
|
||||
import yaml
|
||||
import utils
|
||||
from utils import HIMN_IP
|
||||
|
||||
|
||||
XS_RSA = '/root/.ssh/xs_rsa'
|
||||
ASTUTE_PATH = '/etc/astute.yaml'
|
||||
ASTUTE_SECTION = '@PLUGIN_NAME@'
|
||||
LOG_ROOT = '/var/log/@PLUGIN_NAME@'
|
||||
LOG_FILE = 'compute_post_deployment.log'
|
||||
HIMN_IP = '169.254.0.1'
|
||||
LOG_FILE = os.path.join(utils.LOG_ROOT, 'compute_post_deployment.log')
|
||||
INT_BRIDGE = 'br-int'
|
||||
XS_PLUGIN_ISO = 'xenapi-plugins-mitaka.iso'
|
||||
DIST_PACKAGES_DIR = '/usr/lib/python2.7/dist-packages/'
|
||||
PLATFORM_VERSION = '1.9'
|
||||
|
||||
if not os.path.exists(LOG_ROOT):
|
||||
os.mkdir(LOG_ROOT)
|
||||
if not os.path.exists(utils.LOG_ROOT):
|
||||
os.mkdir(utils.LOG_ROOT)
|
||||
|
||||
logging.basicConfig(filename=os.path.join(LOG_ROOT, LOG_FILE),
|
||||
logging.basicConfig(filename=LOG_FILE,
|
||||
level=logging.DEBUG)
|
||||
|
||||
|
||||
def reportError(err):
|
||||
logging.error(err)
|
||||
raise Exception(err)
|
||||
|
||||
|
||||
def execute(*cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
_env = kwargs.get('env')
|
||||
env_prefix = ''
|
||||
if _env:
|
||||
env_prefix = ''.join(['%s=%s ' % (k, _env[k]) for k in _env])
|
||||
|
||||
env = dict(os.environ)
|
||||
env.update(_env)
|
||||
else:
|
||||
env = None
|
||||
logging.info(env_prefix + ' '.join(cmd))
|
||||
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, # nosec
|
||||
stderr=subprocess.PIPE, env=env)
|
||||
|
||||
if 'prompt' in kwargs:
|
||||
prompt = kwargs.get('prompt')
|
||||
proc.stdout.flush()
|
||||
(out, err) = proc.communicate(prompt)
|
||||
else:
|
||||
out = proc.stdout.readlines()
|
||||
err = proc.stderr.readlines()
|
||||
(out, err) = map(' '.join, [out, err])
|
||||
|
||||
# Both if/else need to deal with "\n" scenario
|
||||
(out, err) = (out.replace('\n', ''), err.replace('\n', ''))
|
||||
|
||||
if out:
|
||||
logging.debug(out)
|
||||
if err:
|
||||
logging.error(err)
|
||||
|
||||
if proc.returncode is not None and proc.returncode != 0:
|
||||
raise Exception(err)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def ssh(host, username, *cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
|
||||
return execute('ssh', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no',
|
||||
'%s@%s' % (username, host), *cmd,
|
||||
prompt=kwargs.get('prompt'))
|
||||
|
||||
|
||||
def scp(host, username, target_path, filename):
|
||||
return execute('scp', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no', filename,
|
||||
'%s@%s:%s' % (username, host, target_path))
|
||||
|
||||
|
||||
def get_astute(astute_path):
|
||||
"""Return the root object read from astute.yaml"""
|
||||
if not os.path.exists(astute_path):
|
||||
reportError('%s not found' % astute_path)
|
||||
with open(astute_path) as f:
|
||||
astute = yaml.safe_load(f)
|
||||
return astute
|
||||
|
||||
|
||||
def astute_get(dct, keys, default=None, fail_if_missing=True):
|
||||
"""A safe dictionary getter"""
|
||||
for key in keys:
|
||||
if key in dct:
|
||||
dct = dct[key]
|
||||
else:
|
||||
if fail_if_missing:
|
||||
reportError('Value of "%s" is missing' % key)
|
||||
return default
|
||||
return dct
|
||||
|
||||
|
||||
def get_options(astute, astute_section):
|
||||
"""Return username and password filled in plugin."""
|
||||
if astute_section not in astute:
|
||||
reportError('%s not found' % astute_section)
|
||||
|
||||
options = astute[astute_section]
|
||||
logging.info('username: {username}'.format(**options))
|
||||
logging.info('password: {password}'.format(**options))
|
||||
logging.info('install_xapi: {install_xapi}'.format(**options))
|
||||
return options['username'], options['password'], \
|
||||
options['install_xapi']
|
||||
|
||||
|
||||
def get_endpoints(astute):
|
||||
"""Return the IP addresses of the endpoints connected to
|
||||
storage/mgmt network.
|
||||
"""
|
||||
"""Return the IP addresses of the storage/mgmt endpoints."""
|
||||
endpoints = astute['network_scheme']['endpoints']
|
||||
endpoints = dict([(
|
||||
k.replace('br-', ''),
|
||||
|
@ -138,56 +37,9 @@ def get_endpoints(astute):
|
|||
return endpoints
|
||||
|
||||
|
||||
def init_eth():
|
||||
"""Initialize the net interface connected to HIMN
|
||||
|
||||
Returns:
|
||||
the IP addresses of local host and hypervisor.
|
||||
"""
|
||||
|
||||
domid = execute('xenstore-read', 'domid')
|
||||
himn_mac = execute(
|
||||
'xenstore-read',
|
||||
'/local/domain/%s/vm-data/himn_mac' % domid)
|
||||
logging.info('himn_mac: %s' % himn_mac)
|
||||
|
||||
_mac = lambda eth: \
|
||||
netifaces.ifaddresses(eth).get(netifaces.AF_LINK)[0]['addr']
|
||||
eths = [eth for eth in netifaces.interfaces() if _mac(eth) == himn_mac]
|
||||
if len(eths) != 1:
|
||||
reportError('Cannot find eth matches himn_mac')
|
||||
|
||||
eth = eths[0]
|
||||
logging.info('himn_eth: %s' % eth)
|
||||
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if not ip:
|
||||
execute('dhclient', eth)
|
||||
fname = '/etc/network/interfaces.d/ifcfg-' + eth
|
||||
s = ('auto {eth}\n'
|
||||
'iface {eth} inet dhcp\n'
|
||||
'post-up route del default dev {eth}').format(eth=eth)
|
||||
with open(fname, 'w') as f:
|
||||
f.write(s)
|
||||
logging.info('%s created' % fname)
|
||||
execute('ifdown', eth)
|
||||
execute('ifup', eth)
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if ip:
|
||||
himn_local = ip[0]['addr']
|
||||
himn_xs = '.'.join(himn_local.split('.')[:-1] + ['1'])
|
||||
if HIMN_IP == himn_xs:
|
||||
logging.info('himn_local: %s' % himn_local)
|
||||
return eth, himn_local
|
||||
|
||||
reportError('HIMN failed to get IP address from Hypervisor')
|
||||
|
||||
|
||||
def install_xenapi_sdk():
|
||||
"""Install XenAPI Python SDK"""
|
||||
execute('cp', 'XenAPI.py', DIST_PACKAGES_DIR)
|
||||
utils.execute('cp', 'XenAPI.py', DIST_PACKAGES_DIR)
|
||||
|
||||
|
||||
def create_novacompute_conf(himn, username, password, public_ip, services_ssl):
|
||||
|
@ -197,7 +49,7 @@ def create_novacompute_conf(himn, username, password, public_ip, services_ssl):
|
|||
and mgmt_if.get(netifaces.AF_INET)[0]['addr']:
|
||||
mgmt_ip = mgmt_if.get(netifaces.AF_INET)[0]['addr']
|
||||
else:
|
||||
reportError('Cannot get IP Address on Management Network')
|
||||
utils.reportError('Cannot get IP Address on Management Network')
|
||||
|
||||
filename = '/etc/nova/nova-compute.conf'
|
||||
cf = ConfigParser.ConfigParser()
|
||||
|
@ -221,24 +73,31 @@ def create_novacompute_conf(himn, username, password, public_ip, services_ssl):
|
|||
with open(filename, 'w') as configfile:
|
||||
cf.write(configfile)
|
||||
except Exception:
|
||||
reportError('Cannot set configurations to %s' % filename)
|
||||
utils.reportError('Cannot set configurations to %s' % filename)
|
||||
logging.info('%s created' % filename)
|
||||
|
||||
|
||||
def route_to_compute(endpoints, himn_xs, himn_local, username):
|
||||
"""Route storage/mgmt requests to compute nodes. """
|
||||
out = ssh(himn_xs, username, 'route', '-n')
|
||||
_net = lambda ip: '.'.join(ip.split('.')[:-1] + ['0'])
|
||||
_mask = lambda cidr: inet_ntoa(pack(
|
||||
'>I', 0xffffffff ^ (1 << 32 - int(cidr)) - 1))
|
||||
_routed = lambda net, mask, gw: re.search(r'%s\s+%s\s+%s\s+' % (
|
||||
net.replace('.', r'\.'),
|
||||
gw.replace('.', r'\.'),
|
||||
mask
|
||||
), out)
|
||||
|
||||
ssh(himn_xs, username,
|
||||
'printf "#!/bin/bash\nsleep 5\n" > /etc/udev/scripts/reroute.sh')
|
||||
def _net(ip):
|
||||
return '.'.join(ip.split('.')[:-1] + ['0'])
|
||||
|
||||
def _mask(cidr):
|
||||
return inet_ntoa(pack('>I', 0xffffffff ^ (1 << 32 - int(cidr)) - 1))
|
||||
|
||||
def _routed(net, mask, gw):
|
||||
return re.search(r'%s\s+%s\s+%s\s+' % (
|
||||
net.replace('.', r'\.'),
|
||||
gw.replace('.', r'\.'),
|
||||
mask
|
||||
), out)
|
||||
|
||||
out = utils.ssh(himn_xs, username, 'route', '-n')
|
||||
|
||||
utils.ssh(himn_xs, username,
|
||||
('printf "#!/bin/bash\nsleep 5\n" >'
|
||||
'/etc/udev/scripts/reroute.sh'))
|
||||
endpoint_names = ['storage', 'mgmt']
|
||||
for endpoint_name in endpoint_names:
|
||||
endpoint = endpoints.get(endpoint_name)
|
||||
|
@ -248,79 +107,82 @@ def route_to_compute(endpoints, himn_xs, himn_local, username):
|
|||
if not _routed(net, mask, himn_local):
|
||||
params = ['route', 'add', '-net', '"%s"' % net, 'netmask',
|
||||
'"%s"' % mask, 'gw', himn_local]
|
||||
ssh(himn_xs, username, *params)
|
||||
utils.ssh(himn_xs, username, *params)
|
||||
# Always add the route to the udev, even if it's currently active
|
||||
cmd = (
|
||||
"printf 'if !(/sbin/route -n | /bin/grep -q -F \"{net}\"); then\n"
|
||||
"/sbin/route add -net \"{net}\" netmask \"{mask}\" gw {himn_local};\n"
|
||||
"printf 'if !(/sbin/route -n | /bin/grep -q -F \"{net}\"); "
|
||||
"then\n"
|
||||
"/sbin/route add -net \"{net}\" netmask "
|
||||
"\"{mask}\" gw {himn_local};\n"
|
||||
"fi\n' >> /etc/udev/scripts/reroute.sh"
|
||||
)
|
||||
cmd = cmd.format(net=net, mask=mask, himn_local=himn_local)
|
||||
ssh(himn_xs, username, cmd)
|
||||
utils.ssh(himn_xs, username, cmd)
|
||||
else:
|
||||
logging.info('%s network ip is missing' % endpoint_name)
|
||||
ssh(himn_xs, username, 'chmod +x /etc/udev/scripts/reroute.sh')
|
||||
ssh(himn_xs, username, ('echo \'SUBSYSTEM=="net" ACTION=="add" '
|
||||
'KERNEL=="xenapi" RUN+="/etc/udev/scripts/reroute.sh"\' '
|
||||
'> /etc/udev/rules.d/90-reroute.rules'))
|
||||
utils.ssh(himn_xs, username, 'chmod +x /etc/udev/scripts/reroute.sh')
|
||||
utils.ssh(himn_xs, username,
|
||||
('echo \'SUBSYSTEM=="net" ACTION=="add" '
|
||||
'KERNEL=="xenapi" RUN+="/etc/udev/scripts/reroute.sh"\' '
|
||||
'> /etc/udev/rules.d/90-reroute.rules'))
|
||||
|
||||
|
||||
def install_suppack(himn, username):
|
||||
"""Install xapi driver supplemental pack. """
|
||||
tmp = ssh(himn, username, 'mktemp', '-d')
|
||||
scp(himn, username, tmp, XS_PLUGIN_ISO)
|
||||
ssh(himn, username, 'xe-install-supplemental-pack', tmp + '/' + XS_PLUGIN_ISO,
|
||||
prompt='Y\n')
|
||||
ssh(himn, username, 'rm', tmp, '-rf')
|
||||
tmp = utils.ssh(himn, username, 'mktemp', '-d')
|
||||
utils.scp(himn, username, tmp, XS_PLUGIN_ISO)
|
||||
utils.ssh(himn, username, 'xe-install-supplemental-pack',
|
||||
tmp + '/' + XS_PLUGIN_ISO, prompt='Y\n')
|
||||
utils.ssh(himn, username, 'rm', tmp, '-rf')
|
||||
|
||||
|
||||
def forward_from_himn(eth):
|
||||
"""Forward packets from HIMN to storage/mgmt network. """
|
||||
execute('sed', '-i', 's/#net.ipv4.ip_forward/net.ipv4.ip_forward/g',
|
||||
'/etc/sysctl.conf')
|
||||
execute('sysctl', '-p', '/etc/sysctl.conf')
|
||||
utils.execute('sed', '-i', 's/#net.ipv4.ip_forward/net.ipv4.ip_forward/g',
|
||||
'/etc/sysctl.conf')
|
||||
utils.execute('sysctl', '-p', '/etc/sysctl.conf')
|
||||
|
||||
endpoint_names = ['br-storage', 'br-mgmt']
|
||||
for endpoint_name in endpoint_names:
|
||||
execute('iptables', '-t', 'nat', '-A', 'POSTROUTING',
|
||||
'-o', endpoint_name, '-j', 'MASQUERADE')
|
||||
execute('iptables', '-A', 'FORWARD',
|
||||
'-i', endpoint_name, '-o', eth,
|
||||
'-m', 'state', '--state', 'RELATED,ESTABLISHED',
|
||||
'-j', 'ACCEPT')
|
||||
execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth, '-o', endpoint_name,
|
||||
'-j', 'ACCEPT')
|
||||
utils.execute('iptables', '-t', 'nat', '-A', 'POSTROUTING',
|
||||
'-o', endpoint_name, '-j', 'MASQUERADE')
|
||||
utils.execute('iptables', '-A', 'FORWARD',
|
||||
'-i', endpoint_name, '-o', eth,
|
||||
'-m', 'state', '--state', 'RELATED,ESTABLISHED',
|
||||
'-j', 'ACCEPT')
|
||||
utils.execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth, '-o', endpoint_name,
|
||||
'-j', 'ACCEPT')
|
||||
|
||||
execute('iptables', '-A', 'INPUT', '-i', eth, '-j', 'ACCEPT')
|
||||
execute('iptables', '-t', 'filter', '-S', 'FORWARD')
|
||||
execute('iptables', '-t', 'nat', '-S', 'POSTROUTING')
|
||||
execute('service', 'iptables-persistent', 'save')
|
||||
utils.execute('iptables', '-A', 'INPUT', '-i', eth, '-j', 'ACCEPT')
|
||||
utils.execute('iptables', '-t', 'filter', '-S', 'FORWARD')
|
||||
utils.execute('iptables', '-t', 'nat', '-S', 'POSTROUTING')
|
||||
utils.execute('service', 'iptables-persistent', 'save')
|
||||
|
||||
|
||||
def forward_port(eth_in, eth_out, target_host, target_port):
|
||||
"""Forward packets from eth_in to eth_out on target_host:target_port. """
|
||||
execute('iptables', '-t', 'nat', '-A', 'PREROUTING',
|
||||
'-i', eth_in, '-p', 'tcp', '--dport', target_port,
|
||||
'-j', 'DNAT', '--to', target_host)
|
||||
execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth_out, '-o', eth_in,
|
||||
'-m', 'state', '--state', 'RELATED,ESTABLISHED',
|
||||
'-j', 'ACCEPT')
|
||||
execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth_in, '-o', eth_out,
|
||||
'-j', 'ACCEPT')
|
||||
utils.execute('iptables', '-t', 'nat', '-A', 'PREROUTING',
|
||||
'-i', eth_in, '-p', 'tcp', '--dport', target_port,
|
||||
'-j', 'DNAT', '--to', target_host)
|
||||
utils.execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth_out, '-o', eth_in,
|
||||
'-m', 'state', '--state', 'RELATED,ESTABLISHED',
|
||||
'-j', 'ACCEPT')
|
||||
utils.execute('iptables', '-A', 'FORWARD',
|
||||
'-i', eth_in, '-o', eth_out,
|
||||
'-j', 'ACCEPT')
|
||||
|
||||
execute('iptables', '-t', 'filter', '-S', 'FORWARD')
|
||||
execute('iptables', '-t', 'nat', '-S', 'POSTROUTING')
|
||||
execute('service', 'iptables-persistent', 'save')
|
||||
utils.execute('iptables', '-t', 'filter', '-S', 'FORWARD')
|
||||
utils.execute('iptables', '-t', 'nat', '-S', 'POSTROUTING')
|
||||
utils.execute('service', 'iptables-persistent', 'save')
|
||||
|
||||
|
||||
def install_logrotate_script(himn, username):
|
||||
"Install console logrotate script"
|
||||
scp(himn, username, '/root/', 'rotate_xen_guest_logs.sh')
|
||||
ssh(himn, username, 'mkdir -p /var/log/xen/guest')
|
||||
ssh(himn, username, '''crontab - << CRONTAB
|
||||
utils.scp(himn, username, '/root/', 'rotate_xen_guest_logs.sh')
|
||||
utils.ssh(himn, username, 'mkdir -p /var/log/xen/guest')
|
||||
utils.ssh(himn, username, '''crontab - << CRONTAB
|
||||
* * * * * /root/rotate_xen_guest_logs.sh
|
||||
CRONTAB''')
|
||||
|
||||
|
@ -337,7 +199,7 @@ def modify_neutron_rootwrap_conf(himn, username, password):
|
|||
with open(filename, 'w') as configfile:
|
||||
cf.write(configfile)
|
||||
except Exception:
|
||||
reportError("Fail to modify file %s", filename)
|
||||
utils.reportError("Fail to modify file %s", filename)
|
||||
logging.info('Modify file %s successfully', filename)
|
||||
|
||||
|
||||
|
@ -355,7 +217,7 @@ def modify_neutron_ovs_agent_conf(int_br, br_mappings):
|
|||
with open(filename, 'w') as configfile:
|
||||
cf.write(configfile)
|
||||
except Exception:
|
||||
reportError("Fail to modify %s", filename)
|
||||
utils.reportError("Fail to modify %s", filename)
|
||||
logging.info('Modify %s successfully', filename)
|
||||
|
||||
|
||||
|
@ -374,18 +236,21 @@ def get_private_network_ethX():
|
|||
if item['action'] == 'add-port' and item['bridge'] == 'br-ex':
|
||||
return item['name']
|
||||
|
||||
|
||||
def find_bridge_mappings(astute, himn, username):
|
||||
ethX = get_private_network_ethX()
|
||||
if not ethX:
|
||||
reportError("Cannot find eth used for private network")
|
||||
utils.reportError("Cannot find eth used for private network")
|
||||
|
||||
# find the ethX mac in /sys/class/net/ethX/address
|
||||
with open('/sys/class/net/%s/address' % ethX, 'r') as fo:
|
||||
mac = fo.readline()
|
||||
network_uuid = ssh(himn, username,
|
||||
'xe vif-list params=network-uuid minimal=true MAC=%s' % mac)
|
||||
bridge = ssh(himn, username,
|
||||
'xe network-param-get param-name=bridge uuid=%s' % network_uuid)
|
||||
network_uuid = utils.ssh(himn, username,
|
||||
('xe vif-list params=network-uuid '
|
||||
'minimal=true MAC=%s') % mac)
|
||||
bridge = utils.ssh(himn, username,
|
||||
('xe network-param-get param-name=bridge '
|
||||
'uuid=%s') % network_uuid)
|
||||
|
||||
# find physical network name
|
||||
phynet_setting = astute['quantum_settings']['L2']['phys_nets']
|
||||
|
@ -394,33 +259,36 @@ def find_bridge_mappings(astute, himn, username):
|
|||
|
||||
|
||||
def restart_services(service_name):
|
||||
execute('stop', service_name)
|
||||
execute('start', service_name)
|
||||
utils.execute('stop', service_name)
|
||||
utils.execute('start', service_name)
|
||||
|
||||
|
||||
def enable_linux_bridge(himn, username):
|
||||
# When using OVS under XS6.5, it will prevent use of Linux bridge in
|
||||
# Dom0, but neutron-openvswitch-agent in compute node will use Linux
|
||||
# bridge, so we remove this restriction here
|
||||
ssh(himn, username, 'rm -f /etc/modprobe.d/blacklist-bridge*')
|
||||
utils.ssh(himn, username, 'rm -f /etc/modprobe.d/blacklist-bridge*')
|
||||
|
||||
|
||||
def patch_ceilometer():
|
||||
"""
|
||||
Add patches which are not MOS with order:
|
||||
"""Add patches which are not merged to upstream
|
||||
|
||||
Order of patches applied:
|
||||
ceilometer-poll-cpu-util.patch
|
||||
"""
|
||||
patchset_dir = sys.path[0]
|
||||
patchfile_list = [
|
||||
'%s/patchset/ceilometer-poll-cpu-util.patch' % patchset_dir,
|
||||
]
|
||||
'%s/patchset/ceilometer-poll-cpu-util.patch' % patchset_dir,
|
||||
]
|
||||
for patch_file in patchfile_list:
|
||||
execute('patch', '-d', DIST_PACKAGES_DIR, '-p1', '-i', patch_file)
|
||||
utils.execute('patch', '-d', DIST_PACKAGES_DIR, '-p1', '-i',
|
||||
patch_file)
|
||||
|
||||
|
||||
def patch_compute_xenapi():
|
||||
"""
|
||||
Add patches which are not merged to upstream with order:
|
||||
"""Add patches which are not merged to upstream
|
||||
|
||||
Order of patches applied:
|
||||
support-disable-image-cache.patch
|
||||
speed-up-config-drive.patch
|
||||
ovs-interim-bridge.patch
|
||||
|
@ -428,36 +296,36 @@ def patch_compute_xenapi():
|
|||
"""
|
||||
patchset_dir = sys.path[0]
|
||||
patchfile_list = [
|
||||
'%s/patchset/support-disable-image-cache.patch' % patchset_dir,
|
||||
'%s/patchset/speed-up-config-drive.patch' % patchset_dir,
|
||||
'%s/patchset/ovs-interim-bridge.patch' % patchset_dir,
|
||||
'%s/patchset/neutron-security-group.patch' % patchset_dir
|
||||
]
|
||||
'%s/patchset/support-disable-image-cache.patch' % patchset_dir,
|
||||
'%s/patchset/speed-up-config-drive.patch' % patchset_dir,
|
||||
'%s/patchset/ovs-interim-bridge.patch' % patchset_dir,
|
||||
'%s/patchset/neutron-security-group.patch' % patchset_dir]
|
||||
for patch_file in patchfile_list:
|
||||
execute('patch', '-d', DIST_PACKAGES_DIR, '-p1', '-i', patch_file)
|
||||
utils.execute('patch', '-d', DIST_PACKAGES_DIR, '-p1', '-i',
|
||||
patch_file)
|
||||
|
||||
|
||||
def patch_neutron_ovs_agent():
|
||||
"""
|
||||
MO8's patch is not needed, keep the func here to add conntrack patch later
|
||||
"""
|
||||
# MO8's patch is not needed, keep the func here to add
|
||||
# conntrack patch later
|
||||
pass
|
||||
|
||||
|
||||
def reconfig_multipath():
|
||||
"""Ignore local disks for multipathd
|
||||
|
||||
Change devnode rule from "^hd[a-z]" to "^(hd|xvd)[a-z]"
|
||||
"""
|
||||
Ignore local disks for multipathd by changing devnode rule from
|
||||
"^hd[a-z]" to "^(hd|xvd)[a-z]"
|
||||
"""
|
||||
execute('sed', '-i', r's/"\^hd\[a-z\]"/"^(hd|xvd)[a-z]"/', '/etc/multipath.conf')
|
||||
execute('service', 'multipath-tools', 'restart')
|
||||
utils.execute('sed', '-i', r's/"\^hd\[a-z\]"/"^(hd|xvd)[a-z]"/',
|
||||
'/etc/multipath.conf')
|
||||
utils.execute('service', 'multipath-tools', 'restart')
|
||||
|
||||
|
||||
def check_and_setup_ceilometer(himn, username, password):
|
||||
"""Set xenapi configuration for ceilometer service"""
|
||||
filename = '/etc/ceilometer/ceilometer.conf'
|
||||
if not os.path.exists(filename):
|
||||
reportError("The file: %s doesn't exist" % filename)
|
||||
utils.reportError("The file: %s doesn't exist" % filename)
|
||||
return
|
||||
|
||||
patch_ceilometer()
|
||||
|
@ -473,23 +341,23 @@ def check_and_setup_ceilometer(himn, username, password):
|
|||
cf.write(configfile)
|
||||
logging.info('Modify file %s successfully', filename)
|
||||
except Exception:
|
||||
reportError("Fail to modify file %s", filename)
|
||||
utils.reportError("Fail to modify file %s", filename)
|
||||
return
|
||||
restart_services('ceilometer-polling')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
install_xenapi_sdk()
|
||||
astute = get_astute(ASTUTE_PATH)
|
||||
astute = utils.get_astute()
|
||||
if astute:
|
||||
username, password, install_xapi = get_options(astute, ASTUTE_SECTION)
|
||||
username, password, install_xapi = utils.get_options(astute)
|
||||
endpoints = get_endpoints(astute)
|
||||
himn_eth, himn_local = init_eth()
|
||||
himn_eth, himn_local = utils.init_eth()
|
||||
|
||||
public_ip = astute_get(
|
||||
public_ip = utils.astute_get(
|
||||
astute, ('network_metadata', 'vips', 'public', 'ipaddr'))
|
||||
|
||||
services_ssl = astute_get(
|
||||
services_ssl = utils.astute_get(
|
||||
astute, ('public_ssl', 'services'))
|
||||
|
||||
if username and password and endpoints and himn_local:
|
||||
|
@ -502,7 +370,8 @@ if __name__ == '__main__':
|
|||
# port forwarding for novnc
|
||||
forward_port('br-mgmt', himn_eth, HIMN_IP, '80')
|
||||
|
||||
create_novacompute_conf(HIMN_IP, username, password, public_ip, services_ssl)
|
||||
create_novacompute_conf(HIMN_IP, username, password, public_ip,
|
||||
services_ssl)
|
||||
patch_compute_xenapi()
|
||||
restart_services('nova-compute')
|
||||
|
||||
|
@ -518,8 +387,8 @@ if __name__ == '__main__':
|
|||
reconfig_multipath()
|
||||
|
||||
# Add xenapi specific setup for ceilometer if service is enabled.
|
||||
is_ceilometer_enabled = astute_get(astute,
|
||||
('ceilometer', 'enabled'))
|
||||
is_ceilometer_enabled = utils.astute_get(astute,
|
||||
('ceilometer', 'enabled'))
|
||||
if is_ceilometer_enabled:
|
||||
check_and_setup_ceilometer(HIMN_IP, username, password)
|
||||
else:
|
||||
|
|
|
@ -1,94 +1,22 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import ConfigParser
|
||||
import logging
|
||||
import netifaces
|
||||
import os
|
||||
import re
|
||||
from socket import inet_ntoa
|
||||
from struct import pack
|
||||
import subprocess # nosec
|
||||
import sys
|
||||
import stat
|
||||
import yaml
|
||||
|
||||
import utils
|
||||
from utils import HIMN_IP
|
||||
|
||||
XS_RSA = '/root/.ssh/xs_rsa'
|
||||
ASTUTE_PATH = '/etc/astute.yaml'
|
||||
ASTUTE_SECTION = '@PLUGIN_NAME@'
|
||||
LOG_ROOT = '/var/log/@PLUGIN_NAME@'
|
||||
LOG_FILE = 'compute_pre_deployment.log'
|
||||
HIMN_IP = '169.254.0.1'
|
||||
INT_BRIDGE = 'br-int'
|
||||
XS_PLUGIN_ISO = 'xenapi-plugins-mitaka.iso'
|
||||
DIST_PACKAGES_DIR = '/usr/lib/python2.7/dist-packages/'
|
||||
LOG_FILE = os.path.join(utils.LOG_ROOT, 'compute_pre_deployment.log')
|
||||
PLATFORM_VERSION = '1.9'
|
||||
|
||||
if not os.path.exists(LOG_ROOT):
|
||||
os.mkdir(LOG_ROOT)
|
||||
if not os.path.exists(utils.LOG_ROOT):
|
||||
os.mkdir(utils.LOG_ROOT)
|
||||
|
||||
logging.basicConfig(filename=os.path.join(LOG_ROOT, LOG_FILE),
|
||||
logging.basicConfig(filename=LOG_FILE,
|
||||
level=logging.DEBUG)
|
||||
|
||||
|
||||
def reportError(err):
|
||||
logging.error(err)
|
||||
raise Exception(err)
|
||||
|
||||
|
||||
def execute(*cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
_env = kwargs.get('env')
|
||||
env_prefix = ''
|
||||
if _env:
|
||||
env_prefix = ''.join(['%s=%s ' % (k, _env[k]) for k in _env])
|
||||
|
||||
env = dict(os.environ)
|
||||
env.update(_env)
|
||||
else:
|
||||
env = None
|
||||
logging.info(env_prefix + ' '.join(cmd))
|
||||
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, # nosec
|
||||
stderr=subprocess.PIPE, env=env)
|
||||
|
||||
if 'prompt' in kwargs:
|
||||
prompt = kwargs.get('prompt')
|
||||
proc.stdout.flush()
|
||||
(out, err) = proc.communicate(prompt)
|
||||
else:
|
||||
out = proc.stdout.readlines()
|
||||
err = proc.stderr.readlines()
|
||||
(out, err) = map(' '.join, [out, err])
|
||||
|
||||
# Both if/else need to deal with "\n" scenario
|
||||
(out, err) = (out.replace('\n', ''), err.replace('\n', ''))
|
||||
|
||||
if out:
|
||||
logging.debug(out)
|
||||
if err:
|
||||
logging.error(err)
|
||||
|
||||
if proc.returncode is not None and proc.returncode != 0:
|
||||
raise Exception(err)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def ssh(host, username, *cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
|
||||
return execute('ssh', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no',
|
||||
'%s@%s' % (username, host), *cmd,
|
||||
prompt=kwargs.get('prompt'))
|
||||
|
||||
|
||||
def scp(host, username, target_path, filename):
|
||||
return execute('scp', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no', filename,
|
||||
'%s@%s:%s' % (username, host, target_path))
|
||||
|
||||
|
||||
def ssh_copy_id(host, username, password):
|
||||
ssh_askpass = "askpass.sh"
|
||||
|
||||
|
@ -102,127 +30,48 @@ def ssh_copy_id(host, username, password):
|
|||
os.remove(XS_RSA)
|
||||
if os.path.exists(XS_RSA + ".pub"):
|
||||
os.remove(XS_RSA + ".pub")
|
||||
execute('ssh-keygen', '-f', XS_RSA, '-t', 'rsa', '-N', '')
|
||||
utils.execute('ssh-keygen', '-f', XS_RSA, '-t', 'rsa', '-N', '')
|
||||
|
||||
env = {
|
||||
"HOME": "/root",
|
||||
"SSH_ASKPASS": os.path.abspath(ssh_askpass),
|
||||
"DISPLAY": ":.",
|
||||
}
|
||||
execute("setsid", "ssh-copy-id", "-o", "StrictHostKeyChecking=no",
|
||||
"-i", XS_RSA, "%s@%s" % (username, host), env=env)
|
||||
|
||||
|
||||
def get_astute(astute_path):
|
||||
"""Return the root object read from astute.yaml"""
|
||||
if not os.path.exists(astute_path):
|
||||
reportError('%s not found' % astute_path)
|
||||
with open(astute_path) as f:
|
||||
astute = yaml.safe_load(f)
|
||||
return astute
|
||||
|
||||
|
||||
def astute_get(dct, keys, default=None, fail_if_missing=True):
|
||||
"""A safe dictionary getter"""
|
||||
for key in keys:
|
||||
if key in dct:
|
||||
dct = dct[key]
|
||||
else:
|
||||
if fail_if_missing:
|
||||
reportError('Value of "%s" is missing' % key)
|
||||
return default
|
||||
return dct
|
||||
|
||||
|
||||
def get_options(astute, astute_section):
|
||||
"""Return username and password filled in plugin."""
|
||||
if astute_section not in astute:
|
||||
reportError('%s not found' % astute_section)
|
||||
|
||||
options = astute[astute_section]
|
||||
logging.info('username: {username}'.format(**options))
|
||||
logging.info('password: {password}'.format(**options))
|
||||
logging.info('install_xapi: {install_xapi}'.format(**options))
|
||||
return options['username'], options['password'], \
|
||||
options['install_xapi']
|
||||
|
||||
|
||||
def init_eth():
|
||||
"""Initialize the net interface connected to HIMN
|
||||
|
||||
Returns:
|
||||
the IP addresses of local host and hypervisor.
|
||||
"""
|
||||
|
||||
domid = execute('xenstore-read', 'domid')
|
||||
himn_mac = execute(
|
||||
'xenstore-read',
|
||||
'/local/domain/%s/vm-data/himn_mac' % domid)
|
||||
logging.info('himn_mac: %s' % himn_mac)
|
||||
|
||||
_mac = lambda eth: \
|
||||
netifaces.ifaddresses(eth).get(netifaces.AF_LINK)[0]['addr']
|
||||
eths = [eth for eth in netifaces.interfaces() if _mac(eth) == himn_mac]
|
||||
if len(eths) != 1:
|
||||
reportError('Cannot find eth matches himn_mac')
|
||||
|
||||
eth = eths[0]
|
||||
logging.info('himn_eth: %s' % eth)
|
||||
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if not ip:
|
||||
execute('dhclient', eth)
|
||||
fname = '/etc/network/interfaces.d/ifcfg-' + eth
|
||||
s = ('auto {eth}\n'
|
||||
'iface {eth} inet dhcp\n'
|
||||
'post-up route del default dev {eth}').format(eth=eth)
|
||||
with open(fname, 'w') as f:
|
||||
f.write(s)
|
||||
logging.info('%s created' % fname)
|
||||
execute('ifdown', eth)
|
||||
execute('ifup', eth)
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if ip:
|
||||
himn_local = ip[0]['addr']
|
||||
himn_xs = '.'.join(himn_local.split('.')[:-1] + ['1'])
|
||||
if HIMN_IP == himn_xs:
|
||||
logging.info('himn_local: %s' % himn_local)
|
||||
return eth, himn_local
|
||||
|
||||
reportError('HIMN failed to get IP address from Hypervisor')
|
||||
utils.execute("setsid", "ssh-copy-id", "-o", "StrictHostKeyChecking=no",
|
||||
"-i", XS_RSA, "%s@%s" % (username, host), env=env)
|
||||
|
||||
|
||||
def check_host_compatibility(himn, username):
|
||||
hotfix = 'XS65ESP1013'
|
||||
installed = ssh(himn, username,
|
||||
'xe patch-list name-label=%s --minimal' % hotfix)
|
||||
ver = ssh(himn, username,
|
||||
('xe host-param-get uuid=$(xe host-list --minimal) '
|
||||
'param-name=software-version param-key=platform_version'))
|
||||
installed = utils.ssh(himn, username,
|
||||
'xe patch-list name-label=%s --minimal' % hotfix)
|
||||
ver = utils.ssh(himn, username,
|
||||
('xe host-param-get uuid=$(xe host-list --minimal) '
|
||||
'param-name=software-version param-key=platform_version'))
|
||||
|
||||
if not installed and ver[:3] == PLATFORM_VERSION:
|
||||
reportError(('Hotfix %s has not been installed '
|
||||
'and product version is %s') % (hotfix, ver))
|
||||
utils.reportError(('Hotfix %s has not been installed '
|
||||
'and product version is %s') % (hotfix, ver))
|
||||
|
||||
|
||||
def check_local_sr(himn, username):
|
||||
sr_type = ssh(himn, username,
|
||||
('xe sr-param-get param-name=type uuid=`xe pool-list params=default-SR --minimal`'))
|
||||
sr_type = utils.ssh(himn, username,
|
||||
('xe sr-param-get param-name=type '
|
||||
'uuid=`xe pool-list params=default-SR --minimal`'))
|
||||
|
||||
if sr_type != "ext" and sr_type != "nfs":
|
||||
reportError(('Default SR type should be EXT or NFS. If using local storage, Please make sure thin'
|
||||
' provisioning is enabled on your host during installation.'))
|
||||
utils.reportError(('Default SR type should be EXT or NFS. If using '
|
||||
'local storage, Please make sure thin provisioning '
|
||||
'is enabled on your host during installation.'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
astute = get_astute(ASTUTE_PATH)
|
||||
astute = utils.get_astute()
|
||||
if astute:
|
||||
username, password, install_xapi = get_options(astute, ASTUTE_SECTION)
|
||||
himn_eth, himn_local = init_eth()
|
||||
username, password, install_xapi = utils.get_options(astute)
|
||||
himn_eth, himn_local = utils.init_eth()
|
||||
|
||||
if username and password and himn_local:
|
||||
ssh_copy_id(HIMN_IP, username, password)
|
||||
check_host_compatibility(HIMN_IP, username)
|
||||
check_local_sr(HIMN_IP, username)
|
||||
check_local_sr(HIMN_IP, username)
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import logging
|
||||
import netifaces
|
||||
import os
|
||||
import subprocess
|
||||
import yaml
|
||||
|
||||
XS_RSA = '/root/.ssh/xs_rsa'
|
||||
ASTUTE_PATH = '/etc/astute.yaml'
|
||||
ASTUTE_SECTION = '@PLUGIN_NAME@'
|
||||
LOG_ROOT = '/var/log/@PLUGIN_NAME@'
|
||||
HIMN_IP = '169.254.0.1'
|
||||
|
||||
|
||||
class ExecutionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class FatalException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def reportError(err):
|
||||
logging.error(err)
|
||||
raise FatalException(err)
|
||||
|
||||
|
||||
def execute(*cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
_env = kwargs.get('env')
|
||||
env_prefix = ''
|
||||
if _env:
|
||||
env_prefix = ''.join(['%s=%s ' % (k, _env[k]) for k in _env])
|
||||
|
||||
env = dict(os.environ)
|
||||
env.update(_env)
|
||||
else:
|
||||
env = None
|
||||
logging.info(env_prefix + ' '.join(cmd))
|
||||
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, # nosec
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, env=env)
|
||||
|
||||
if 'prompt' in kwargs:
|
||||
prompt = kwargs.get('prompt')
|
||||
proc.stdout.flush()
|
||||
(out, err) = proc.communicate(prompt)
|
||||
else:
|
||||
out = proc.stdout.readlines()
|
||||
err = proc.stderr.readlines()
|
||||
(out, err) = map(' '.join, [out, err])
|
||||
|
||||
# Both if/else need to deal with "\n" scenario
|
||||
(out, err) = (out.replace('\n', ''), err.replace('\n', ''))
|
||||
|
||||
if out:
|
||||
logging.debug(out)
|
||||
if err:
|
||||
logging.error(err)
|
||||
|
||||
if proc.returncode is not None and proc.returncode != 0:
|
||||
raise ExecutionError(err)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def ssh(host, username, *cmd, **kwargs):
|
||||
cmd = map(str, cmd)
|
||||
|
||||
return execute('ssh', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no',
|
||||
'%s@%s' % (username, host), *cmd,
|
||||
prompt=kwargs.get('prompt'))
|
||||
|
||||
|
||||
def scp(host, username, target_path, filename):
|
||||
return execute('scp', '-i', XS_RSA,
|
||||
'-o', 'StrictHostKeyChecking=no', filename,
|
||||
'%s@%s:%s' % (username, host, target_path))
|
||||
|
||||
|
||||
def get_astute(astute_path=ASTUTE_PATH):
|
||||
"""Return the root object read from astute.yaml"""
|
||||
if not os.path.exists(astute_path):
|
||||
reportError('%s not found' % astute_path)
|
||||
with open(astute_path) as f:
|
||||
astute = yaml.safe_load(f)
|
||||
return astute
|
||||
|
||||
|
||||
def astute_get(dct, keys, default=None, fail_if_missing=True):
|
||||
"""A safe dictionary getter"""
|
||||
for key in keys:
|
||||
if key in dct:
|
||||
dct = dct[key]
|
||||
else:
|
||||
if fail_if_missing:
|
||||
reportError('Value of "%s" is missing' % key)
|
||||
return default
|
||||
return dct
|
||||
|
||||
|
||||
def get_options(astute, astute_section=ASTUTE_SECTION):
|
||||
"""Return username and password filled in plugin."""
|
||||
if astute_section not in astute:
|
||||
reportError('%s not found' % astute_section)
|
||||
|
||||
options = astute[astute_section]
|
||||
logging.info('username: {username}'.format(**options))
|
||||
logging.info('password: {password}'.format(**options))
|
||||
logging.info('install_xapi: {install_xapi}'.format(**options))
|
||||
return options['username'], options['password'], \
|
||||
options['install_xapi']
|
||||
|
||||
|
||||
def init_eth():
|
||||
"""Initialize the net interface connected to HIMN
|
||||
|
||||
Returns:
|
||||
the IP addresses of local host and hypervisor.
|
||||
"""
|
||||
|
||||
def _mac(eth):
|
||||
return netifaces.ifaddresses(eth).get(netifaces.AF_LINK)[0]['addr']
|
||||
|
||||
domid = execute('xenstore-read', 'domid')
|
||||
himn_mac = execute(
|
||||
'xenstore-read',
|
||||
'/local/domain/%s/vm-data/himn_mac' % domid)
|
||||
logging.info('himn_mac: %s' % himn_mac)
|
||||
|
||||
eths = [eth for eth in netifaces.interfaces() if _mac(eth) == himn_mac]
|
||||
if len(eths) != 1:
|
||||
reportError('Cannot find eth matches himn_mac')
|
||||
|
||||
eth = eths[0]
|
||||
|
||||
logging.info('himn_eth: %s' % eth)
|
||||
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if not ip:
|
||||
execute('dhclient', eth)
|
||||
fname = '/etc/network/interfaces.d/ifcfg-' + eth
|
||||
s = ('auto {eth}\n'
|
||||
'iface {eth} inet dhcp\n'
|
||||
'post-up route del default dev {eth}').format(eth=eth)
|
||||
with open(fname, 'w') as f:
|
||||
f.write(s)
|
||||
logging.info('%s created' % fname)
|
||||
execute('ifdown', eth)
|
||||
execute('ifup', eth)
|
||||
ip = netifaces.ifaddresses(eth).get(netifaces.AF_INET)
|
||||
|
||||
if ip:
|
||||
himn_local = ip[0]['addr']
|
||||
himn_xs = '.'.join(himn_local.split('.')[:-1] + ['1'])
|
||||
if HIMN_IP == himn_xs:
|
||||
logging.info('himn_local: %s' % himn_local)
|
||||
return eth, himn_local
|
||||
|
||||
reportError('HIMN failed to get IP address from Hypervisor')
|
|
@ -17,9 +17,9 @@ set -eux
|
|||
|
||||
THIS_FILE=$(readlink -f $0)
|
||||
FUELPLUG_UTILS_ROOT=$(dirname $THIS_FILE)
|
||||
cd $FUELPLUG_UTILS_ROOT
|
||||
rm -rf xenserver-suppack
|
||||
mkdir -p xenserver-suppack && cd xenserver-suppack
|
||||
BUILDROOT=${FUELPLUG_UTILS_ROOT}/build
|
||||
rm -rf $BUILDROOT
|
||||
mkdir -p $BUILDROOT && cd $BUILDROOT
|
||||
|
||||
|
||||
# =============================================
|
||||
|
@ -48,66 +48,85 @@ export DEBIAN_FRONTEND=noninteractive
|
|||
|
||||
# =============================================
|
||||
# Install suppack builder
|
||||
RPM_ROOT=http://coltrane.uk.xensource.com/usr/groups/release/XenServer-7.x/XS-7.0/RTM-125380/binary-packages/RPMS/domain0/RPMS/noarch
|
||||
wget $RPM_ROOT/supp-pack-build-2.1.0-xs55.noarch.rpm -O supp-pack-build.rpm
|
||||
wget $RPM_ROOT/xcp-python-libs-1.9.0-159.noarch.rpm -O xcp-python-libs.rpm
|
||||
|
||||
# Don't install the RPM as we may not have root.
|
||||
rpm2cpio supp-pack-build.rpm | cpio -idm
|
||||
rpm2cpio xcp-python-libs.rpm | cpio -idm
|
||||
# Work around dodgy requirements for xcp.supplementalpack.setup function
|
||||
# Note that either root or a virtual env is needed here. venvs are better :)
|
||||
cp -f usr/bin/* .
|
||||
|
||||
# If we are in a venv, we can potentially work with genisoimage and not mkisofs
|
||||
venv_prefix=$(python -c 'import sys; print sys.prefix if hasattr(sys, "real_prefix") else ""')
|
||||
set +e
|
||||
rpm -q supp-pack-build-2.1.0-xs55.noarch &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
rpm -i http://coltrane.uk.xensource.com/usr/groups/release/XenServer-7.x/XS-7.0/RTM-125380/binary-packages/RPMS/domain0/RPMS/noarch/supp-pack-build-2.1.0-xs55.noarch.rpm
|
||||
fi
|
||||
rpm -q xcp-python-libs-1.9.0-159.noarch &> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
rpm -i http://coltrane.uk.xensource.com/usr/groups/release/XenServer-7.x/XS-7.0/RTM-125380/binary-packages/RPMS/domain0/RPMS/noarch/xcp-python-libs-1.9.0-159.noarch.rpm
|
||||
fi
|
||||
mkisofs=`which mkisofs`
|
||||
set -e
|
||||
if [ -n "$venv_prefix" -a -z "$mkisofs" ]; then
|
||||
# Some systems (e.g. debian) only have genisofsimage.
|
||||
set +e
|
||||
genisoimage=`which genisoimage`
|
||||
set -e
|
||||
[ -n "$genisoimage" ] && ln -s $genisoimage $venv_prefix/bin/mkisofs
|
||||
fi
|
||||
|
||||
# Now we must have mkisofs as the supp pack builder just invokes it
|
||||
which mkisofs || (echo "mkisofs not installed" && exit 1)
|
||||
|
||||
# =============================================
|
||||
# Check out rpm packaging repo
|
||||
rm -rf xenserver-nova-suppack-builder
|
||||
git clone $RPM_BUILDER_REPO xenserver-nova-suppack-builder
|
||||
cd xenserver-nova-suppack-builder
|
||||
pushd xenserver-nova-suppack-builder
|
||||
git checkout -b mos_suppack_builder "$GITBRANCH"
|
||||
cd ..
|
||||
popd
|
||||
|
||||
|
||||
# =============================================
|
||||
# Create nova rpm file
|
||||
rm -rf nova
|
||||
git clone "$NOVA_GITREPO" nova
|
||||
cd nova
|
||||
pushd nova
|
||||
git checkout -b mos_nova "$GITBRANCH"
|
||||
# patch xenhost as this file is not merged into this release
|
||||
cp $FUELPLUG_UTILS_ROOT/../plugin_source/deployment_scripts/patchset/xenhost plugins/xenserver/xenapi/etc/xapi.d/plugins/
|
||||
cd ..
|
||||
popd
|
||||
|
||||
cp -r xenserver-nova-suppack-builder/plugins/xenserver/xenapi/* nova/plugins/xenserver/xenapi/
|
||||
cd nova/plugins/xenserver/xenapi/contrib
|
||||
pushd nova/plugins/xenserver/xenapi/contrib
|
||||
./build-rpm.sh $XS_PLUGIN_VERSION
|
||||
cd $FUELPLUG_UTILS_ROOT/
|
||||
RPMFILE=$(find -name "openstack-xen-plugins-*.noarch.rpm" -print)
|
||||
cd xenserver-suppack
|
||||
popd
|
||||
|
||||
RPMFILE=$(find $FUELPLUG_UTILS_ROOT -name "openstack-xen-plugins-*.noarch.rpm" -print)
|
||||
|
||||
|
||||
# =============================================
|
||||
# Create neutron rpm file
|
||||
rm -rf neutron
|
||||
git clone "$NEUTRON_GITREPO" neutron
|
||||
cd neutron
|
||||
pushd neutron
|
||||
git checkout -b mos_neutron "$GITBRANCH"
|
||||
cd ..
|
||||
popd
|
||||
|
||||
cp -r xenserver-nova-suppack-builder/neutron/* \
|
||||
neutron/neutron/plugins/ml2/drivers/openvswitch/agent/xenapi/
|
||||
cd neutron/neutron/plugins/ml2/drivers/openvswitch/agent/xenapi/contrib
|
||||
pushd neutron/neutron/plugins/ml2/drivers/openvswitch/agent/xenapi/contrib
|
||||
./build-rpm.sh $XS_PLUGIN_VERSION
|
||||
cd $FUELPLUG_UTILS_ROOT/
|
||||
popd
|
||||
|
||||
NEUTRON_RPMFILE=$(find -name "openstack-neutron-xen-plugins-*.noarch.rpm" -print)
|
||||
NEUTRON_RPMFILE=$(find $FUELPLUG_UTILS_ROOT -name "openstack-neutron-xen-plugins-*.noarch.rpm" -print)
|
||||
|
||||
|
||||
# =============================================
|
||||
# Create Supplemental pack
|
||||
rm -rf suppack
|
||||
mkdir -p suppack
|
||||
#rm -rf suppack
|
||||
#mkdir -p suppack
|
||||
|
||||
tee buildscript.py << EOF
|
||||
import sys
|
||||
sys.path.append('$BUILDROOT/usr/lib/python2.7/site-packages')
|
||||
from xcp.supplementalpack import *
|
||||
from optparse import OptionParser
|
||||
|
||||
|
@ -133,5 +152,5 @@ python buildscript.py \
|
|||
--pdv=$OS_RELEASE \
|
||||
--bld=0 \
|
||||
--out=$FUELPLUG_UTILS_ROOT \
|
||||
$FUELPLUG_UTILS_ROOT/$RPMFILE \
|
||||
$FUELPLUG_UTILS_ROOT/$NEUTRON_RPMFILE
|
||||
$RPMFILE \
|
||||
$NEUTRON_RPMFILE
|
||||
|
|
Loading…
Reference in New Issue