def _process_pending_results(self, iterator, one_pass=False, max_passes=None): if not hasattr(self, "curr_host"): return super(StrategyModule, self)._process_pending_results(iterator, one_pass, max_passes) prev_host_state = iterator.get_host_state(self.curr_host) results = super(StrategyModule, self)._process_pending_results(iterator, one_pass) while self._need_debug(results): next_action = NextAction() dbg = Debugger(self, results, next_action) dbg.cmdloop() if next_action.result == NextAction.REDO: # rollback host state self.curr_tqm.clear_failed_hosts() iterator._host_states[self.curr_host.name] = prev_host_state if reduce(lambda total, res: res.is_failed() or total, results, False): self._tqm._stats.failures[self.curr_host.name] -= 1 elif reduce(lambda total, res: res.is_unreachable() or total, results, False): self._tqm._stats.dark[self.curr_host.name] -= 1 # redo super(StrategyModule, self)._queue_task(self.curr_host, self.curr_task, self.curr_task_vars, self.curr_play_context) results = super(StrategyModule, self)._process_pending_results(iterator, one_pass) elif next_action.result == NextAction.CONTINUE: break elif next_action.result == NextAction.EXIT: exit(1) return results
def get_cpu_facts(self): cpu_facts = {} i = 0 physid = 0 sockets = {} if not os.access("/proc/cpuinfo", os.R_OK): return cpu_facts cpu_facts['processor'] = [] for line in get_file_lines("/proc/cpuinfo"): data = line.split(":", 1) key = data[0].strip() # model name is for Intel arch, Processor (mind the uppercase P) # works for some ARM devices, like the Sheevaplug. if key == 'model name' or key == 'Processor': if 'processor' not in cpu_facts: cpu_facts['processor'] = [] cpu_facts['processor'].append(data[1].strip()) i += 1 elif key == 'physical id': physid = data[1].strip() if physid not in sockets: sockets[physid] = 1 elif key == 'cpu cores': sockets[physid] = int(data[1].strip()) if len(sockets) > 0: cpu_facts['processor_count'] = len(sockets) cpu_facts['processor_cores'] = reduce(lambda x, y: x + y, sockets.values()) else: cpu_facts['processor_count'] = i cpu_facts['processor_cores'] = 'NA' return cpu_facts
def secondsToStr(t): # http://bytes.com/topic/python/answers/635958-handy-short-cut-formatting-elapsed-time-floating-point-seconds def rediv(ll, b): return list(divmod(ll[0], b)) + ll[1:] return "%d:%02d:%02d.%03d" % tuple( reduce(rediv, [[t * 1000, ], 1000, 60, 60]))
def get_candidate_disks(self, disk_count, size_unit='gb', capacity=None): self.debug("getting candidate disks...") drives_req = dict( driveCount=disk_count, sizeUnit=size_unit, driveType='ssd', ) if capacity: drives_req['targetUsableCapacity'] = capacity (rc, drives_resp) = request(self.api_url + "/storage-systems/%s/drives" % (self.ssid), data=json.dumps(drives_req), headers=self.post_headers, method='POST', url_username=self.api_username, url_password=self.api_password, validate_certs=self.validate_certs) if rc == 204: self.module.fail_json( msg= 'Cannot find disks to match requested criteria for ssd cache') disk_ids = [d['id'] for d in drives_resp] bytes = reduce(lambda s, d: s + int(d['usableCapacity']), drives_resp, 0) return (disk_ids, bytes)
def get_cpu_facts(self): cpu_facts = {} i = 0 physid = 0 sockets = {} if not os.access("/proc/cpuinfo", os.R_OK): return cpu_facts cpu_facts['processor'] = [] for line in get_file_lines("/proc/cpuinfo"): data = line.split(":", 1) key = data[0].strip() # model name is for Intel arch, Processor (mind the uppercase P) # works for some ARM devices, like the Sheevaplug. if key == 'model name' or key == 'Processor': if 'processor' not in cpu_facts: cpu_facts['processor'] = [] cpu_facts['processor'].append(data[1].strip()) i += 1 elif key == 'physical id': physid = data[1].strip() if physid not in sockets: sockets[physid] = 1 elif key == 'cpu cores': sockets[physid] = int(data[1].strip()) if len(sockets) > 0: cpu_facts['processor_count'] = len(sockets) cpu_facts['processor_cores'] = reduce(lambda x, y: x + y, sockets.values()) else: cpu_facts['processor_count'] = i cpu_facts['processor_cores'] = 'NA' return cpu_facts
def secondsToStr(t): def rediv(ll, b): return list(divmod(ll[0], b)) + ll[1:] return "%d:%02d:%02d.%03d" % tuple( reduce(rediv, [[ t * 1000, ], 1000, 60, 60]))
def get_var(self, *keys, **kwargs): """Get deeply nested values from task_vars. Ansible task_vars structures are Python dicts, often mapping strings to other dicts. This helper makes it easier to get a nested value, raising OpenShiftCheckException when a key is not found. Keyword args: default: On missing key, return this as default value instead of raising exception. convert: Supply a function to apply to normalize the value before returning it. None is the default (return as-is). This function should raise ValueError if the user has provided a value that cannot be converted, or OpenShiftCheckException if some other problem needs to be described to the user. """ if len(keys) == 1: keys = keys[0].split(".") try: value = reduce(operator.getitem, keys, self.task_vars) except (KeyError, TypeError): if "default" not in kwargs: raise OpenShiftCheckException( "This check expects the '{}' inventory variable to be defined\n" "in order to proceed, but it is undefined. There may be a bug\n" "in Ansible, the checks, or their dependencies." "".format(".".join(map(str, keys))) ) value = kwargs["default"] convert = kwargs.get("convert", None) try: if convert is None: return value elif convert is bool: # interpret bool as Ansible does, instead of python truthiness return ansible_to_bool(value) else: return convert(value) except ValueError as error: # user error in specifying value raise OpenShiftCheckException( 'Cannot convert inventory variable to expected type:\n' ' "{var}={value}"\n' '{error}'.format(var=".".join(keys), value=value, error=error) ) except OpenShiftCheckException: # some other check-specific problem raise except Exception as error: # probably a bug in the function raise OpenShiftCheckException( 'There is a bug in this check. While trying to convert variable \n' ' "{var}={value}"\n' 'the given converter cannot be used or failed unexpectedly:\n' '{error}'.format(var=".".join(keys), value=value, error=error) )
def get_var(self, *keys, **kwargs): """Get deeply nested values from task_vars. Ansible task_vars structures are Python dicts, often mapping strings to other dicts. This helper makes it easier to get a nested value, raising OpenShiftCheckException when a key is not found. Keyword args: default: On missing key, return this as default value instead of raising exception. convert: Supply a function to apply to normalize the value before returning it. None is the default (return as-is). This function should raise ValueError if the user has provided a value that cannot be converted, or OpenShiftCheckException if some other problem needs to be described to the user. """ if len(keys) == 1: keys = keys[0].split(".") try: value = reduce(operator.getitem, keys, self.task_vars) except (KeyError, TypeError): if "default" not in kwargs: raise OpenShiftCheckException( "This check expects the '{}' inventory variable to be defined\n" "in order to proceed, but it is undefined. There may be a bug\n" "in Ansible, the checks, or their dependencies." "".format(".".join(map(str, keys)))) value = kwargs["default"] convert = kwargs.get("convert", None) try: if convert is None: return value elif convert is bool: # interpret bool as Ansible does, instead of python truthiness return ansible_to_bool(value) else: return convert(value) except ValueError as error: # user error in specifying value raise OpenShiftCheckException( 'Cannot convert inventory variable to expected type:\n' ' "{var}={value}"\n' '{error}'.format(var=".".join(keys), value=value, error=error)) except OpenShiftCheckException: # some other check-specific problem raise except Exception as error: # probably a bug in the function raise OpenShiftCheckException( 'There is a bug in this check. While trying to convert variable \n' ' "{var}={value}"\n' 'the given converter cannot be used or failed unexpectedly:\n' '{type}: {error}'.format(var=".".join(keys), value=value, type=error.__class__.__name__, error=error))
def get_cpu_facts(self, collected_facts=None): physid = 0 sockets = {} cpu_facts = {} collected_facts = collected_facts or {} rc, out, err = self.module.run_command("/usr/bin/kstat cpu_info") cpu_facts['processor'] = [] for line in out.splitlines(): if len(line) < 1: continue data = line.split(None, 1) key = data[0].strip() # "brand" works on Solaris 10 & 11. "implementation" for Solaris 9. if key == 'module:': brand = '' elif key == 'brand': brand = data[1].strip() elif key == 'clock_MHz': clock_mhz = data[1].strip() elif key == 'implementation': processor = brand or data[1].strip() # Add clock speed to description for SPARC CPU # FIXME if collected_facts.get('ansible_machine') != 'i86pc': processor += " @ " + clock_mhz + "MHz" if 'ansible_processor' not in collected_facts: cpu_facts['processor'] = [] cpu_facts['processor'].append(processor) elif key == 'chip_id': physid = data[1].strip() if physid not in sockets: sockets[physid] = 1 else: sockets[physid] += 1 # Counting cores on Solaris can be complicated. # https://blogs.oracle.com/mandalika/entry/solaris_show_me_the_cpu # Treat 'processor_count' as physical sockets and 'processor_cores' as # virtual CPUs visisble to Solaris. Not a true count of cores for modern SPARC as # these processors have: sockets -> cores -> threads/virtual CPU. if len(sockets) > 0: cpu_facts['processor_count'] = len(sockets) cpu_facts['processor_cores'] = reduce(lambda x, y: x + y, sockets.values()) else: cpu_facts['processor_cores'] = 'NA' cpu_facts['processor_count'] = len(cpu_facts['processor']) return cpu_facts
def get_cpu_facts(self, collected_facts=None): physid = 0 sockets = {} cpu_facts = {} collected_facts = collected_facts or {} rc, out, err = self.module.run_command("/usr/bin/kstat cpu_info") cpu_facts['processor'] = [] for line in out.splitlines(): if len(line) < 1: continue data = line.split(None, 1) key = data[0].strip() # "brand" works on Solaris 10 & 11. "implementation" for Solaris 9. if key == 'module:': brand = '' elif key == 'brand': brand = data[1].strip() elif key == 'clock_MHz': clock_mhz = data[1].strip() elif key == 'implementation': processor = brand or data[1].strip() # Add clock speed to description for SPARC CPU # FIXME if collected_facts.get('ansible_machine') != 'i86pc': processor += " @ " + clock_mhz + "MHz" if 'ansible_processor' not in collected_facts: cpu_facts['processor'] = [] cpu_facts['processor'].append(processor) elif key == 'chip_id': physid = data[1].strip() if physid not in sockets: sockets[physid] = 1 else: sockets[physid] += 1 # Counting cores on Solaris can be complicated. # https://blogs.oracle.com/mandalika/entry/solaris_show_me_the_cpu # Treat 'processor_count' as physical sockets and 'processor_cores' as # virtual CPUs visisble to Solaris. Not a true count of cores for modern SPARC as # these processors have: sockets -> cores -> threads/virtual CPU. if len(sockets) > 0: cpu_facts['processor_count'] = len(sockets) cpu_facts['processor_cores'] = reduce(lambda x, y: x + y, sockets.values()) else: cpu_facts['processor_cores'] = 'NA' cpu_facts['processor_count'] = len(cpu_facts['processor']) return cpu_facts
def change_instance_state(module, gce, instance_names, number, zone, state): """Changes the state of a list of instances. For example, change from started to stopped, or started to absent. module: Ansible module object gce: authenticated GCE connection object instance_names: a list of instance names to terminate zone: GCEZone object where the instances reside prior to termination state: 'state' parameter passed into module as argument Returns a dictionary of instance names that were changed. """ changed = False nodes = [] state_instance_names = [] if isinstance(instance_names, str) and number: node_names = ['%s-%03d' % (instance_names, i) for i in range(number)] elif isinstance(instance_names, str) and not number: node_names = [instance_names] else: node_names = instance_names for name in node_names: inst = None try: inst = gce.ex_get_node(name, zone) except ResourceNotFoundError: state_instance_names.append(name) except Exception as e: module.fail_json(msg=unexpected_error_msg(e), changed=False) else: nodes.append(inst) state_instance_names.append(name) if state in ['absent', 'deleted'] and number: changed_nodes = gce.ex_destroy_multiple_nodes(nodes) or [False] changed = reduce(lambda x, y: x or y, changed_nodes) else: for node in nodes: if state in ['absent', 'deleted']: gce.destroy_node(node) changed = True elif state == 'started' and node.state == libcloud.compute.types.NodeState.STOPPED: gce.ex_start_node(node) changed = True elif state in [ 'stopped', 'terminated' ] and node.state == libcloud.compute.types.NodeState.RUNNING: gce.ex_stop_node(node) changed = True return (changed, state_instance_names)
def change_instance_state(module, gce, instance_names, number, zone, state): """Changes the state of a list of instances. For example, change from started to stopped, or started to absent. module: Ansible module object gce: authenticated GCE connection object instance_names: a list of instance names to terminate zone: GCEZone object where the instances reside prior to termination state: 'state' parameter passed into module as argument Returns a dictionary of instance names that were changed. """ changed = False nodes = [] state_instance_names = [] if isinstance(instance_names, str) and number: node_names = ['%s-%03d' % (instance_names, i) for i in range(number)] elif isinstance(instance_names, str) and not number: node_names = [instance_names] else: node_names = instance_names for name in node_names: inst = None try: inst = gce.ex_get_node(name, zone) except ResourceNotFoundError: state_instance_names.append(name) except Exception as e: module.fail_json(msg=unexpected_error_msg(e), changed=False) else: nodes.append(inst) state_instance_names.append(name) if state in ['absent', 'deleted'] and number: changed_nodes = gce.ex_destroy_multiple_nodes(nodes) or [False] changed = reduce(lambda x, y: x or y, changed_nodes) else: for node in nodes: if state in ['absent', 'deleted']: gce.destroy_node(node) changed = True elif state == 'started' and \ node.state == libcloud.compute.types.NodeState.STOPPED: gce.ex_start_node(node) changed = True elif state in ['stopped', 'terminated'] and \ node.state == libcloud.compute.types.NodeState.RUNNING: gce.ex_stop_node(node) changed = True return (changed, state_instance_names)
def _process_pending_results(self, iterator, one_pass=False, max_passes=None): if not hasattr(self, "curr_host"): return super(StrategyModule, self)._process_pending_results( iterator, one_pass, max_passes) prev_host_state = iterator.get_host_state(self.curr_host) results = super(StrategyModule, self)._process_pending_results(iterator, one_pass) while self._need_debug(results): next_action = NextAction() dbg = Debugger(self, results, next_action) dbg.cmdloop() if next_action.result == NextAction.REDO: # rollback host state self.curr_tqm.clear_failed_hosts() iterator._host_states[self.curr_host.name] = prev_host_state if reduce(lambda total, res: res.is_failed() or total, results, False): self._tqm._stats.failures[self.curr_host.name] -= 1 elif reduce(lambda total, res: res.is_unreachable() or total, results, False): self._tqm._stats.dark[self.curr_host.name] -= 1 # redo super(StrategyModule, self)._queue_task(self.curr_host, self.curr_task, self.curr_task_vars, self.curr_play_context) results = super(StrategyModule, self)._process_pending_results( iterator, one_pass) elif next_action.result == NextAction.CONTINUE: break elif next_action.result == NextAction.EXIT: exit(1) return results
def combine(*terms, **kwargs): recursive = kwargs.get('recursive', False) if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs): raise errors.AnsibleFilterError("'recursive' is the only valid keyword argument") for t in terms: if not isinstance(t, dict): raise errors.AnsibleFilterError("|combine expects dictionaries, got " + repr(t)) if recursive: return reduce(merge_hash, terms) else: return dict(itertools.chain(*map(iteritems, terms)))
def combine(*terms, **kwargs): recursive = kwargs.get('recursive', False) if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs): raise errors.AnsibleFilterError("'recursive' is the only valid keyword argument") for t in terms: if not isinstance(t, dict): raise errors.AnsibleFilterError("|combine expects dictionaries, got " + repr(t)) if recursive: return reduce(merge_hash, terms) else: return dict(itertools.chain(*map(iteritems, terms)))
def extract(item, container, morekeys=None): from jinja2.runtime import Undefined value = container[item] if value is not Undefined and morekeys is not None: if not isinstance(morekeys, list): morekeys = [morekeys] try: value = reduce(lambda d, k: d[k], morekeys, value) except KeyError: value = Undefined() return value
def get_var(task_vars, *keys, **kwargs): """Helper function to get deeply nested values from task_vars. Ansible task_vars structures are Python dicts, often mapping strings to other dicts. This helper makes it easier to get a nested value, raising OpenShiftCheckException when a key is not found or returning a default value provided as a keyword argument. """ try: value = reduce(operator.getitem, keys, task_vars) except (KeyError, TypeError): if "default" in kwargs: return kwargs["default"] raise OpenShiftCheckException("'{}' is undefined".format(".".join(map(str, keys)))) return value
def get_var(task_vars, *keys, **kwargs): """Helper function to get deeply nested values from task_vars. Ansible task_vars structures are Python dicts, often mapping strings to other dicts. This helper makes it easier to get a nested value, raising OpenShiftCheckException when a key is not found. """ try: value = reduce(operator.getitem, keys, task_vars) except (KeyError, TypeError): if "default" in kwargs: return kwargs["default"] raise OpenShiftCheckException("'{}' is undefined".format(".".join( map(str, keys)))) return value
def extract(item, container, morekeys=None): from jinja2.runtime import Undefined value = container[item] if value is not Undefined and morekeys is not None: if not isinstance(morekeys, list): morekeys = [morekeys] try: value = reduce(lambda d, k: d[k], morekeys, value) except KeyError: value = Undefined() return value
def combine(*terms, **kwargs): recursive = kwargs.get('recursive', False) if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs): raise AnsibleFilterError("'recursive' is the only valid keyword argument") dicts = [] for t in terms: if isinstance(t, MutableMapping): dicts.append(t) elif isinstance(t, list): dicts.append(combine(*t, **kwargs)) else: raise AnsibleFilterError("|combine expects dictionaries, got " + repr(t)) if recursive: return reduce(merge_hash, dicts) else: return dict(itertools.chain(*map(iteritems, dicts)))
def combine(*terms, **kwargs): recursive = kwargs.get('recursive', False) if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs): raise AnsibleFilterError("'recursive' is the only valid keyword argument") dicts = [] for t in terms: if isinstance(t, MutableMapping): dicts.append(t) elif isinstance(t, list): dicts.append(combine(*t, **kwargs)) else: raise AnsibleFilterError("|combine expects dictionaries, got " + repr(t)) if recursive: return reduce(merge_hash, dicts) else: return dict(itertools.chain(*map(iteritems, dicts)))
def _need_debug(self, results): return reduce( lambda total, res: res.is_failed() or res.is_unreachable() or total, results, False)
def _need_debug(self, results): return reduce(lambda total, res: res.is_failed() or res.is_unreachable() or total, results, False)