def build_services(status=None, paths=None, create_instance=False, node=None): """ Returns a list of all services of status matching the specified status. If no status is specified, returns all services. """ if paths is None: paths = [] errors = [] services = {} if isinstance(paths, str): paths = [paths] if len(paths) == 0: paths = list_services() missing_paths = [] else: local_paths = list_services() missing_paths = sorted(list(set(paths) - set(local_paths))) for m in missing_paths: name, namespace, kind = split_path(m) if create_instance: services[m] = factory(kind)(name, namespace, node=node) else: # foreign service services[m] = factory(kind)(name, namespace, node=node, volatile=True) paths = list(set(paths) & set(local_paths)) for path in paths: name, namespace, kind = split_path(path) try: svc = factory(kind)(name, namespace, node=node) except (ex.Error, ex.InitError, ValueError, utilities.configparser.Error) as e: errors.append("%s: %s" % (path, str(e))) node.log.error(str(e)) continue except ex.AbortAction: continue except: import traceback traceback.print_exc() continue services[svc.path] = svc return [s for _, s in sorted(services.items())], errors
def on_create(self): changes = [] has_ca = False if not self.oget("DEFAULT", "cn"): if self.namespace == "system": changes.append("cn=%s" % self.name) else: changes.append("cn=%s" % self.fullname) if self.namespace != "system": try: self.conf_get("DEFAULT", "validity") except ex.OptNotFound: changes.append("validity=%s" % DEFAULT_SACC_CERT_VALIDITY) grant = "guest:" + self.namespace changes.append("grant=%s" % grant) if not self.oget("DEFAULT", "ca"): capath = self.node.oget("cluster", "ca") if capath is None: capath = "system/sec/ca-" + self.node.cluster_name name, namespace, kind = split_path(capath) casec = factory("sec")(name, namespace="system", volatile=True, log=self.log) if casec.exists(): has_ca = True changes.append("ca=%s" % capath) else: print("no cluster CA defined. skip certificate generation.") if changes: self.set_multi(changes) if has_ca and "certificate" not in self.data_keys( ) and "private_key" in casec.data_keys(): self.gen_cert()
def svc_ptr_record(self, qname): if not qname.endswith(PTR_SUFFIX): return [] names = [] ref = ".".join(reversed(qname[:-PTR_SUFFIX_LEN].split("."))) with shared.CLUSTER_DATA_LOCK: for nodename, node in shared.CLUSTER_DATA.items(): status = node.get("services", {}).get("status", {}) for path, svc in status.items(): name, namespace, kind = split_path(path) if kind != "svc": continue if not namespace: namespace = "root" for rid, resource in status[path].get("resources", {}).items(): addr = resource.get("info", {}).get("ipaddr") if addr is None: continue if addr != ref: continue try: hostname = resource.get( "info", {}).get("hostname").split(".")[0].lower() except Exception: hostname = None gen_name = "%s.%s.%s.%s." % (name, namespace, kind, self.cluster_name) gen_name = gen_name.lower() if hostname and hostname != name: names.append("%s.%s" % (hostname, gen_name)) else: names.append(gen_name) return names
def ca(self): capath = self.oget("DEFAULT", "ca") name, namespace, kind = split_path(capath) return factory("sec")(name, namespace=namespace, volatile=True, node=self.node)
def init(self): if self.username is not None and self.password is not None: return s = "array#" + self.head try: stype = self.node.oget(s, "type") except Exception: raise ex.Error("no array configuration for head %s"%self.head) if stype != "nexenta": raise ex.Error("array %s type is not nexanta" % self.head) try: self.username = self.node.oget(s, "username") except Exception: raise ex.Error("no username information for head %s"%self.head) try: self.password = self.node.oget(s, "password") except Exception: raise ex.Error("no password information for head %s"%self.head) self.port = self.node.oget(s, "port") try: secname, namespace, _ = split_path(self.password) self.password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: raise ex.Error("error decoding password: %s" % exc) self.url = 'https://%(head)s:%(port)d/rest/nms/ <https://%(head)s:%(port)d/rest/nms/>'%dict(head=self.head, port=self.port)
def _install_data(self, kind): for data in self.data_data(kind): name, _, kind = split_path(data["obj"]) obj = factory(kind)(name, namespace=self.svc.namespace, volatile=True, node=self.svc.node) if not obj.exists(): self.log.warning( "referenced %s %s does not exist: " "expected data %s can not be installed in the volume", kind, name, data["key"]) continue keys = obj.resolve_key(data["key"]) if not keys and not is_glob(data["key"]): self.log.warning( "%s %s has no key %s. " "expected data can not be installed in the volume", kind, name, data["key"]) continue self.log.debug("install ./%s/%s/%s in %s", kind, name, data["key"], data["path"]) for key in keys: obj.install_key(key, data["path"], uid=self.uid, gid=self.gid, mode=self.octal_mode, dirmode=self.octal_dirmode)
def rbac(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) name, namespace, kind = split_path(options.path) if kind == "cfg": role = "guest" else: # sec, usr role = "admin" thr.rbac_requires(roles=[role], namespaces=[namespace], **kwargs)
def action(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) name, namespace, kind = split_path(options.path) svc = factory(kind)(name=name, namespace=namespace, volatile=True) data = { "status": 0, "data": [res.rid for res in svc.get_resources("task") if res.confirmation], } return data
def a_records(self): data = self.get_cache("a") if data is not None: return data names = {} key = self.cache_key() for nodename in self.cluster_nodes: try: node = shared.CLUSTER_DATA[nodename] except KeyError: continue status = node.get("services", {}).get("status", {}) for path, svc in status.items(): name, namespace, kind = split_path(path) if kind != "svc": continue if namespace: namespace = namespace.lower() else: namespace = "root" scaler_slave = svc.get("scaler_slave") if scaler_slave: _name = name[name.index(".") + 1:] else: _name = name zone = "%s.%s.%s." % (namespace, kind, self.cluster_name) qname = "%s.%s" % (_name, zone) if qname not in names: names[qname] = set() local_zone = "%s.%s.%s.node.%s." % (namespace, kind, nodename, self.cluster_name) local_qname = "%s.%s" % (_name, local_zone) if local_qname not in names: names[local_qname] = set() for rid, resource in status.get(path, {}).get("resources", {}).items(): addr = resource.get("info", {}).get("ipaddr") if addr is None: continue hostname = resource.get("info", {}).get("hostname") names[qname].add(addr) names[local_qname].add(addr) rname = self.unique_name(addr) + "." + qname if rname not in names: names[rname] = set() names[rname].add(addr) if hostname: name = hostname.split(".")[0] + "." + qname if name not in names: names[name] = set() names[name].add(addr) names.update(self.dns_a_records()) self.set_cache(key, "a", names) return names
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects self.filtering = len(objects) > 0 if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): try: name = self.node.oget(s, "name") except Exception: name = None if not name: name = s.split("#", 1)[-1] if name in done: continue if self.filtering and name not in self.objects: continue try: stype = self.node.oget(s, "type") except: continue if stype != "hds": continue try: bin = self.node.oget(s, 'bin') jre_path = self.node.oget(s, 'jre_path') url = self.node.oget(s, 'url') username = self.node.oget(s, 'username') password = self.node.oget(s, 'password') except Exception as exc: print("error parsing section %s: %s" % (s, exc), file=sys.stderr) continue try: secname, namespace, _ = split_path(password) password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue self.arrays.append( Array(name, url, username, password, bin=bin, jre_path=jre_path, node=self.node)) done.append(name)
def __init__(self, name): self.node_flag = os.path.join(Env.paths.pathvar, "node", "frozen") if name == "node": self.flag = self.node_flag else: name, namespace, kind = split_path(name) if namespace: self.flag = os.path.join(Env.paths.pathvar, "namespaces", namespace, kind, name, "frozen") else: self.flag = os.path.join(Env.paths.pathvar, kind, name, "frozen")
def a_records(self): data = self.get_cache("a") if data is not None: return data names = {} for nodename in self.cluster_nodes: try: node = shared.CLUSTER_DATA[nodename] except KeyError: continue status = node.get("services", {}).get("status", {}) for path, svc in status.items(): name, namespace, kind = split_path(path) if kind != "svc": continue if namespace: namespace = namespace.lower() else: namespace = "root" scaler_slave = svc.get("scaler_slave") if scaler_slave: _name = name[name.index(".") + 1:] else: _name = name zone = "%s.%s.%s." % (namespace, kind, self.cluster_name) qname = "%s.%s" % (_name, zone) if qname not in names: names[qname] = set() for rid, resource in status.get(path, {}).get("resources", {}).items(): addr = resource.get("info", {}).get("ipaddr") if addr is None: continue hostname = resource.get("info", {}).get("hostname") names[qname].add(addr) rname = self.unique_name(addr) + "." + qname if rname not in names: names[rname] = set() names[rname].add(addr) if hostname: name = hostname.split(".")[0] + "." + qname if name not in names: names[name] = set() names[name].add(addr) for i, ip in enumerate(shared.NODE.dns): try: dns = "%s.%s." % (shared.NODE.dnsnodes[i].split(".")[0], self.cluster_name) names[dns] = set([ip]) except IndexError: self.log.warning("dns (%s) and dnsnodes (%s) are not aligned" "" % (shared.NODE.dns, shared.NODE.dnsnodes)) break self.set_cache("a", names) return names
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects self.filtering = len(objects) > 0 if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): name = s.split("#", 1)[-1] if name in done: continue try: stype = self.node.oget(s, "type") except: continue if stype != "eva": continue try: manager = self.node.oget(s, 'manager') username = self.node.oget(s, 'username') password = self.node.oget(s, 'password') sssubin = self.node.oget(s, 'bin') except Exception as exc: print("error parsing section %s: %s" % (s, exc), file=sys.stderr) pass try: secname, namespace, _ = split_path(password) password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue out, err = sssu('ls system', manager, username, password, sssubin=sssubin) _in = False for line in out.split('\n'): if 'Systems avail' in line: _in = True continue if not _in: continue name = line.strip() if self.filtering and name not in self.objects: continue self.arrays.append( Eva(name, manager, username, password, sssubin=sssubin)) done.append(name)
def incompatible_claims(self, volume=None): if not volume: volume = self.volsvc volume_children_not_in_svc_parents = set() for e in volume.children: c1 = e + "@" + Env.nodename c2 = split_path(e)[0] + "@" + Env.nodename if c1 not in self.svc.parents and \ c2 not in self.svc.parents: volume_children_not_in_svc_parents.add(e) return volume_children_not_in_svc_parents
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects if len(objects) > 0: self.filtering = True else: self.filtering = False self.arrays = [] if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): name = s.split("#", 1)[-1] if name in done: continue if self.filtering and name not in self.objects: continue try: stype = self.node.oget(s, "type") except: continue if stype != "centera": continue try: server = self.node.oget(s, "server") username = self.node.oget(s, "username") password = self.node.oget(s, "password") jcass_dir = self.node.oget(s, "jcass_dir") java_bin = self.node.oget(s, "java_bin") except: print("error parsing section", s, file=sys.stderr) try: secname, namespace, _ = split_path(password) password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue self.arrays.append( Centera(name, server=server, username=username, password=password, java_bin=java_bin, jcass_dir=jcass_dir, node=self.node)) done.append(name)
def rbac(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) name, namespace, kind = split_path(options.path) if options.action in GUEST_ACTIONS: role = "guest" elif options.action in OPERATOR_ACTIONS: role = "operator" elif options.action in ADMIN_ACTIONS: role = "admin" else: role = "root" if options.action == "set": # load current config try: cf = shared.SERVICES[options.path].print_config_data() except Exception as exc: cf = {} # purge unwanted sections try: del cf["metadata"] except Exception: pass # merge changes in current config for buff in options.options.get("kw", []): k, v = buff.split("=", 1) if k[-1] in ("+", "-"): k = k[:-1] k = k.strip() try: s, k = k.split(".", 1) except Exception: s = "DEFAULT" if s not in cf: cf[s] = {} cf[s][k] = v # apply object create rbac to the amended config payload = {options.path: cf} errors = self.rbac_create_data(payload=payload, thr=thr, **kwargs) if errors: raise ex.HTTP(403, errors) else: thr.rbac_requires(roles=[role], namespaces=[namespace], **kwargs) if options.cmd: # compat, requires root kwargs["roles"] = ["root"] thr.rbac_requires(**kwargs)
def postinstall(self, key=None): """ Refresh installed keys """ changed_volumes = set() for path in list_services(namespace=self.namespace, kinds=["svc"]): name, _, _ = split_path(path) svc = factory("svc")(name, namespace=self.namespace, volatile=True, node=self.node, log=self.log) for res in svc.get_resources("volume"): if res.has_data(self.kind, self.path, key) and res._status() == core.status.UP: installed = res._install_data(self.kind) if installed: changed_volumes.add(res.volsvc.path) if res.volsvc.path in changed_volumes: res.send_signals()
def dispatch_svcs(paths): data = {} for path in paths: try: _, _, kind = split_path(path) except ValueError: continue try: validate_kind(kind) except ValueError as exc: raise ex.Error(str(exc)) try: data[kind].append(path) except KeyError: data[kind] = [path] return data
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects self.filtering = len(objects) > 0 self.timeout = 10 if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): try: name = self.node.oget(s, 'name') except Exception: name = None if not name: name = s.split("#", 1)[-1] if name in done: continue if self.filtering and name not in self.objects: continue try: stype = self.node.oget(s, "type") except: continue if stype != "dorado": continue timeout = self.node.oget(s, "timeout") try: username = self.node.oget(s, "username") password = self.node.oget(s, "password") api = self.node.oget(s, "api") except: print("error parsing section", s, file=sys.stderr) continue try: secname, namespace, _ = split_path(password) password = factory("sec")(secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue self.arrays.append( Dorado(name, api, username, password, timeout, node=self.node)) done.append(name)
def postinstall(self, key=None): """ Refresh installed keys """ for path in self.node.svcs_selector("*/svc/*", namespace=self.namespace, local=True): name, _, _ = split_path(path) svc = factory("svc")(name, namespace=self.namespace, volatile=True, node=self.node, log=self.log) for vol in svc.get_resources("volume"): if vol.has_data(self.kind, self.path, key) and vol._status() == core.status.UP: vol._install_data(self.kind)
def ptr_records(self): data = self.get_cache("ptr") if data is not None: return data names = {} key = self.cache_key() for nodename in self.cluster_nodes: try: node = shared.CLUSTER_DATA[nodename] except KeyError: continue status = node.get("services", {}).get("status", {}) for path, svc in status.items(): name, namespace, kind = split_path(path) if kind != "svc": continue if not namespace: namespace = "root" for rid, resource in status[path].get("resources", {}).items(): addr = resource.get("info", {}).get("ipaddr") if addr is None: continue qname = "%s%s" % ( ".".join(reversed(addr.split("."))), PTR_SUFFIX, ) if qname not in names: names[qname] = [] try: hostname = resource.get( "info", {}).get("hostname").split(".")[0].lower() except Exception: hostname = None gen_name = "%s.%s.%s.%s." % (name, namespace, kind, self.cluster_name) gen_name = gen_name.lower() if hostname and hostname != name: target = "%s.%s" % (hostname, gen_name) else: target = "%s" % gen_name if target in names[qname]: continue names[qname].append(target) self.set_cache(key, "ptr", names) return names
def users(self, exclude=None): exclude = exclude or [] users = [] for child in self.children: if child in exclude: continue name, namespace, kind = split_path(child) obj = factory(kind)(name=name, namespace=self.namespace, volatile=True, node=self.node) for res in obj.get_resources("volume"): if res.name != self.name: continue if res.status() in (core.status.UP, core.status.STDBY_UP, core.status.WARN): users.append(child) return users
def _data_status(self, kind): for data in self.data_data(kind): name, _, kind = split_path(data["obj"]) obj = factory(kind)(name, namespace=self.svc.namespace, volatile=True, node=self.svc.node) if not obj.exists(): self.status_log( "referenced %s %s does not exist: " "expected data %s can not be installed in the volume" % (kind, name, data["key"]), "warn") continue keys = obj.resolve_key(data["key"]) if not keys and not is_glob(data["key"]): self.status_log( "%s %s has no key %s. " "expected data can not be installed in the volume" % (kind, name, data["key"]), "warn")
def format_instance(path, idata, mon_data=None, discard_disabled=False, nodename=None): name, namespace, kind = split_path(path) svc_notice = get_svc_notice(idata) tree = utilities.render.forest.Forest( separator=" ", widths=( (14, None), None, 10, None, ), ) node_name = tree.add_node() node_name.add_column(strip_path(path, os.environ.get("OSVC_NAMESPACE")), color.BOLD) node_name.add_column() if "cluster" in idata: node_name.add_column( idata["cluster"].get("avail", "n/a"), STATUS_COLOR[idata["cluster"].get("avail", "n/a")]) else: node_name.add_column() node_name.add_column(svc_notice) node_instances = node_name.add_node() node_instances.add_column("instances") add_instances(node_instances, path, nodename, mon_data) if nodename in service_nodes(path, mon_data): add_node_node(node_instances, nodename, idata, mon_data, discard_disabled=discard_disabled) add_parents(node_name, idata, mon_data, namespace) add_children(node_name, idata, mon_data, namespace) add_scaler_slaves(node_name, idata, mon_data, namespace) add_slaves(node_name, idata, mon_data, namespace) tree.out()
def action(self, nodename, thr=None, **kwargs): """ Care with locks """ thr.log_request("shutdown daemon", nodename, **kwargs) with shared.THREADS_LOCK: shared.THREADS["scheduler"].stop() mon = shared.THREADS["monitor"] if thr.stopped() or shared.NMON_DATA.status == "shutting": thr.log.info("already shutting") # wait for service shutdown to finish before releasing the dup client while True: if mon._shutdown: break time.sleep(0.3) return {"status": 0} try: thr.set_nmon("shutting") mon.kill_procs() for path in shared.SMON_DATA: _, _, kind = split_path(path) if kind not in ("svc", "vol"): continue thr.set_smon(path, local_expect="shutdown") self.wait_shutdown() # send a last status to peers so they can takeover asap mon.update_hb_data() mon._shutdown = True shared.wake_monitor("services shutdown done") except Exception as exc: thr.log.exception(exc) thr.log.info("services are now shutdown") while True: with shared.THREADS_LOCK: if not shared.THREADS["monitor"].is_alive(): break time.sleep(0.3) shared.DAEMON_STOP.set() return {"status": 0}
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects self.filtering = len(objects) > 0 self.arrays = [] if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): name = s.split("#", 1)[-1] if name in done: continue if self.filtering and name not in self.objects: continue try: stype = self.node.oget(s, "type") except: continue if stype != "netapp": continue kwargs = {"node": self.node} for key in ("server", "username", "key"): try: kwargs[key] = self.node.oget(s, key) except: print("missing parameter: %s", s) if "server" not in kwargs or "username" not in kwargs or "key" not in kwargs: continue try: secname, namespace, _ = split_path(kwargs["password"]) kwargs["password"] = factory("sec")( secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue self.arrays.append(Netapp(s, **kwargs))
def configure_volume(self, volume, size=None, fmt=True, access="rwo", shared=False, nodes=None, env=None): if self.template is None: raise ex.Error("pool#%s.template is not set" % self.name) if not is_service(self.template): raise ex.Error("%s template volume not found" % self.template) name = self.default_disk_name(volume) tname, tnamespace, tkind = split_path(self.template) if tkind != "vol": raise ex.Error("%s template kind is not vol") svc = factory(tkind)(tname, tnamespace, volatile=True, node=self.node) config = svc.print_config_data() try: del config["DEFAULT"]["disable"] except KeyError: pass if "DEFAULT" not in config: config["DEFAULT"] = {} if "env" not in config: config["env"] = {} config["DEFAULT"]["pool"] = self.name config["DEFAULT"]["access"] = access if access in ("rox", "rwx"): config["DEFAULT"]["topology"] = "flex" config["DEFAULT"]["flex_min"] = 0 if nodes: config["DEFAULT"]["nodes"] = nodes config["env"]["size"] = size if env: config["env"].update(env) self.node.install_svc_conf_from_data(volume.name, volume.namespace, volume.kind, config)
def action(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) thr.log_request("drain node", nodename, **kwargs) thr.event("node_freeze", data={"reason": "drain"}) thr.freezer.node_freeze() if thr.stopped() or shared.NMON_DATA.status in ("draining", "shutting"): thr.log.info("already %s", shared.NMON_DATA.status) # wait for service shutdown to finish before releasing the dup client if options.wait: elapse = 0.0 while True: if shared.THREADS[ "monitor"]._shutdown or shared.NMON_DATA.status not in ( "draining", "shutting"): break if options.time and elapse > options.time: return {"status": 1, "error": "timeout"} time.sleep(0.3) elapse += 0.3 return {"status": 0} try: thr.set_nmon("draining") for path in shared.SMON_DATA: _, _, kind = split_path(path) if kind not in ("svc", "vol"): continue thr.set_smon(path, local_expect="shutdown") if options.wait: try: self.wait_shutdown(timeout=options.time) except ex.TimeOut: return {"status": 1, "error": "timeout"} except Exception as exc: thr.log.exception(exc) return {"status": 0}
def action(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) name, namespace, kind = split_path(options.path) if thr.get_service(options.path) is None and options.action not in ("create", "deploy"): thr.log_request("service action (%s not installed)" % options.path, nodename, lvl="warning", **kwargs) raise ex.HTTP(404, "%s not found" % options.path) if not options.action and not options.cmd: thr.log_request("service action (no action set)", nodename, lvl="error", **kwargs) raise ex.HTTP(400, "action not set") for opt in ("node", "daemon", "svcs", "service", "s", "parm_svcs", "local", "id"): if opt in options.options: del options.options[opt] for opt, ropt in (("jsonpath_filter", "filter"),): if opt in options.options: options.options[ropt] = options.options[opt] del options.options[opt] options.options["local"] = True pmod = importlib.import_module("commands.{kind}.parser".format(kind=kind)) popt = pmod.OPT def find_opt(opt): for k, o in popt.items(): if o.dest == opt: return o if o.dest == "parm_" + opt: return o if options.cmd: cmd = [options.cmd] else: cmd = [options.action] for opt, val in options.options.items(): po = find_opt(opt) if po is None: continue if val == po.default: continue if val is None: continue opt = po._long_opts[0] if po._long_opts else po._short_opts[0] if po.action == "append": cmd += [opt + "=" + str(v) for v in val] elif po.action == "store_true" and val: cmd.append(opt) elif po.action == "store_false" and not val: cmd.append(opt) elif po.type == "string": opt += "=" + val cmd.append(opt) elif po.type == "integer": opt += "=" + str(val) cmd.append(opt) fullcmd = Env.om + ["svc", "-s", options.path] + cmd thr.log_request("run 'om %s %s'" % (options.path, " ".join(cmd)), nodename, **kwargs) if options.sync: proc = Popen(fullcmd, stdout=PIPE, stderr=PIPE, stdin=None, close_fds=True) out, err = proc.communicate() try: result = json.loads(out) except Exception: result = { "status": 0, "data": { "out": bdecode(out), "err": bdecode(err), "ret": proc.returncode, }, } else: import uuid session_id = str(uuid.uuid4()) env = {} env.update(os.environ) env["OSVC_PARENT_SESSION_UUID"] = session_id proc = Popen(fullcmd, stdin=None, close_fds=True, env=env) thr.push_proc(proc) result = { "status": 0, "data": { "pid": proc.pid, "session_id": session_id, }, "info": "started %s action %s" % (options.path, " ".join(cmd)), } return result
def __init__(self, objects=None, node=None): if objects is None: objects = [] self.objects = objects if len(objects) > 0: self.filtering = True else: self.filtering = False self.arrays = [] if node: self.node = node else: self.node = Node() done = [] for s in self.node.conf_sections(cat="array"): name = s.split("#", 1)[-1] if name in done: continue if self.filtering and name not in self.objects: continue try: stype = self.node.oget(s, "type") except: continue if stype != "emcvnx": continue try: method = self.node.oget(s, "method") scope = self.node.oget(s, "scope") spa = self.node.oget(s, "spa") spb = self.node.oget(s, "spb") username = self.node.oget(s, "username") password = self.node.oget(s, "password") except Exception as exc: print("error parsing section %s: %s" % (s, exc), file=sys.stderr) continue if method == "credentials": if username is None or password is None: print( "error parsing section %s: username and password are mandatory" % s, file=sys.stderr) continue try: secname, namespace, _ = split_path(password) password = factory("sec")( secname, namespace=namespace, volatile=True).decode_key("password") except Exception as exc: print("error decoding password: %s", exc, file=sys.stderr) continue self.arrays.append( EmcVnx(name, method, scope, spa, spb, username=username, password=password, node=self.node)) done.append(name)