def _validate_and_retrieve_pre_config(): """ Validate whether the values in the pre-configuration file are valid :return: JSON contents """ if not os.path.exists(PRECONFIG_FILE): return with open(PRECONFIG_FILE, 'r') as pre_config: try: config = json.loads(pre_config.read()) except Exception as ex: print Interactive.boxed_message(['JSON contents could not be retrieved from file {0}.\nError message: {1}'.format(PRECONFIG_FILE, ex)]) sys.exit(1) if 'asdmanager' not in config or not isinstance(config['asdmanager'], dict): print Interactive.boxed_message(['The ASD manager pre-configuration file must contain a "asdmanager" key with a dictionary as value']) sys.exit(1) errors = [] config = config['asdmanager'] actual_keys = config.keys() expected_keys = ['api_ip', 'api_port', 'asd_ips', 'asd_start_port', 'store'] for key in actual_keys: if key not in expected_keys: errors.append('Key {0} is not supported by the ASD manager'.format(key)) if len(errors) > 0: print Interactive.boxed_message(['Errors found while verifying pre-configuration:', ' - {0}'.format('\n - '.join(errors)), '', 'Allowed keys:\n' ' - {0}'.format('\n - '.join(expected_keys))]) sys.exit(1) try: Toolbox.verify_required_params(actual_params=config, required_params={'store': (str, ['arakoon', 'etcd'], False), 'api_ip': (str, Toolbox.regex_ip, True), 'asd_ips': (list, Toolbox.regex_ip, False), 'api_port': (int, {'min': 1025, 'max': 65535}, False), 'asd_start_port': (int, {'min': 1025, 'max': 65435}, False)}) except RuntimeError as rte: print Interactive.boxed_message(['The asd-manager pre-configuration file does not contain correct information\n{0}'.format(rte)]) sys.exit(1) return config
def add_service(name, client, params=None, target_name=None, startup_dependency=None, delay_registration=False): """ Add a service :param name: Template name of the service to add :type name: str :param client: Client on which to add the service :type client: source.tools.localclient.LocalClient :param params: Additional information about the service :type params: dict or None :param target_name: Overrule default name of the service with this name :type target_name: str or None :param startup_dependency: Additional startup dependency :type startup_dependency: str or None :param delay_registration: Register the service parameters in the config management right away or not :type delay_registration: bool :return: Parameters used by the service :rtype: dict """ if params is None: params = {} service_name = Systemd._get_name(name, client, '/opt/asd-manager/config/systemd/') template_file = '/opt/asd-manager/config/systemd/{0}.service'.format(service_name) if not client.file_exists(template_file): # Given template doesn't exist so we are probably using system init scripts return if target_name is not None: service_name = target_name params.update({'SERVICE_NAME': Toolbox.remove_prefix(service_name, 'ovs-'), 'STARTUP_DEPENDENCY': '' if startup_dependency is None else '{0}.service'.format(startup_dependency)}) template_content = client.file_read(template_file) for key, value in params.iteritems(): template_content = template_content.replace('<{0}>'.format(key), value) client.file_write('/lib/systemd/system/{0}.service'.format(service_name), template_content) try: client.run(['systemctl', 'daemon-reload']) client.run(['systemctl', 'enable', '{0}.service'.format(service_name)]) except CalledProcessError as cpe: Systemd._logger.exception('Add {0}.service failed, {1}'.format(service_name, cpe.output)) raise Exception('Add {0}.service failed, {1}'.format(service_name, cpe.output)) if delay_registration is False: Systemd.register_service(service_metadata=params, node_name='') return params
def list(key): """ List all keys starting with specified key :param key: Key to list :type key: str :return: Generator with all keys :rtype: generator """ key = ArakoonConfiguration._clean_key(key) client = ArakoonConfiguration.get_client() entries = [] for entry in client.prefix(key): if key == '' or entry.startswith(key + '/'): cleaned = Toolbox.remove_prefix(entry, key).strip('/').split('/')[0] if cleaned not in entries: entries.append(cleaned) yield cleaned
def add_service(name, client, params=None, target_name=None, startup_dependency=None, delay_registration=False): """ Add a service :param name: Template name of the service to add :type name: str :param client: Client on which to add the service :type client: source.tools.localclient.LocalClient :param params: Additional information about the service :type params: dict or None :param target_name: Overrule default name of the service with this name :type target_name: str or None :param startup_dependency: Additional startup dependency :type startup_dependency: str or None :param delay_registration: Register the service parameters in the config management right away or not :type delay_registration: bool :return: Parameters used by the service :rtype: dict """ if params is None: params = {} service_name = Upstart._get_name(name, client, '/opt/asd-manager/config/upstart/') template_file = '/opt/asd-manager/config/upstart/{0}.conf'.format(service_name) if not client.file_exists(template_file): # Given template doesn't exist so we are probably using system init scripts return if target_name is not None: service_name = target_name params.update({'SERVICE_NAME': Toolbox.remove_prefix(service_name, 'ovs-'), 'STARTUP_DEPENDENCY': '' if startup_dependency is None else 'started {0}'.format(startup_dependency)}) template_content = client.file_read(template_file) for key, value in params.iteritems(): template_content = template_content.replace('<{0}>'.format(key), value) client.file_write('/etc/init/{0}.conf'.format(service_name), template_content) if delay_registration is False: Upstart.register_service(service_metadata=params, node_name='') return params
def get_candidate_versions(client, package_names): """ Retrieve the versions candidate for installation of the packages provided :param client: Root client on which to check the candidate versions :type client: source.tools.localclient.LocalClient :param package_names: Name of the packages to check :type package_names: list :return: Package candidate versions :rtype: dict """ DebianPackage.update(client=client) versions = {} for package_name in package_names: versions[package_name] = '' for line in client.run(['apt-cache', 'policy', package_name, DebianPackage.APT_CONFIG_STRING]).splitlines(): line = line.strip() if line.startswith('Candidate:'): candidate = Toolbox.remove_prefix(line, 'Candidate:').strip() if candidate == '(none)': candidate = '' versions[package_name] = candidate break return versions
def setup(): """ Interactive setup part for initial asd manager configuration with etcd """ print Interactive.boxed_message(['ASD Manager setup']) local_client = LocalClient() service_name = 'asd-manager' print '- Verifying distribution' if ServiceManager.has_service(service_name, local_client): print '' # Spacing print Interactive.boxed_message(['The ASD Manager is already installed.']) sys.exit(1) ipaddresses = check_output("ip a | grep 'inet ' | sed 's/\s\s*/ /g' | cut -d ' ' -f 3 | cut -d '/' -f 1", shell=True).strip().splitlines() ipaddresses = [found_ip.strip() for found_ip in ipaddresses if found_ip.strip() != '127.0.0.1'] if not ipaddresses: print Interactive.boxed_message(['Could not retrieve IP information on current node']) sys.exit(1) config = None preconfig = '/opt/OpenvStorage/config/openvstorage_preconfig.json' run_interactive = True if os.path.exists(preconfig): config = {} with open(preconfig, 'r') as pre_config: try: config = json.load(pre_config) except Exception as ex: raise ValueError('JSON contents could not be retrieved from file {0}.\nErrormessage: {1}'.format(preconfig, ex)) run_interactive = 'asdmanager' not in config if run_interactive is False: asd_preconfig = config['asdmanager'] required = {'api_ip': (str, Toolbox.regex_ip), 'asd_ips': (list, Toolbox.regex_ip, False), 'api_port': (int, {'min': 1025, 'max': 65535}, False), 'asd_start_port': (int, {'min': 1025, 'max': 65435}, False)} Toolbox.verify_required_params(required_params=required, actual_params=asd_preconfig) api_ip = asd_preconfig['api_ip'] api_port = asd_preconfig.get('api_port', 8500) asd_ips = asd_preconfig.get('asd_ips', []) asd_start_port = asd_preconfig.get('asd_start_port', 8600) if api_ip not in ipaddresses: print Interactive.boxed_message(['Unknown API IP provided, please choose from: {0}'.format(', '.join(ipaddresses))]) sys.exit(1) if set(asd_ips).difference(set(ipaddresses)): print Interactive.boxed_message(['Unknown ASD IP provided, please choose from: {0}'.format(', '.join(ipaddresses))]) sys.exit(1) else: api_ip = Interactive.ask_choice(ipaddresses, 'Select the public IP address to be used for the API') api_port = Interactive.ask_integer("Select the port to be used for the API", 1025, 65535, 8500) ipaddresses.append('All') asd_ips = [] add_ips = True while add_ips: current_ips = ' - Current selected IPs: {0}'.format(asd_ips) new_asd_ip = Interactive.ask_choice(ipaddresses, 'Select an IP address or all IP addresses to be used for the ASDs{0}'.format(current_ips if len(asd_ips) > 0 else ''), default_value='All') if new_asd_ip == 'All': ipaddresses.remove('All') asd_ips = [] add_ips = False else: asd_ips.append(new_asd_ip) ipaddresses.remove(new_asd_ip) add_ips = Interactive.ask_yesno("Do you want to add another IP?") asd_start_port = Interactive.ask_integer("Select the port to be used for the ASDs", 1025, 65435, 8600) if api_port in range(asd_start_port, asd_start_port + 100): print Interactive.boxed_message(['API port cannot be in the range of the ASD port + 100']) sys.exit(1) print '- Initializing etcd' try: alba_node_id = EtcdConfiguration.initialize(api_ip, api_port, asd_ips, asd_start_port) except: print '' # Spacing print Interactive.boxed_message(['Could not connect to Etcd.', 'Please make sure an Etcd proxy is available, pointing towards an OpenvStorage cluster.']) sys.exit(1) ServiceManager.add_service(service_name, local_client, params={'ASD_NODE_ID': alba_node_id, 'PORT_NUMBER': str(api_port)}) print '- Starting ASD manager service' try: ServiceManager.start_service(service_name, local_client) except Exception as ex: EtcdConfiguration.uninitialize(alba_node_id) print Interactive.boxed_message(['Starting asd-manager failed with error:', str(ex)]) sys.exit(1) print Interactive.boxed_message(['ASD Manager setup completed'])
def unregister_service(node_name, service_name): """ Un-register the metadata of a service from the configuration management :param node_name: Unused :type node_name: str :param service_name: Name of the service to clean from the configuration management :type service_name: str :return: None """ _ = node_name with open(Toolbox.BOOTSTRAP_FILE, 'r') as bs_file: node_id = json.load(bs_file)['node_id'] Configuration.delete(key='/ovs/alba/asdnodes/{0}/services/{1}'.format(node_id, Toolbox.remove_prefix(service_name, 'ovs-')))
def register_service(node_name, service_metadata): """ Register the metadata of the service to the configuration management :param node_name: Unused :type node_name: str :param service_metadata: Metadata of the service :type service_metadata: dict :return: None """ _ = node_name service_name = service_metadata['SERVICE_NAME'] with open(Toolbox.BOOTSTRAP_FILE, 'r') as bs_file: node_id = json.load(bs_file)['node_id'] Configuration.set(key='/ovs/alba/asdnodes/{0}/services/{1}'.format(node_id, Toolbox.remove_prefix(service_name, 'ovs-')), value=service_metadata)