def property_set(self, property_dict, property_type=GLOBAL_TYPE, change_set=None): # type: (Dict[str,str], str, List[str]) -> None """Set a property :param property_dict: property dictionary containing key / values :type property_dict: dictionary :param property_type: one of 'global', 'group' or 'host' :type property_type: string :param change_set: for group or host sets this is the list of groups or hosts to set the property for :type change_set: list of strings """ ansible_properties = AnsibleProperties() for key, value in property_dict.items(): check_arg(key, u._('Property Key'), str) current_property = ansible_properties.get_property(key) if current_property is not None: current_property_type = current_property.value_type if current_property_type is not str: original_value = value value = yaml.safe_load(value) # this check is to make sure that we can assign an empty # string to a property. without this safe_load will turn # an empty string into a None which is different than an # empty string. if isinstance(original_value, six.string_types)\ and value is None: value = '' if current_property.value is None: current_property_type = None check_arg(value, u._('Property Value'), current_property_type, empty_ok=True) property_dict[key] = value else: check_arg(value, u._('Property Value'), str, empty_ok=True) if type(value) is str and '"' in value: raise InvalidArgument( u._('Cannot use double quotes in ' 'a property value.')) self._check_type(property_type) if property_type is not GLOBAL_TYPE: check_arg(change_set, u._('Change Set'), list, none_ok=True) change_set = safe_decode(change_set) if property_type == GLOBAL_TYPE: ansible_properties.set_property(property_dict) elif property_type == GROUP_TYPE: ansible_properties.set_group_property(property_dict, change_set) else: ansible_properties.set_host_property(property_dict, change_set)
def load_container_info(self): """get the list of containers on the host""" hostname = self.hostname err_msg, output = \ self.inventory.run_ansible_command('-a "docker ps -a"', hostname) if err_msg: msg = 'Error accessing host %s : %s %s' % (hostname, err_msg, output) raise FailedOperation(msg) if not output: msg = ('Host %s is not accessible.' % hostname) raise FailedOperation(msg) else: if '>>' not in output: msg = ('Host: %s. Invalid ansible return data: [%s].' % (hostname, output)) raise FailedOperation(msg) if 'NAMES' not in output: msg = ('Host: %s. Invalid docker ps return data: [%s].' % (hostname, output)) raise FailedOperation(msg) ansible_properties = AnsibleProperties() base_distro = \ ansible_properties.get_property_value('kolla_base_distro') install_type = \ ansible_properties.get_property_value('kolla_install_type') # typically this prefix will be "ol-openstack-" container_prefix = base_distro + '-' + install_type + '-' # process ps output containers = {} # the ps output is after the '>>' output = output.split('>>', 1)[1] LOG.info('docker ps -a on host: %s:\n%s' % (hostname, output)) lines = output.split('\n') for line in lines: tokens = line.split() if len(tokens) < 2: continue cid = tokens[0] image = tokens[1] if container_prefix not in image: # skip non-kolla containers continue name = image.split(container_prefix)[1] name = name.split(':')[0] containers[cid] = name self.container_info = containers
def property_clear(self, property_list, property_type=GLOBAL_TYPE, change_set=None): # type: (List[str], str, List[str]) -> None """Clear a property :param property_list: property list :type property_list: list :param property_type: one of 'global', 'group' or 'host' :type property_type: string :param change_set: for group or host clears this is the list of groups or hosts to clear the property for :type change_set: list of strings """ check_arg(property_list, u._('Property List'), list) property_list = safe_decode(property_list) self._check_type(property_type) if property_type is not GLOBAL_TYPE: check_arg(change_set, u._('Change Set'), list, none_ok=True) change_set = safe_decode(change_set) ansible_properties = AnsibleProperties() if property_type == GLOBAL_TYPE: ansible_properties.clear_property(property_list) elif property_type == GROUP_TYPE: ansible_properties.clear_group_property(property_list, change_set) else: ansible_properties.clear_host_property(property_list, change_set)
def property_get(self, property_type=GLOBAL_TYPE, get_set=None): # type: (str, List[str]) -> List[Property] """Returns a list of Property objects :param property_type: one of 'global', 'group', or 'host' :type property_type: string :param get_set: optional list of hosts or groups to be used when getting group or host related property lists :type get_set: list of strings :return: properties :rtype: list of Property objects """ self._check_type(property_type) get_set = safe_decode(get_set) ansible_properties = AnsibleProperties() result_list = [] if property_type == GLOBAL_TYPE: property_list = ansible_properties.get_all_unique() elif property_type == GROUP_TYPE: property_list = ansible_properties.get_group_list(get_set) else: property_list = ansible_properties.get_host_list(get_set) override_flags = ansible_properties.get_all_override_flags() for prop in property_list: result = Property(prop, override_flags.get(prop.name, None)) result_list.append(result) return result_list
def _run_deploy_rules(self, playbook): properties = AnsibleProperties() inventory = Inventory.load() # cannot have both groups and hosts if playbook.hosts and playbook.groups: raise InvalidArgument( u._('Hosts and Groups arguments cannot ' 'both be present at the same time.')) # verify that all services exists if playbook.services: for service in playbook.services: valid_service = inventory.get_service(service) if not valid_service: raise NotInInventory(u._('Service'), service) # check that every group with enabled services # has hosts associated to it group_services = inventory.get_group_services() failed_groups = [] failed_services = [] if group_services: for (groupname, servicenames) in group_services.items(): group = inventory.get_group(groupname) hosts = group.get_hostnames() group_needs_host = False if not hosts: for servicename in servicenames: if self._is_service_enabled(servicename, inventory, properties): group_needs_host = True failed_services.append(servicename) if group_needs_host: failed_groups.append(groupname) if len(failed_groups) > 0: raise InvalidConfiguration( u._('Deploy failed. ' 'Groups: {groups} with enabled ' 'services : {services} ' 'have no associated hosts').format( groups=failed_groups, services=failed_services))
def _run_deploy_rules(playbook): properties = AnsibleProperties() inventory = Inventory.load() # check that password file has no empty password values empty_keys = get_empty_password_values() if empty_keys: raise InvalidConfiguration( u._('Deploy failed. There are empty password values ' 'in {etc}passwords.yml. ' 'Please run kolla-cli password init or ' 'kolla-cli password set(key) to correct them. ' '\nEmpty passwords: ' '{keys}').format(etc=get_kolla_etc(), keys=empty_keys)) # cannot have both groups and hosts if playbook.hosts and playbook.groups: raise InvalidArgument( u._('Hosts and Groups arguments cannot ' 'both be present at the same time.')) # verify that all services exists if playbook.services: for service in playbook.services: valid_service = inventory.get_service(service) if not valid_service: raise NotInInventory(u._('Service'), service) # check that every group with enabled services # has hosts associated to it group_services = inventory.get_group_services() failed_groups = [] failed_services = [] if group_services: for (groupname, servicenames) in group_services.items(): group = inventory.get_group(groupname) hosts = group.get_hostnames() group_needs_host = False if not hosts: for servicename in servicenames: if _is_service_enabled(servicename, inventory, properties): group_needs_host = True failed_services.append(servicename) if group_needs_host: failed_groups.append(groupname) if len(failed_groups) > 0: raise InvalidConfiguration( u._('Deploy failed. ' 'Groups: {groups} with enabled ' 'services : {services} ' 'have no associated hosts').format( groups=failed_groups, services=failed_services)) # check that ring files are in /etc/kolla/config/swift if # swift is enabled expected_files = ['account.ring.gz', 'container.ring.gz', 'object.ring.gz'] is_swift_enabled = _is_service_enabled('swift', inventory, properties) if is_swift_enabled: path_pre = os.path.join(get_kolla_etc(), 'config', 'swift') for expected_file in expected_files: path = os.path.join(path_pre, expected_file) if not os.path.isfile(path): msg = u._('Deploy failed. ' 'Swift is enabled but ring buffers have ' 'not yet been set up. Please see the ' 'documentation for swift configuration ' 'instructions.') raise InvalidConfiguration(msg)