ref: bc71c98fcf64345b38e7e342b9efe66b97ebaa25
parent: 47a17ff536441934c0a98bd83ef081796f133bf8
parent: 0d7c6fae35a1fe99a0b74fbbdf18942f68e20f81
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Oct 19 18:40:15 PDT 2023
Merge pull request #7 from halfwit/rework Rework
--- a/README.md
+++ b/README.md
@@ -39,8 +39,8 @@
A service can be added by creating a directory. Services may be read by anyone, but can only be modified by the creator or registry owner. Write requests must come from users in the same authdom.
Each service dir contains many of the following files:
- - addr
- - auth
+ - address
+ - authdom (Still a TODO)
- status (ok/down)
- uptime
- description
@@ -49,25 +49,15 @@
- It may be beneficial to expose an events file that `services` can do a blocking read on, waiting for a service to be removed/added
- `auth` is an optional address for the auth server to use
-## svc/services
+## svc/monitor
-Usage: `svc/services [-o] [-f servicesdb] [-s svcfs]`
+Usage: `svc/monitor [-o] [-s svcfs]`
- `-o` Alternate naming in services, `ipnet.sysname.svcname`
-- `-f` Read in services from db
- `-s` Address of svcfs
-Services connects to a `svcfs`, by default checking for an entry in your local ipnet=.
-Without `-f`, it checks for and parses `/cfg/$sysname/registry`. (`-f` and the default directroy are temporary stopgaps before services can be self-publishing)
-
-```
-## /cfg/mysystem/registry
-service=myservice
- addr=tcp!myserver!19294
- description='My shared service'
-```
-
-Services will populate your local /srv with an fd pointing to all records in the given `svcfs` as well as any local entries.
+monitor connects to a `svcfs`, by default checking for an entry in your local ipnet=.
+monitor will populate your local /srv with an fd pointing to all records in the given `svcfs`.
- If the status of a service changes from Ok, it will be automatically removed
- multiple instances can be run, one per svcfs
- on exit, all mounted services should be kept alive; so on start it should handle silently failing when an entry already exists
@@ -81,8 +71,14 @@
```
$ svc/query speakers
-service=speakers addr=livingroom!12345 description='Living room speakers' uptime=1239021 status=ok
-service=speakers addr=bedroom!1234 description='Bedroom speakers' uptime=123811 status=ok
+service=speakers address=livingroom!12345
+ description='Living room speakers'
+ uptime='4 days, 3 hour, 0 minutes'
+ status=ok
+service=speakers address=bedroom!1234
+ description='Bedroom speakers'
+ uptime='55 days, 0 hours, 2 minutes'
+ status=ok
```
## svc/publish
@@ -99,3 +95,4 @@
## Future
- Integration into `cpurc`
+- Allow setting an Authdom for a services
--- a/libservice/mkfile
+++ b/libservice/mkfile
@@ -6,6 +6,7 @@
svcdial.$O\
svcquery.$O\
svctimefmt.$O\
+ svcfree.$O\
HFILES=\
service.h
--- a/libservice/service.h
+++ b/libservice/service.h
@@ -30,3 +30,4 @@
int svctimefmt(Fmt *f);
int svcdial(char *netroot, char *authdom);
Service* svcquery(int fd, char *query, char **argv, int argc);
+void svcfree(Service *);
--- /dev/null
+++ b/libservice/svcfree.c
@@ -1,0 +1,14 @@
+#include <u.h>
+#include <libc.h>
+#include "service.h"
+
+void
+svcfree(Service *s)
+{
+ Service *sn;
+
+ for(; s; s = sn){
+ sn = s->next;
+ free(s);
+ }
+}
--- a/libservice/svctimefmt.c
+++ b/libservice/svctimefmt.c
@@ -5,14 +5,13 @@
int
svctimefmt(Fmt *f)
{
- vlong u, d, h, m, s;
+ vlong u, d, h, m;
/* Untested at the moment */
u = va_arg(f->args, vlong);
d = u / 86400;
- h = u % 3600; // Give remaining hours
- m = h % 60;
- s = m % 60;
+ h = u % 86400 / 3600;
+ m = u % 3600 / 60;
/* Print whole integer values for each */
- return fmtprint(f, "\'%d days, %d hours, %d minutes, %d seconds\'", (int)d, (int)h, (int)m, (int)s);
+ return fmtprint(f, "\'%d days, %d hours, %d minutes\'", (int)d, (int)h, (int)m);
}
--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,8 @@
drop\
publish\
query\
- svcfs
+ svcfs\
+ monitor
LIB=libservice/libservice.a$O
--- /dev/null
+++ b/monitor.c
@@ -1,0 +1,130 @@
+#include <u.h>
+#include <libc.h>
+#include "libservice/service.h"
+
+void monitor(char *,int, int, int);
+void publish(Service *, char *);
+
+static void
+usage(void)
+{
+ fprint(2, "usage: %s [-o] [-r timeout] [-a authdom] [-s svcfs]\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+ char *svcfs;
+ char *authdom;
+ int style, fd, pollrate;
+
+ svcfs = nil;
+ authdom = nil;
+ style = 1;
+ pollrate = 30;
+
+ ARGBEGIN{
+ case 's':
+ svcfs = EARGF(usage());
+ break;
+ case 'a':
+ authdom = EARGF(usage());
+ break;
+ case 'o':
+ style++;
+ break;
+ case 'r':
+ pollrate = atoi(EARGF(usage()));
+ break;
+ default:
+ usage();
+ }ARGEND
+ argv0 = "monitor";
+
+ if(argc > 0)
+ usage();
+ if((fd = svcdial(svcfs, authdom)) < 0){
+ fprint(2, "Unable to dial svcfs: %r\n");
+ exits("error");
+ }
+
+ if(authdom != nil){
+ monitor(authdom, fd, style, pollrate);
+ exits(0);
+ }
+ monitor("9front", fd, style, pollrate);
+ exits(0);
+
+}
+
+char *
+clean(char *addr)
+{
+ char *c;
+ if(strncmp(addr, "tcp!", 4) == 0)
+ addr += 4;
+ c = strchr(addr, '!');
+ if(c != nil)
+ *c='\0';
+ return addr ;
+}
+
+void
+monitor(char *authdom, int fd, int style, int rate)
+{
+ Service *svc, *s;
+ char srv[MAXADDR];
+ int i;
+
+ for(;;){
+ for(i=0; i < rate; i++)
+ sleep(1000);
+ svc = svcquery(fd, ".", nil, 0);
+ for(s = svc; s; s = s->next){
+ switch(style){
+ case 1:
+ sprint(srv, "/srv/%s.%s.%s", s->name, clean(s->address), authdom);
+ break;
+ case 2:
+ sprint(srv, "/srv/%s.%s.%s", authdom, clean(s->address), s->name);
+ break;
+ }
+ switch(s->status){
+ case Sok:
+ publish(s, srv);
+ break;
+ case Sdown:
+ remove(srv);
+ break;
+ case Sreg:
+ // No-op
+ break;
+ }
+ }
+ svcfree(svc);
+ }
+}
+
+void
+publish(Service *s, char *srv)
+{
+ char buf[128];
+ int f, fd;
+ char *dest;
+
+ /* TODO: stat first and bail before we double dial/create */
+
+ /* Dial */
+ dest = netmkaddr(s->address, 0, "9fs");
+ fd = dial(dest, 0, 0, 0);
+ if(fd < 0)
+ return;
+ f = create(srv, OWRITE, 0666);
+ if(f < 0)
+ return;
+ /* Publish fd from dial */
+ sprint(buf, "%d", fd);
+ write(f, buf, strlen(buf));
+ close(f);
+}
--- a/query.c
+++ b/query.c
@@ -33,11 +33,7 @@
if(s->next != nil)
print("\n");
}
- for(s = svcs; s;){
- svcs = s->next;
- free(s);
- s = svcs;
- }
+ svcfree(svcs);
}
void
--- a/services
+++ /dev/null
@@ -1,57 +1,0 @@
-#!/bin/rc
-
-$argv0 = $0
-
-fn usage {
- echo 'Usage:' $argv0 '[-o] [-f servicesdb] [-s svcfs]' >[1=2]
- exits 'usage'
-}
-
-dbfile=()
-svcfs=()
-order=1
-while(~ $1 -*){
- switch($1){
- case -o; order=2
- case *
- ~ $#* 1 && usage
- switch($1){
- case -f; dbfile=$2
- case -s; svcfs=$2
- case *; usage
- }
- shift
- }
- shift
-}
-
-! ~ $#* 0 && usage
-
-if(~ $svcfs "")
- svcfs=`{ndb/ipquery sys $sysname registry | sed 's/registry=//'}
-if(~ $svcfs ""){
- echo 'Unable to find Registry'
- exits 'registry'
-}
-# Ours, we check later for the one associated with svcfs
-# With -s, parse the addr ipnet if exists and use that instead
-ipnet=`{ndb/ipquery sys $sysname ipnet | sed 's/ipnet=//'}
-
-fn mount {
- # Mount up svcfs in our namespace
- srv -c -m $svcfs^'!16675' services /mnt/services
-
-}
-
-fn publish {
- # Try /cfg/sysname/services if not set
- # Initial read + post everything
- # - if we posted the service, service.local
-}
-
-fn serve {
-
-}
-
-# Walk the dir, parse addr file + build /srv/service.sysname.ipnet
-# With -o, /srv/ipnet.sysname.service
--- a/svcfs.c
+++ b/svcfs.c
@@ -411,7 +411,7 @@
sprint(data, "%s\n", f->svc->svc->address);
goto Readstr;
case Quptime:
- sprint(data, "%lld\n", f->svc->uptime);
+ sprint(data, "%lld\n", f->svc->svc->uptime);
goto Readstr;
case Qdesc:
sprint(data, "%s\n", f->svc->svc->description);
@@ -847,7 +847,7 @@
{
int fd;
- if(strncmp(svc->svc->address, "none", 4) == 0)
+ if(strcmp(svc->svc->address, "none") == 0)
return 2;
fd = dial(svc->svc->address, nil, nil, nil);
if(fd < 0){
@@ -856,9 +856,9 @@
return -1;
}
close(fd);
- if(svc->svc->status == Sok)
- return 1;
- return 0;
+ if(svc->svc->status != Sok)
+ return 0;
+ return 1;
}
void
@@ -876,7 +876,7 @@
for(i = 0; i < seconds; i++)
sleep(1000);
for(i = 0; i < NSVCS; i++)
- for(svc = services[i]; svc !=nil; svc = svc->link)
+ for(svc = services[i]; svc != nil; svc = svc->link){
switch(alive(svc)){
case -1:
/* Offline */
@@ -895,6 +895,7 @@
/* Still in setup */
break;
}
+ }
}
}