async def do(self, args): await self.root.setup(self) etc = self.root.etcd path = '/device' if not args: raise CommandError("You need to specify a device.") arg = args.pop(0) types = EtcTypes() Device.types(types) try: t = await etc.tree('/'.join((path, arg, DEV)), types=types, create=False) except KeyError: raise CommandError("Device '%s' not found." % (arg, )) if args: args = ' '.join(args) if args == '-': if self._nl: args = sys.stdin.read().rstrip('\n') else: args = sys.stdin.readline().rstrip('\n') await t.set(self._attr, args) if self.root.verbose > 1: print("Location set.", file=self.stdout) elif self._attr in t: print(t[self._attr], file=self.stdout) elif self.root.verbose: print(self._attr.ucfirst() + " not yet set.", file=sys.stderr) return 1
async def do(self, args): t = await self.setup(meta=False) if not args: if not cmd.root.cfg['testing']: raise CommandError("You can't delete everything.") args = t for k in args: try: task = await t.subdir(k, name=TASK, create=False) except KeyError: raise CommandError("%s: does not exist" % k) if self.root.verbose: print("%s: deleted" % k, file=self.stdout) rec = None while True: p = task._parent if p is None: break p = p() if p is None: break if p is task: break try: await task.delete(recursive=rec) except etcd.EtcdDirNotEmpty: if rec: raise break rec = False task = p
async def do(self,args): t = await self.setup() if not args: if not cmd.root.cfg['testing']: raise CommandError("You can't delete everything.") if not self.options.recursive: raise CommandError("You can't delete everything non-recursively.") await t.delete(recursive=True) return for k in args: try: dev = await t.subdir(k,name=DEV, create=False) except KeyError: raise CommandError("%s: does not exist"%k) if self.root.verbose: print("%s: deleted"%k, file=self.stdout) rec=self.options.recursive while True: p = dev._parent if p is None: break p = p() if p is None: break if p is t: break try: await dev.delete(recursive=rec) except etcd.EtcdDirNotEmpty: break rec=False dev = p
async def do(self, args): if not args: raise CommandError("Not specifying values to %s makes no sense." % ("delete" if self.delete else "add/update")) etc = await self.root._get_etcd() retval = 0 if self.delete: if not self.create: raise CommandError( "You can't update and delete at the same time.") for a in args: pa = a.replace('.', '/') kw = {} if self.modified: kw['prevIndex'] = self.modified if self.previous: kw['prevValue'] = self.previous try: await etc.delete('/' + pa, recursive=True, **kw) except etcd.EtcdCompareFailed: logger.fatal("Bad modstamp: " + a) retval = 1 except etcd.EtcdKeyNotFound: logger.info("Key already deleted: " + a) else: for a in args: a, v = a.split('=', 1) pa = a.replace('.', '/') create = self.create try: kw = {} if self.modified: kw['index'] = self.modified create = False if self.previous: kw['prev'] = self.previous create = False if v: kw['value'] = v if self.append: kw['append'] = True create = True r = await etc.set('/' + pa, create=create, **kw) if self.append: print(r.key.rsplit('/', 1)[1], file=self.stdout) except etcd.EtcdCompareFailed: logger.error("Bad modstamp: " + a) retval = 1 except etcd.EtcdAlreadyExist: logger.error("Entry exists: " + a) retval = 1 return retval
async def do(self, args): if not args: raise CommandError("Not specifying values to %s makes no sense." % ("delete" if self.delete else "add/update")) etc = await self.root._get_etcd() retval = 0 if len(args) < 2 or '=' not in args[-1]: raise SyntaxError("Usage: … path/to/device input/name entry=value") p = p1 = '/' + '/'.join(DEV_DIR) + '/' + args.pop(0).replace( '.', '/') + '/' + DEV import pdb pdb.set_trace() for a in args: if '=' not in a: p = p1 + '/' + a.replace('.', '/') continue a, v = a.split('=', 1) pa = p + '/' + a.replace('.', '/') try: if v == '' and self.delete: r = await etc.delete(pa) else: r = await etc.set(pa, value=v, ext=True) except etcd.EtcdKeyNotFound: logger.info("Key already deleted: " + a) except etcd.EtcdCompareFailed: logger.error("Bad modstamp: " + a) retval = 1 except etcd.EtcdAlreadyExist: logger.error("Entry exists: " + a) retval = 1 return retval
async def do(self, args): tree = await self.root._get_tree() t = await self.setup(meta=True) if args: objs = [] for a in args: m = import_string(a) if isinstance(m, py_types.ModuleType): from moat.script.util import objects n = 0 for c in objects(m, Task, filter=lambda x: getattr( x, 'taskdef', None) is not None): await t.add_task(c, force=self.force) n += 1 if self.root.verbose > (1 if n else 0): print("%s: %s command%s found." % (a, n if n else "no", "" if n == 1 else "s"), file=self.stdout) else: if not isinstance(m, Task): raise CommandError("%s is not a task" % a) await t.add_task(m, force=self.force) else: for c in task_types(): await t.add_task(c, force=self.force) r = await tree.subdir(*TASKSCAN_DIR) from moat.task.collect import Collector await r.add_task(path=(), taskdef=Collector.taskdef, force=self.force) await t.wait()
async def do(self,args): t = await self.setup() if args: dirs = [] for a in args: try: dirs.append(await t.subdir(a, create=False)) except KeyError: raise CommandError("'%s' does not exist"%(a,)) else: dirs = [t] for tt in dirs: async for dev in tt.tagged(DEV, depth=self.options.this): path = dev.path[len(DEV_DIR):-1] if self.root.verbose == 2: print('*','/'.join(path), sep='\t',file=self.stdout) for k,v in r_show(dev,''): print(k,v, sep='\t',file=self.stdout) elif self.root.verbose > 1: dump({'/'.join(path):r_dict(dict(dev))}, stream=self.stdout) else: path = '/'.join(path) name = dev.get('name','-') val = dev.get('value','-') if name == path: name = "-" print(path,name,val, sep='\t',file=self.stdout)
async def do(self, args): if self.root.cfg['config'].get('testing', False): print("NOTE: this is a test configuration.", file=sys.stderr) else: # pragma: no cover ## not doing the real thing here print("WARNING: this is NOT a test.", file=sys.stderr) time.sleep(3) if args: return (await super().do(args)) res = 0 for c in self.subCommandClasses: if c.summary is None: continue if self.root.verbose > 1: print("Checking:", c.name) c = c(parent=self) try: res = (await c.do(args) or 0) except Exception as exc: # pragma: no cover if self.root.verbose > 1: import traceback traceback.print_exc(file=sys.stderr) return 9 raise CommandError("%s failed: %s" % (c.name, repr(exc))) else: if res: print("Error. Stopped test run.", file=sys.stderr) return res if self.root.verbose: print("All tests done.", file=self.stdout) return res
def handleOptions(self): opts = self.options if (opts.delete or opts.modified or opts.previous) and opts.append: raise CommandError("Conflicting arguments") self.delete = opts.delete self.modified = opts.modified self.previous = opts.previous self.append = opts.append self.create = not opts.update
async def do(self, args): if not self.root.cfg['config'].get('testing',False) or \ len(args) != 2 or " ".join(args) != "me hardeR": raise CommandError("You're insane.") etc = await self.root._get_etcd() self.log.fatal("Erasing your etcd data in three seconds.") time.sleep(3) await etc.delete("/", recursive=True) self.log.warn("All gone.") return
async def do(self,args): t = await self.setup() try: data = {} name="" webpath = args[0].rstrip('/').lstrip('/') if webpath == "": raise CommandError("Empty web entry path?") if webpath[0] == ':' or '/:' in webpath: raise CommandError("Don't add the tag") p=1 while p < len(args): try: k,v = args[p].split('=') except ValueError: break p += 1 data[k] = v descr = " ".join(args[p:]) except IndexError: raise CommandError("Missing command parameters") finally: pass try: web = await t.subdir(webpath, name=WEBSERVER, create=not self._update) except KeyError: raise CommandError("Web item '%s' not found." % webpath) if descr: await web.set('descr', descr, sync=False) if data: for k,v in data.items(): if v == "": try: await web.delete(k, sync=False) except KeyError: pass else: await web.set(k,v, sync=False, ext=True)
async def do(self,args): await self.root.setup(self) if len(args) < 2: raise CommandError("Usage: … add ‹name› ‹host› [‹port›]") name = args[0] if ':' in name or '/' in name: raise CommandError("The service name can't contain colons or slashes.") host = args[1] try: if args[2] == '-': port = 4304 else: port = int(args[2]) except IndexError: port = 4304 except ValueError: raise CommandError("The port must be an integer") else: if port<1 or port>65534: raise CommandError("The port must be positive and <65535") try: t = await self.root.tree.subdir('bus','onewire',name, create=not self.update) await t.subdir('bus') except etcd.EtcdAlreadyExist: raise CommandError("Host '%s' exists. Use '-u' or choose a different name." % name) except etcd.EtcdKeyNotFound: raise CommandError("Host '%s' does not exist. Drop '-u' or choose an existing name." % name) await t.set('server',{'host':host,'port':port}) if len(args) > 3: await t.set('info',' '.join(args[3:])) if self.root.verbose > 1: print(name, "updated" if self.update else "created", file=self.stdout)
async def do(self, args): tree = await self.root._get_tree() if not len(args): args = ("", ) else: if len(args) > 1 and self.options.watch: raise CommandError("You can only watch one node. Sorry.") for a in args: a = tuple(x for x in a.split('/') if x != '') try: d = await tree.lookup(*a) except KeyError: print("Node '%s' not found" % (a, ), file=sys.stderr) continue try: coll = d.task_monitor except AttributeError: print("Node '%s' does not have tasks" % (d, ), file=sys.stderr) continue def show(r): if len(r) > 1: r1 = r[1] if not isinstance(r1, str): r1 = '/'.join(r1) if r[0] == 'add': print("Task:" + r1, 'at', '/'.join(r[2]), *r[3:], file=self.stdout) elif r[0] == 'drop': print("Delete", r1, *r[2:], file=self.stdout) elif r[0] == 'scan': print("Subtask", r1, *r[2:], file=self.stdout) elif r[0] == 'watch': print('---', file=self.stdout) if not self.options.watch: raise StopIteration else: raise RuntimeError("Unknown response: " + repr(r)) if hasattr(coll, '__aiter__'): async for r in coll: try: show(r) except StopIteration: break else: for r in coll: show(r)
async def do(self, args): t = await self.setup() tree = await self.root._get_tree() t2 = await tree.subdir(TASKDEF_DIR) if args: objs = [] for a in args: m = import_string(a) if isinstance(m, py_types.ModuleType): try: syms = m.__all__ except AttributeError: syms = dir(m) n = 0 for c in syms: c = getattr(m, c, None) if isinstance(c, type) and issubclass( c, BaseModule) and c.prefix is not None: objs.append(c) n += 1 if self.root.verbose > (1 if n else 0): print("%s: %s module%s found." % (a, n if n else "no", "" if n == 1 else "s"), file=self.stdout) if self.tasks: n = 0 for c in objects(m, Task, filter=lambda x: getattr( x, 'taskdef', None) is not None): await t2.add_task(c, force=self.force) n += 1 if self.root.verbose > (1 if n else 0): print("%s: %s command%s found." % (a, n if n else "no", "" if n == 1 else "s"), file=self.stdout) else: if not isinstance(m, BaseModule): raise CommandError("%s is not a task" % a) objs.append(m) else: objs = modules() tasks = await t.root.subdir(TASKDEF_DIR) for obj in objs: await t.add_module(obj, force=self.force) for ta in obj.task_types(): await tasks.add_task(ta, force=self.force) await t.wait()
async def do(self, args): import moat.util # side effect: loads YAML representers from yaml import dump if args: try: for n, a in enumerate(args): if n: print("---", file=self.stdout) c = self.root.cfg for aa in a.split('.'): c = c[aa] dump(c, stream=self.stdout) except KeyError: raise CommandError("Key %s does not exist" % (repr(a), )) else: dump(self.root.cfg, stream=self.stdout)
async def do(self, args): t = await self.setup() if args: dirs = [] for a in args: tt = t try: for k in a.split('/'): if k: tt = tt._get(k) dirs.append(tt) except KeyError: print("Module '%s' not known" % (a, ), file=sys.stderr) else: if not cmd.root.cfg['testing']: raise CommandError("You can't delete everything.") dirs = (t) for k in dirs: t = await k k = t.path rec = True while True: p = t._parent if p is None: break p = p() if p is None or p is t: break try: await t.delete(recursive=rec) except etcd.EtcdDirNotEmpty: if rec: raise break if isinstance(t, MoatLoaderDir): try: t2 = t.root.lookup(*TASKDEF_DIR, self.name) except KeyError: pass else: await t2.delete(recursive=True) rec = False t = p if self.root.verbose: print("%s: deleted" % '/'.join(k), file=self.stdout)
async def do(self,args): t = await self.setup() if args: if self.options.all: raise CommandError("Arguments and '-a' are mutually exclusive") dirs = [] for a in args: dirs.append(await t.subdir(a, create=False)) verbose = True else: dirs = [t] verbose = self.options.all for tt in dirs: async for web in tt.tagged(WEBSERVER): path = web.path[len(WEBSERVER_DIR):-1] if verbose: dump({path: r_dict(dict(web))}, stream=self.stdout) else: print('/'.join(path), web.get('host','-'), web.get('port',80), web.get('default','default'), web.get('descr',''), sep='\t',file=self.stdout)
async def do(self,args): await self.root.setup(self) etc = self.root.etcd if not args: if not cmd.root.cfg['testing']: raise CommandError("You can't delete everything.") args = [] res = etc.get('/bus/onewire') for r in res.children: args.append(r.name.rsplit('/',1)[1]) for k in args: try: await etc.delete('/bus/onewire/'+k, recursive=True) except etcd.EtcdKeyNotFound: if self.root.verbose: print("%s: not known"%k, file=sys.stderr) else: with suppress(etcd.EtcdKeyNotFound): await etc.delete('/task/onewire/'+k, recursive=True) with suppress(etcd.EtcdKeyNotFound): await etc.delete('/task/moat/scan/bus/onewire/'+k, recursive=True)
async def do(self, args): t = await self.setup(meta=True) if args: if self.options.all: raise CommandError("Arguments and '-a' are mutually exclusive") dirs = [] for a in args: dirs.append(await t.subdir(a, create=False)) verbose = True else: dirs = [t] verbose = self.options.all for tt in dirs: async for task in tt.tagged(TASKDEF): path = task.path[len(TASKDEF_DIR):-1] if verbose: dump({path: r_dict(dict(task))}, stream=self.stdout) else: print('/'.join(path), task.get('summary', task.get('descr', '??')), sep='\t', file=self.stdout)
async def do(self,args): tree = await self.root._get_tree() t = await self.setup(meta=True) if args: objs = [] for a in args: m = import_string(a) if isinstance(m,types.ModuleType): from moat.script.util import objects n = 0 for c in objects(m, WebdefDir, filter=lambda x:getattr(x,'name',None) is not None): await t.add_webdef(c, force=self.force) n += 1 if self.root.verbose > (1 if n else 0): print("%s: %s webdef%s found." % (a,n if n else "no", "" if n==1 else "s"), file=self.stdout) else: if not isinstance(m,WebdefDir): raise CommandError("%s is not a web definition"%a) await t.add_webdef(m, force=self.force) else: for c in webdefs(): await t.add_webdef(c, force=self.force) await t.wait()
async def do(self, args): td = await self.setup(meta=True) if not args: if not cmd.root.cfg['testing']: raise CommandError("You can't delete everything.") args = td.tagged(TASKDEF) for k in args: t = await td.subdir(k, name=TASKDEF, create=False) if self.root.verbose: print("%s: deleted" % k, file=self.stdout) rec = True while True: p = t._parent if p is None: break p = p() if p is None or p is t: break try: await t.delete(recursive=rec) except etcd.EtcdDirNotEmpty: if rec: raise break rec = False t = p
def handleOptions(self): opts = self.options self.verbose = opts.verbose paths = [] if opts.files: for f in opts.files: paths.extend(glob.glob(f)) if not paths: # pragma: no cover ## not while testing! if 'MOAT_CFG' in os.environ: paths.append(os.environ['MOAT_CFG']) elif os.path.exists(DEFAULT_CFG): paths.append(DEFAULT_CFG) self.cfg = {'config': {}} if not opts.no_default: r_update(self.cfg['config'], DEFAULT_CONFIG) r_update(self.cfg['config'], QBROKER_DEFAULT_CONFIG) for p in paths: with open(p) as f: cfg = yaml.safe_load(f) r_update(self.cfg, cfg) if opts.opts: for o in opts.opts: k, v = o.split('=', 1) oc = None c = self.cfg for kk in k.split('.'): oc = c ok = kk c = c.setdefault(kk, {}) oc[ok] = v #logging.basicConfig(stream=logfile,level=(logging.ERROR,logging.WARNING,logging.INFO,logging.INFO,logging.DEBUG)[min(self.verbose,4)]) lcfg = self.cfg['config'].setdefault('logging', {'version': 1}) hd = lcfg.setdefault('root', {}).setdefault('handlers', []) if opts.logto: if 'logfile' not in hd: hd.append('logfile') lh = lcfg['handlers'].setdefault('logfile', { 'level': 'logging.DEBUG', 'formatter': 'std', }) lh['class'] = 'logging.FileHandler' lh['filename'] = opts.logto fmt = lcfg.setdefault('formatters', {}) fmt.setdefault('std', {'format': '%(levelname)s:%(name)s:%(message)s'}) fmt.setdefault('stderr', {'format': '%(message)s'}) if opts.verbose: if 'stderr' not in hd: hd.append('stderr') else: if 'stderr' in hd: hd.remove('stderr') lh = lcfg.setdefault('handlers', {}).setdefault('stderr', {'formatter': 'stderr'}) lh['class'] = 'logging.StreamHandler' lh['stream'] = sys.stderr lh['level'] = ('ERROR', 'ERROR', 'WARNING', 'INFO', 'INFO', 'DEBUG')[min(self.verbose, 5)] from logging.config import dictConfig lcfg['disable_existing_loggers'] = False dictConfig(lcfg) logging.captureWarnings(True) self.app = self.cfg['config'].get('app', None) # Rather than enumerate IP addresses, this is the quick&only-somewhat-dirty way s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('8.8.8.8', 53)) # connecting to a UDP address doesn't send packets addr = s.getsockname()[0] s.close() if self.app is None: addr = socket.getfqdn(addr) addr = addr.split('.') if len(addr) < 3: # pragma: no cover raise CommandError( "You need to fix your FQDN ('%s'), or use the '-a' option." % ".".join(addr)) #addr.reverse() self.host = ".".join(addr)
async def do(self, args): c = self.root.cfg try: c = c['config'] except KeyError: # pragma: no cover raise CommandError("config: missing 'config' entry")
async def do(self,args): try: data = {} webdefpath="" name="" p=0 webpath = args[p].rstrip('/').lstrip('/') if webpath == "": raise CommandError("Empty web entry path?") if webpath[0] == ':' or '/:' in webpath: raise CommandError("Don't add the tag") p+=1 if not self._update: webdefpath = args[p].rstrip('/').lstrip('/') if webdefpath == "": raise CommandError("Empty web definition path?") if webdefpath[0] == ':' or '/:' in webdefpath: raise CommandError("Don't add the tag") p+=1 while p < len(args): try: k,v = args[p].split('=') except ValueError: break p += 1 if k == "name": name = v else: data[k] = v if not self._update: args[p] # raises IndexError if nothing is left descr = " ".join(args[p:]) except IndexError: raise CommandError("Missing command parameters") t = await self.setup(meta=False) if not self._update: try: td = await self.setup(meta=True) webdef = await td.subdir(webdefpath,name=WEBDEF, create=False) except KeyError: raise CommandError("Web def '%s' not found" % webdefpath) try: web = await t.subdir(webpath,name=WEBDATA, create=not self._update) except KeyError: raise CommandError("Web item '%s' not found." % webpath) if not self._update: await web.set('def', webdefpath, sync=False) if name: await web.set('name', name, sync=False) if descr: await web.set('descr', descr, sync=False) if data: for k,v in data.items(): if v == "": try: await web.delete(k, sync=False) except KeyError: pass else: await web.set(k,v, sync=False)
async def do(self, args): c = self.root.cfg['config'] try: c = c['etcd'] except KeyError: raise CommandError("config: missing 'etcd' section") for k in ('host', 'port', 'root'): if k not in c: raise CommandError("config.etcd: missing '%s' entry" % k) # pragma: no cover retval = 0 etc = await self.root._get_etcd() tree = await self.root._get_tree() log = logging.getLogger(__name__ + ".etcd") show = log.info if self.parent.fix else log.warning try: s = None s = await etc.tree('/config') await s.subdir('run', create=False) except KeyError: show("/config/run created.") if self.parent.fix: await s.subdir('run', create=True) else: retval += 1 finally: if s is not None: await s.close() stats = set(("ok", "warn", "error", "fail")) s = await etc.tree("/status") try: if "run" not in s: show("missing 'run' entry") if self.parent.fix: await s.set("run", dict()) # pragma: no cover else: retval += 1 if "error" not in s: show("missing 'error' entry") if self.parent.fix: await s.set("error", dict()) else: retval += 1 await s.wait() if not self.root.cfg['config'].get('testing', False): return # The next part is test environment only try: t = self.Task_do3(self, "test/do_3") await t except RuntimeError as exc: pass else: raise RuntimeError( "Error did not propagate") # pragma: no cover run_state = await _run_state(tree, ('test', 'do_3')) if 'running' in run_state: raise RuntimeError( "Procedure end 2 did not take") # pragma: no cover await s.wait() assert run_state['stopped'] > run_state['started'], ( run_state['stopped'], run_state['started']) assert run_state['state'] == "error", run_state['state'] try: t = self.Task_do4(self, "test/do_4", _ttl=3, _refresh=10) await t except JobMarkGoneError: pass else: raise RuntimeError( "Cancellation ('running' marker gone) did not propagate" ) # pragma: no cover run_state = await _run_state(tree, ('test', 'do_4')) assert 'running' not in run_state await s.wait() assert run_state['stopped'] > run_state['started'], ( run_state['stopped'], run_state['started']) assert run_state['state'] == "fail", run_state['state'] logger.error( "The following 'Job is already running' message is part of the test." ) global _do2_running _do2_running = False dt2 = self.Task_do2(self, "test/do_2", {}) await s.wait() dt2.run_state = run_state = await _run_state( tree, ('test', 'do_2')) t1 = time.time() while True: if _do2_running: break await asyncio.sleep(0.1, loop=self.root.loop) if time.time() - t1 > 10: import pdb pdb.set_trace() raise RuntimeError("do2 didn't run") dt2a = self.Task_do2(self, "test/do_2", {}) try: await dt2a except JobIsRunningError as exc: assert exc.args[0] == "test/do_2", exc else: raise RuntimeError("Dup run didn't") # pragma: no cover await dt2 if 'running' in run_state: raise RuntimeError( "Procedure end did not take") # pragma: no cover await s.wait() assert run_state['stopped'] > run_state['started'], ( run_state['stopped'], run_state['started']) assert run_state['state'] == "ok", run_state['state'] try: errs = await etc.read("/status/error") except etcd.EtcdKeyNotFound: if self.parent.fix: raise RuntimeError( "Creating /status/error did not take. Duh?" ) # pragma: no cover ## hopefully # otherwise it's not there and there's nothing to do else: pass finally: await s.close() return retval
async def do(self,args): try: data = {} name="" p=0 devpath = args[p].rstrip('/').lstrip('/') if devpath == "": raise CommandError("Empty dev entry path?") if devpath[0] == ':' or '/:' in devpath: raise CommandError("Don't add the tag") p+=1 if not self._update: typepath = args[p].rstrip('/').lstrip('/') if typepath == "": raise CommandError("Empty type path?") if typepath[0] == ':' or '/:' in typepath: raise CommandError("Don't add the tag") p+=1 while p < len(args): try: k,v = args[p].split('=') except ValueError: break p += 1 if k == "name": name = v else: data[k] = v if not self._update: args[p] # raises IndexError if nothing is left descr = " ".join(args[p:]) except IndexError: raise CommandError("Missing command parameters") t = await self.setup() if not self._update: try: td = await t.root.lookup(TYPEDEF_DIR) td = await td.lookup(typepath, name=TYPEDEF) except KeyError: raise CommandError("type '%s' not found" % (typepath,)) try: dev = await t.subdir(devpath,name=DEV, create=not self._update) except KeyError: raise CommandError("Device item '%s' not found." % (devpath,)) if not self._update: await dev.set('type', typepath, sync=False) if name: await dev.set('name', name, sync=False) if descr: await dev.set('descr', descr, sync=False) if data: d = await dev.subdir('data', create=None) for k,v in data.items(): if k.startswith("input/") or k.startswith("output/"): dx = dev else: dx = d if v == "": try: await dx.delete(k, sync=False) except KeyError: pass else: await dx.set(k.split('/'),v, sync=False, ext=True)
async def do(self, args): t = await self.setup(meta=self._def) if self._def and self.options.is_global: if self.options.delete: raise CommandError("You cannot delete global parameters.") data = self.root.etc_cfg['run'] elif not args: if self.options.delete: raise CommandError("You cannot delete all parameters.") async for task in t.tagged(self.TAG, depth=self.DEPTH): path = task.path[len(self.DIR):-1] for k in self._VARS: if k in task: print('/'.join(path), k, task[k], sep='\t', file=self.stdout) return else: name = args.pop(0) try: data = await t.subdir(name, name=self.TAG, create=None if self._make else False) except KeyError: raise CommandError("Task definition '%s' is unknown." % name) if self.options.delete: if not args: args = self._VARS for k in args: if k in data: if self.root.verbose: print("%s=%s (deleted)" % (k, data[k]), file=self.stdout) await data.delete(k) elif len(args) == 1 and '=' not in args[0]: print(data[args[0]], file=self.stdout) elif not len(args): for k in self._VARS: if k in data: print(k, data[k], sep='\t', file=self.stdout) else: while args: k = args.pop(0) try: k, v = k.split('=', 1) except ValueError: if k not in self._VARS: raise CommandError("'%s' is not a valid parameter." % k) print(k, data.get(k, '-'), sep='\t', file=self.stdout) else: if k not in self._VARS: raise CommandError("'%s' is not a valid parameter." % k) if self.root.verbose: if k not in data: print("%s=%s (new)" % (k, v), file=self.stdout) elif str(data[k]) == v: print("%s=%s (unchanged)" % (k, v), file=self.stdout) else: print("%s=%s (was %s)" % (k, v, data[k]), file=self.stdout) await data.set(k, v, ext=True)
async def do(self, args): from yaml import safe_dump from moat.dev import DEV_DIR, DEV from moat.dev.base import _SOURCES tree = await self.root._get_tree() tree = tree.lookup(DEV_DIR) if self.options.list and self.options.show: raise CommandError("'-s' and '-l' are mutually exclusive") if self.options.list or self.options.show or len(args) < 2: if len(args) == 0: args = ((), ) for a in args: try: t = await tree.lookup(a) if len(args) == 1 and DEV in t and not self.options.list: self.options.show = True if self.options.show and DEV not in t: print("'%s': not a device.'" % (a, ), file=sys.stderr) continue if not self.options.list and DEV in t: d = await t[DEV] if self.options.dump: safe_dump(await rec_d(d), stream=self.stdout) else: print("device", d.path[len(DEV_DIR):-1], sep='\t', file=self.stdout) for k, v in d.items(): if k in _SOURCES: for n, c in v.items(): if hasattr(c, 'get'): c = c.get('value') print('%s/%s' % (k, n), c, sep='\t', file=self.stdout) else: print(k, v, sep='\t', file=self.stdout) print("") else: async for d in t.tagged(DEV): print('/'.join(d.path[len(DEV_DIR):-1]), sep='\t', file=self.stdout) except KeyError: print("'%s' does not exist" % (a, ), file=sys.stderr) continue else: try: t = tree.lookup(args[0], name=DEV) except KeyError: raise CommandError("Device '%a' not found" % (args[0], )) else: if '/' in args[1]: t = t.lookup(args[1]) if len(args) == 2: for k, v in t.items(): print(k, v.get('value', '??'), sep='\t', file=self.stdout) else: for a in args[1:]: try: print(a, t[a], sep='\t', file=self.stdout) except KeyError: print("%s: not found" % (a, ), file=sys.stderr) elif len(args) == 2 and args[1] in _SOURCES: t = t.lookup(args[1]) for k, v in t.items(): print(k, v, sep='\t', file=self.stdout) else: for a in args[1:]: try: print(a, t[a], sep='\t', file=self.stdout) except KeyError: print("%s: not found" % (a, ), file=sys.stderr)
async def do(self, args): try: data = {} taskdefpath = "" name = "" p = 0 taskpath = args[p].rstrip('/').lstrip('/') if taskpath == "": raise CommandError("Empty task path?") if taskpath[0] == ':' or '/:' in taskpath: raise CommandError("Don't add the tag") p += 1 if not self._update: taskdefpath = args[p].rstrip('/').lstrip('/') if taskdefpath == "": raise CommandError("Empty task definition path?") if taskdefpath[0] == ':' or '/:' in taskdefpath: raise CommandError("Don't add the tag") p += 1 while p < len(args): try: k, v = args[p].split('=') except ValueError: break p += 1 if k == "name": name = v else: data[k] = v if not self._update: args[p] # raises IndexError if nothing is left descr = " ".join(args[p:]) except IndexError: raise CommandError("Missing command parameters") t = await self.setup(meta=False) if not self._update: try: td = await self.setup(meta=True) taskdef = await td.subdir(taskdefpath, name=TASKDEF, create=False) except KeyError: raise CommandError("Taskdef '%s' not found" % taskdefpath) try: task = await t.subdir(taskpath, name=TASK, create=not self._update) except KeyError: raise CommandError( "Task '%s' not found. (Use its path, not the name?)" % taskpath) if not self._update: await task.set('taskdef', taskdefpath, sync=False) p = self.options.parent if p is not None: if p == '-': with suppress(KeyError): await task.delete('parent', sync=False) else: await task.set('parent', p, sync=False) if name: await task.set('name', name, sync=False) if descr: await task.set('descr', descr, sync=False) if data: d = await task.subdir('data', create=None) for k, v in data.items(): if v == "": try: await d.delete(k, sync=False) except KeyError: pass else: await d.set(k, v, sync=False, ext=True)
async def do(self,args): await self.root.setup(self) tree = self.root.tree seen = False if not args: t = await tree.lookup('bus','onewire') for srv,v in t.items(): try: v = await v['bus'] except (etcd.EtcdKeyNotFound,KeyError): pass else: for b in v.keys(): seen = True print(srv,b.replace(' ','/'), sep='\t',file=self.stdout) if self.root.verbose and not seen: print("No buses known.", file=sys.stderr) return srv = args.pop(0) if not args: try: t = await tree.subdir('bus','onewire',srv,'bus', create=False,recursive=True) except (etcd.EtcdKeyNotFound,KeyError): pass else: for bus,dc in t.items(): if dc.get('broken',0): print(bus,"*inaccessible*", sep='\t',file=self.stdout) seen = True dc = dc.get('devices',{}) items = [] for typ,v in dc.items(): try: dt = device_types()[typ] tname = dt.name except KeyError: dt = OnewireDevice tname = '?'+typ items.append("%s:%d"%(tname,len(v))) print(bus.replace(' ','/'),*items, sep='\t',file=self.stdout) seen = True if self.root.verbose and not seen: print("No buses known.", file=sys.stderr) return bus = args.pop(0) if args: raise CommandError("Usage: conn onewire bus [server [bus]]") bus = bus.replace('/',' ') try: t = await tree.subdir('bus','onewire',srv, 'bus',bus,'devices', create=False,recursive=True) except (etcd.EtcdKeyNotFound,KeyError): raise CommandError("Bus %s:%s does not exist." % (srv,bus)) for typ,v in t.items(): try: dt = device_types()[typ] tname = dt.name except KeyError: dt = OnewireDevice tname = '?'+typ for dev in v.keys(): print(typ+'.'+dev, tname) seen = True if self.root.verbose and not seen: print("No devices known.", file=sys.stderr)