https://github.com/gromnitsky/servizi-di-base
Run homelab scripts as remote jobs via POST requests. 0 configuration, no yaml, no json, no docker, no kubernetes
https://github.com/gromnitsky/servizi-di-base
webhook-server
Last synced: 7 months ago
JSON representation
Run homelab scripts as remote jobs via POST requests. 0 configuration, no yaml, no json, no docker, no kubernetes
- Host: GitHub
- URL: https://github.com/gromnitsky/servizi-di-base
- Owner: gromnitsky
- Created: 2025-03-10T20:13:43.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2025-03-13T16:57:41.000Z (7 months ago)
- Last Synced: 2025-03-13T17:53:26.432Z (7 months ago)
- Topics: webhook-server
- Language: JavaScript
- Homepage:
- Size: 17.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
~~~
$ scc *js | grep ^[LJ]
Language Files Lines Blanks Comments Code Complexity
JavaScript 1 275 48 5 222 41
~~~## Reqs
node v22, script(1) with `-e` option support (macOS 14.6.1 Sonoma).
As it runs user services through a PTY, it's incompatible with Windows
(WSL2 excluded).## Usage
The simplest "webhook" script:
~~~
$ cat my-uptime
#!/bin/sh
uptime > result
~~~Trigger such a script:
~~~
$ curl -si http://127.0.0.1:3000/my-uptime -F a=@/dev/null
HTTP/1.1 100 ContinueHTTP/1.1 200 OK
Date: Mon, 10 Mar 2025 18:27:07 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 12jobs/Dxh6Wf
~~~To get the result, use a job id, `jobs/Dxh6Wf` in this case:
~~~
$ curl -si http://127.0.0.1:3000/jobs/Dxh6Wf
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Date: Mon, 10 Mar 2025 18:29:46 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Transfer-Encoding: chunked20:27:12 up 13 days, 7:27, 2 users, load average: 0.20, 0.32, 0.31
~~~## Reqs for scripts
1. collect all data you want to return in a tmp file, then do an
atomic:$ mv my-tmp-file result
2. your script runs in a temp dir that is automatically deleted once a
user retrieves `result` file;3. don't write to `pid`, `cmd` and `log` files (all your stdout/stderr
automatically goes to `log` file);4. don't read stdin, it's null;
5. the files the user submits have names like `payload.0`, `payload.1`,
&c; these names are passed to your script as arguments.6. do the usual command line arguments parsing; when a user submits
http://127.0.0.1:3000/my-uptime?-f=1&-b=2
your script gets 4 distinct arguments `-f`, `1`, `-b`, `2` and
`payload.0` as the last argument;7. any other exit code except 0 indicates that your script has failed.
## Server usage
[HOST=127.0.0.1] [PORT=3000] ./server.js [dir-with-scripts]
If no `dir-with-scripts` is provided the current directory is used.
## Invoking scripts
$ curl -si http://$HOST:$PORT/script-name -F a=@/dev/null
Even if the remote script doesn't need a payload, an empty file in a
multipart/form-data POST request is required.To pass any options, use url search params:
script-name?--foo=bar&--baz=quix
would appear to remote script as 4 arguments `--foo`, `bar`, `--baz`,
`quix`. It's up to the script what to do with them.Endpoints:
* POST `/script-name`. This returns a job id in the form of
`jobs/XXXXXX`.
* GET `/jobs/XXXXXX` returns either 200 with the script result, 500 if
the script failed, 418 if the script is still running, or 404 if the
job is missing. If you get 200, the job XXXXXX is also removed from
the server, meaning you can read a successful response only once.
* GET `/jobs/XXXXXX/log` returns either 418 (with the stdout/stderr of
the script) if the job is pending, or 200 if it's finished.
* GET `/jobs/XXXXXX/kill` sends SIGKILL to the script & its children.## ♲ Loicense
MIT