def print_dev_bottom_up(self, chain=[], node=None, highlight=[], verbose=False): if len(chain) == 0: prev_size = 0 used_s = "-" else: prev_size = self.tree.get_dev(chain[-1].child).size used = chain[-1].get_used(prev_size) used_s = print_size(used) if prev_size == 0: pct = "-" else: pct = "%.2f%%" % (100 * used // self.size) node_dev = node.add_node() node_dev.add_column(self.alias, color.BROWN) node_dev.add_column(self.devtype) node_dev.add_column(used_s, align="right") node_dev.add_column(print_size(self.size), align="right") node_dev.add_column(pct, align="right") if verbose: col = node_dev.add_column() for devpath in self.devpath: if highlight is not None and devpath in highlight: textcolor = color.LIGHTBLUE else: textcolor = None col.add_text(devpath, textcolor) for r in self.parents: dev = self.get_dev(r.parent) dev.print_dev_bottom_up(chain + [r], node_dev, verbose=verbose)
def write_stats(self): with open(self.last_stats_file, "w") as ofile: json.dump(self.stats, ofile) if len(self.stats["targets"]) < 2: return self.log.info("total transfered %s at %s to %d targets", print_size(self.stats["bytes"], unit="B"), print_size(self.stats["speed"], unit="B") + "/s", len(self.stats["targets"]))
def _update_stats(self, data, target=None): self.log.info("transfered %s at %s", print_size(data["bytes"], unit="B"), print_size(data["speed"], unit="B") + "/s") # aggregate stats self.stats["bytes"] += data["bytes"] n_targets = len(self.stats["targets"]) self.stats["speed"] = (data["speed"] * n_targets + data["speed"]) / (n_targets + 1) self.stats["targets"][target] = data
def print_dev(self, relation=None, node=None, highlight=[], verbose=False): if relation is None: parent_size = 0 else: parent_size = self.get_dev(relation.parent).get_size() if parent_size == 0: pct = "-" else: pct = "%.2f%%" % (100 * self.size // parent_size) node_dev = node.add_node() node_dev.add_column(self.alias, color.BROWN) node_dev.add_column(self.devtype) node_dev.add_column(print_size(self.size), align="right") node_dev.add_column(pct, align="right") if verbose: col = node_dev.add_column() for devpath in self.devpath: if highlight is not None and devpath in highlight: textcolor = color.LIGHTBLUE else: textcolor = None col.add_text(devpath, textcolor) for r in self.children: d = self.get_dev(r.child) if d is None: node_unk = node_dev.add_node() node_unk.add_column("%s (unknown)" % r.child) else: d.print_dev(relation=r, node=node_dev, highlight=highlight, verbose=verbose)
def _add_key(self, key, data): if not key: raise ex.excError("secret key name can not be empty") if not data: raise ex.excError("secret value can not be empty") data = "crypt:"+base64.urlsafe_b64encode(self.encrypt(data, cluster_name="join", encode=True)).decode() self.set_multi(["data.%s=%s" % (key, data)]) self.log.info("secret key '%s' added (%s)", key, print_size(len(data), compact=True, unit="b")) # refresh if in use self.postinstall(key)
def _add_key(self, key, data): if not key: raise ex.excError("configuration key name can not be empty") if not data: raise ex.excError("configuration value can not be empty") if not is_string(data): data = "base64:"+bdecode(base64.urlsafe_b64encode(data)) elif "\n" in data: data = "base64:"+bdecode(base64.urlsafe_b64encode(bencode(data))) else: data = "literal:"+data self.set_multi(["data.%s=%s" % (key, data)]) self.log.info("configuration key '%s' added (%s)", key, print_size(len(data), compact=True, unit="b")) # refresh if in use self.postinstall(key)
def fmt_mem_total(get, stats_data): if stats_data is None: return "" mem = 0 for _data in stats_data.values(): try: mem += get(_data) except (KeyError, TypeError) as exc: pass if mem == 0: return " -" try: return print_size(mem, unit="b", compact=True) except Exception: return " -"
def fmt_blk(get, stats_data): if stats_data is None: return "" val = 0 for _data in stats_data.values(): try: val += get(_data) except (KeyError, TypeError) as exc: pass if val == 0: return " -" try: return print_size(val, unit="b", compact=True) except Exception: return " -"
def speed(get, prev_stats, stats): fmt = "%8s" if stats is None: return "" total = 0 for node, _data in stats.items(): try: curr = get(_data) prev = get(prev_stats[node]) interval = _data["timestamp"] - prev_stats[node]["timestamp"] total += (curr - prev) / interval except Exception as exc: raise ValueError if total == 0: return fmt % "-" return fmt % (print_size(total, unit="b", compact=True) + "b/s")
def get_mem_bytes(self): s = '0' source = self.s_default try: s = self.node.conf_get('node', 'mem_bytes') s = str(s/1024/1024) source = self.s_config except (ex.OptNotFound, ex.RequiredOptNotFound): try: s = self._get_mem_bytes() source = self.s_probe except AttributeError: pass return { "title": "mem", "value": s, "source": source, "formatted_value": print_size(s) }
def load_free_total(key): if "monitor" not in data: return line = [ colorize(" " + key, color.BOLD), "", "", "", "", "", "", "", "", "", "", "", "|" if nodenames else "", ] for nodename in nodenames: total = data["monitor"]["nodes"].get(nodename, {}).get( "stats", {}).get(key + "_total") avail = data["monitor"]["nodes"].get(nodename, {}).get( "stats", {}).get(key + "_avail") limit = 100 - data["monitor"]["nodes"].get(nodename, {}).get( "min_avail_" + key, 0) if avail is None or total in (0, None): line.append("-") continue usage = 100 - avail total = print_size(total, unit="MB", compact=True) if limit: cell = "%d/%d%%:%s" % (usage, limit, total) else: cell = "%d%%:%s" % (usage, total) if usage > limit: cell = colorize(cell, color.RED) line.append(cell) out.append(line)
def create_volume(self): volume = factory("vol")(name=self.r.volname, namespace=self.r.svc.namespace, node=self.r.svc.node) if volume.exists(): self.r.log.info("volume %s already exists", self.r.volname) data = volume.print_status_data(mon_data=True) if not data or "cluster" not in data: return volume if not self.r.svc.node.get_pool(volume.pool): raise ex.excError("pool %s not found on this node" % volume.pool) if self.r.svc.options.leader and volume.topology == "failover" and \ (self.owned() or not self.claimed(volume)) and \ data["avail"] != "up" and data["cluster"]["avail"] == "up": self.r.log.info( "volume %s is up on peer, we are leader: take it over", self.r.volname) volume.action("takeover", options={"wait": True, "time": 60}) return volume elif not self.r.svc.options.leader: self.r.log.info( "volume %s does not exist, we are not leader: wait its propagation", self.r.volname) self.r.wait_for_fn( lambda: volume.exists(), 10, 1, "non leader instance waited for too long for the " "volume to appear") return volume pooltype = self.r.oget("type") self.r.log.info( "create new volume %s (pool name: %s, pool type: %s, " "access: %s, size: %s, format: %s, shared: %s)", self.r.volname, self.r.pool, pooltype, self.r.access, print_size(self.r.size, unit="B", compact=True), self.r.format, self.r.shared) pool = self.r.svc.node.find_pool(poolname=self.r.pool, pooltype=pooltype, access=self.r.access, size=self.r.size, fmt=self.r.format, shared=self.r.shared) if pool is None: raise ex.excError("could not find a pool matching criteria") pool.log = self.r.log try: nodes = self.r.svc._get("DEFAULT.nodes") except ex.OptNotFound: nodes = None env = {} for mapping in pool.volume_env: try: src, dst = mapping.split(":", 1) except Exception: continue args = src.split(".", 1) val = self.r.svc.oget(*args) if val is None: raise ex.excError("missing mapped key in %s: %s" % (self.r.svc.path, mapping)) if is_string(val) and ".." in val: raise ex.excError( "the '..' substring is forbidden in volume env keys: %s=%s" % (mapping, val)) env[dst] = val pool.configure_volume(volume, fmt=self.r.format, size=self.r.size, access=self.r.access, nodes=nodes, shared=self.r.shared, env=env) volume = factory("vol")(name=self.r.volname, namespace=self.r.svc.namespace, node=self.r.svc.node) return volume