def check_host_compatibility(himn, username): xcp_version = utils.get_xcp_version(himn, username) if LooseVersion(xcp_version) < LooseVersion(MIN_XCP_VERSION): utils.reportError('Platform version %s should equal or greater than %s' % (xcp_version, MIN_XCP_VERSION)) return version_hotfixes = json.loads(VERSION_HOTFIXES) ver = utils.ssh(himn, username, ('xe host-param-get uuid=$(xe host-list --minimal) ' 'param-name=software-version param-key=product_version')) hotfixes = version_hotfixes.get(ver) if not hotfixes: return for hotfix in hotfixes: if not hotfix: continue installed = utils.ssh(himn, username, 'xe patch-list name-label=%s --minimal' % hotfix) if not installed: utils.reportError('Hotfix %s has not been installed ' % ver)
def mod_ceilometer(): rc, out, err = utils.detailed_execute('pcs', 'resource', 'show', 'p_ceilometer-agent-central', allowed_return_codes=[0, 1]) """Wait until all ocf resources are started, otherwise there is risk for race condition: If run "pcs resource restart" while some resources are still in restarting or initiating stage, it may result into failures for both. """ if rc == 0: wait_ocf_resource_started(300, 10) LOG.info("Patching ceilometer pipeline.yaml to exclude \ network.servers.*") # Exclude network.services.* to avoid error 404 pipeline = '/etc/ceilometer/pipeline.yaml' if not os.path.exists(pipeline): utils.reportError('%s not found' % pipeline) with open(pipeline) as f: ceilometer = yaml.safe_load(f) sources = utils.astute_get(ceilometer, ('sources', )) if len(sources) != 1: utils.reportError('ceilometer has none or more than one sources') source = sources[0] meters = utils.astute_get(source, ('meters', )) new_meter = '!network.services.*' if new_meter not in meters: meters.append(new_meter) with open(pipeline, "w") as f: ceilometer = yaml.safe_dump(ceilometer, f) restart_info = utils.execute('pcs', 'resource', 'restart', 'p_ceilometer-agent-central') LOG.info(restart_info)
def install_suppack(himn, username, package, xcp_version): """Install xapi driver supplemental pack. """ tmp = utils.ssh(himn, username, 'mktemp', '-d') real_pack = "xcp_%s/%s" % (xcp_version, package) if not os.path.exists(real_pack): utils.reportError('Package folder %s not exist' % real_pack) utils.scp(himn, username, tmp, real_pack) if LooseVersion(xcp_version) < LooseVersion('2.2.0'): utils.ssh(himn, username, 'xe-install-supplemental-pack', tmp + '/' + package, prompt='Y\n') else: errcode, uuid, errmsg = \ utils.ssh_detailed(himn, username, 'xe', 'update-upload', 'file-name=' + tmp + '/' + package, allowed_return_codes=[0, 1]) if errcode == 0: utils.ssh(himn, username, 'xe', 'update-apply', 'uuid=' + uuid.strip()) else: LOG.debug("Install supplemental pack failed, err: %s", errmsg) if "The uploaded update already exists" in errmsg: uuid = parse_uuid(errmsg) if uuid is None: raise utils.ExecutionError(errmsg) # Check current update is applied already out = utils.ssh(himn, username, 'xe', 'update-list', 'uuid=' + uuid, '--minimal') # Apply this update if cannot find it with uuid if not out: utils.ssh(himn, username, 'xe', 'update-apply', 'uuid=' + uuid) utils.ssh(himn, username, 'rm', tmp, '-rf')
def mod_ceilometer(): rc, out, err = utils.detailed_execute( 'pcs', 'resource', 'show', 'p_ceilometer-agent-central', allowed_return_codes=[0, 1]) """Wait until all ocf resources are started, otherwise there is risk for race condition: If run "pcs resource restart" while some resources are still in restarting or initiating stage, it may result into failures for both. """ if rc == 0: wait_ocf_resource_started(300, 10) LOG.info("Patching ceilometer pipeline.yaml to exclude \ network.servers.*") # Exclude network.services.* to avoid error 404 pipeline = '/etc/ceilometer/pipeline.yaml' if not os.path.exists(pipeline): utils.reportError('%s not found' % pipeline) with open(pipeline) as f: ceilometer = yaml.safe_load(f) sources = utils.astute_get(ceilometer, ('sources',)) if len(sources) != 1: utils.reportError('ceilometer has none or more than one sources') source = sources[0] meters = utils.astute_get(source, ('meters',)) new_meter = '!network.services.*' if new_meter not in meters: meters.append(new_meter) with open(pipeline, "w") as f: ceilometer = yaml.safe_dump(ceilometer, f) restart_info = utils.execute( 'pcs', 'resource', 'restart', 'p_ceilometer-agent-central') LOG.info(restart_info)
def check_local_sr(himn, username): 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": 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.'))
def modify_neutron_rootwrap_conf(himn, username, password): """Set xenapi configurations""" filename = '/etc/neutron/rootwrap.conf' cf = ConfigParser.ConfigParser() try: cf.read(filename) cf.set('xenapi', 'xenapi_connection_url', 'http://%s' % himn) cf.set('xenapi', 'xenapi_connection_username', username) cf.set('xenapi', 'xenapi_connection_password', password) with open(filename, 'w') as configfile: cf.write(configfile) except Exception: utils.reportError("Fail to modify file %s", filename) LOG.info('Modify file %s successfully', filename)
def find_dom0_bridge(himn, username, bridge_name): ethX = get_network_ethX(bridge_name) if not ethX: utils.reportError("Cannot find eth used for private network") ethX = ethX.split('.')[0] # 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 = 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) return bridge
def modify_neutron_ovs_agent_conf(int_br, br_mappings): filename = '/etc/neutron/plugins/ml2/openvswitch_agent.ini' cf = ConfigParser.ConfigParser() try: cf.read(filename) cf.set('agent', 'root_helper', 'neutron-rootwrap-xen-dom0 /etc/neutron/rootwrap.conf') cf.set('agent', 'root_helper_daemon', '') cf.set('agent', 'minimize_polling', False) cf.set('ovs', 'integration_bridge', int_br) cf.set('ovs', 'bridge_mappings', br_mappings) with open(filename, 'w') as configfile: cf.write(configfile) except Exception: utils.reportError("Fail to modify %s", filename) LOG.info('Modify %s successfully', filename)
def wait_ocf_resource_started(timeout, interval): """Wait until all ocf resources are started""" LOG.info("Waiting for all ocf resources to start") remain_time = timeout while remain_time > 0: resources = utils.execute('pcs', 'resource', 'show') if resources: exists_not_started = any([("Started" not in line) for line in resources.split('\n') if "ocf::fuel" in line]) # All started if not exists_not_started: return sleep(interval) remain_time = timeout - interval utils.reportError("Timeout for waiting resources to start")
def install_image_cache_cleanup(): tool_path = '/usr/bin/destroy_cached_images' tool_conf = '/etc/nova/nova-compute.conf' # install this tool. try: src_file = 'tools/destroy_cached_images.py' target_file = tool_path shutil.copy(src_file, target_file) os.chown(target_file, 0, 0) os.chmod(target_file, stat.S_IRWXU) except Exception: utils.reportError("Failed to install file %s" % target_file) # create a daily clean-up cron job cron_entry = '5 3 * * * {} --config-file={} >/dev/null 2>&1'.format( tool_path, tool_conf) user = '******' utils.add_cron_job(user, cron_entry) LOG.info('Added crontab successfully: %s' % cron_entry)
def find_bridge_mappings(astute, himn, username): ethX = get_private_network_ethX() if not ethX: 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 = 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'] physnet = phynet_setting.keys()[0] return physnet + ':' + bridge
def check_host_compatibility(himn, username): version_hotfixes = json.loads(VERSION_HOTFIXES) ver = utils.ssh(himn, username, ('xe host-param-get uuid=$(xe host-list --minimal) ' 'param-name=software-version param-key=product_version')) hotfixes = version_hotfixes.get(ver) if not hotfixes: return for hotfix in hotfixes: if not hotfix: continue installed = utils.ssh(himn, username, 'xe patch-list name-label=%s --minimal' % hotfix) if not installed: utils.reportError('Hotfix %s has not been installed ' % ver)
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): utils.reportError("The file: %s doesn't exist" % filename) return patch_ceilometer() cf = ConfigParser.ConfigParser() try: cf.read(filename) cf.set('DEFAULT', 'hypervisor_inspector', 'xenapi') cf.set('xenapi', 'connection_url', 'http://%s' % himn) cf.set('xenapi', 'connection_username', username) cf.set('xenapi', 'connection_password', password) with open(filename, 'w') as configfile: cf.write(configfile) LOG.info('Modify file %s successfully', filename) except Exception: utils.reportError("Fail to modify file %s", filename) return restart_services('ceilometer-polling')
def create_novacompute_conf(himn, username, password, public_ip, services_ssl): """Fill nova-compute.conf with HIMN IP and root password. """ mgmt_if = netifaces.ifaddresses('br-mgmt') if mgmt_if and mgmt_if.get(netifaces.AF_INET) \ and mgmt_if.get(netifaces.AF_INET)[0]['addr']: mgmt_ip = mgmt_if.get(netifaces.AF_INET)[0]['addr'] else: utils.reportError('Cannot get IP Address on Management Network') filename = '/etc/nova/nova-compute.conf' cf = ConfigParser.ConfigParser() try: cf.read(filename) cf.set('DEFAULT', 'compute_driver', 'xenapi.XenAPIDriver') cf.set('DEFAULT', 'force_config_drive', 'True') if not cf.has_section('vnc'): cf.add_section('vnc') scheme = "https" if services_ssl else "http" cf.set('vnc', 'novncproxy_base_url', '%s://%s:6080/vnc_auto.html' % (scheme, public_ip)) cf.set('vnc', 'vncserver_proxyclient_address', mgmt_ip) if not cf.has_section('xenserver'): cf.add_section('xenserver') cf.set('xenserver', 'connection_url', 'http://%s' % himn) cf.set('xenserver', 'connection_username', username) cf.set('xenserver', 'connection_password', password) cf.set('xenserver', 'vif_driver', 'nova.virt.xenapi.vif.XenAPIOpenVswitchDriver') cf.set('xenserver', 'ovs_integration_bridge', INT_BRIDGE) cf.set('xenserver', 'cache_images', 'none') with open(filename, 'w') as configfile: cf.write(configfile) except Exception: utils.reportError('Cannot set configurations to %s' % filename) LOG.info('%s created' % filename)
def create_novacompute_conf(himn, username, password, public_ip, services_ssl): """Fill nova-compute.conf with HIMN IP and root password. """ mgmt_if = netifaces.ifaddresses('br-mgmt') if mgmt_if and mgmt_if.get(netifaces.AF_INET) \ and mgmt_if.get(netifaces.AF_INET)[0]['addr']: mgmt_ip = mgmt_if.get(netifaces.AF_INET)[0]['addr'] else: utils.reportError('Cannot get IP Address on Management Network') filename = '/etc/nova/nova-compute.conf' cf = ConfigParser.ConfigParser() try: cf.read(filename) cf.set('DEFAULT', 'compute_driver', 'xenapi.XenAPIDriver') cf.set('DEFAULT', 'force_config_drive', 'True') if not cf.has_section('vnc'): cf.add_section('vnc') scheme = "https" if services_ssl else "http" cf.set('vnc', 'novncproxy_base_url', '%s://%s:6080/vnc_auto.html' % (scheme, public_ip)) cf.set('vnc', 'vncserver_proxyclient_address', mgmt_ip) if not cf.has_section('xenserver'): cf.add_section('xenserver') cf.set('xenserver', 'connection_url', 'http://%s' % himn) cf.set('xenserver', 'connection_username', username) cf.set('xenserver', 'connection_password', password) cf.set('xenserver', 'vif_driver', 'nova.virt.xenapi.vif.XenAPIOpenVswitchDriver') cf.set('xenserver', 'ovs_integration_bridge', INT_BRIDGE) cf.set('xenserver', 'cache_images', 'all') with open(filename, 'w') as configfile: cf.write(configfile) except Exception: utils.reportError('Cannot set configurations to %s' % filename) LOG.info('%s created' % filename)
def mod_novnc(): astute = utils.get_astute() if astute: filename = '/etc/nova/nova.conf' orig_filename = filename + ".orig" if not os.path.exists(orig_filename): shutil.copyfile(filename, orig_filename) cf = ConfigParser.ConfigParser() try: cf.read(orig_filename) if not cf.has_section('cache'): cf.add_section('cache') cf.set('cache', 'enable', 'True') memcached_servers = cf.get('keystone_authtoken', 'memcached_servers') cf.set('cache', 'memcached_servers', memcached_servers) cf.set('DEFAULT', 'memcached_servers', memcached_servers) with open(filename, 'w') as configfile: cf.write(configfile) LOG.info('%s created' % filename) utils.execute('service', 'nova-novncproxy', 'restart') utils.execute('service', 'nova-consoleauth', 'restart') except Exception: utils.reportError('Cannot set configurations to %s' % filename)