commit 37f9100f97610267fc25c2ae3f9d0b0e2621eaee Author: Anton Lydike Date: Fri Sep 10 14:31:02 2021 +0200 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a08fa3 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Jank Pipeline + +This is a minimal CI/CD pipeline built just as a fun side project. You might be able to use it on a private project for a quick and dirty hack, but should probably not use it for anything more serious. + +It has two components: `shellsrv` and `git-build`. + +# `shellsrv` +This tool is a quick way to glue networking capabilities to shell scripts. + +You call it by running `./shellsrv -p COMMAND [ARGS...]` + +It sets up an https server, and whenever a GET/PUSH/POST etc html request arrives, it calls `COMMAND ARGS ` and passes the request body as stdin to the created process... + +# `git-build` +This is designed to interface with the shellsrv script. It reads a ref from stdin json and then clones a git repo. diff --git a/git-build b/git-build new file mode 100755 index 0000000..7c8ee3b --- /dev/null +++ b/git-build @@ -0,0 +1,52 @@ +#!/usr/bin/env fish +# called using shellsrv git-build + +set -l repo $argv[1] +set -l path $argv[3] +set -l local_location (pwd) + +if test "$path" != '/build-pls' + echo "invalid path" + exit 1 +end + +set -l tmp_dir /tmp/build_(random) + +git clone $repo $tmp_dir +cd $tmp_dir + +# read json from stding - which is the request body +git checkout (jq -r '.after') + +# read config +set mount /pipeline +set envfile "" + +for l in (cat .ezpipe) + if test -z "$l" + continue + end + set -l parts (string split -m 1 "=" "$l") + set $parts[1] $parts[2] +end + +set docker_args + +if test -z "$image" + echo "image required" + exit 1 +end +if test -z "$entrypoint" + echo "entrypoint required" + exit 1 +end + +if test ! -z "$envfile" + set -a docker_args '--env-file' + set -a docker_args $local_location/$envfile +end + +docker run --rm $docker_args -v (pwd):$mount -w $mount $image $mount/$entrypoint + +cd .. +rm -rf $tmp_dir diff --git a/shellsrv b/shellsrv new file mode 100755 index 0000000..3220059 --- /dev/null +++ b/shellsrv @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +from http.server import BaseHTTPRequestHandler, HTTPServer +from subprocess import Popen, PIPE +from shlex import quote + +import argparse +import sys + +def server_class_factory(command): + class MyServer(BaseHTTPRequestHandler): + def do_GET(self): + self.handle_all() + def do_POST(self): + self.handle_all() + def do_PUT(self): + self.handle_all() + def handle_all(self): + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + content = self.rfile.read(int(self.headers.get('Content-Length', 0))) + p = Popen(command + [quote(self.command), quote(self.path)], stdin=PIPE, shell=False) + p.communicate(input=content) + + def log_message(self, format, *args): + return + return MyServer + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='shellsrv - Translate HTTP requests to command invocations on the host system.\n\n\nEach GET request results in the execution of COMMAND ARGS GET . Other HTTP verbs might be added later.', prog='shellsrv') + + parser.add_argument('--host', '-H', type=str, help='HTTP server host, default 0.0.0.0', default="0.0.0.0") + parser.add_argument('--port', '-p', type=int, help='HTTP server port, default 8080', default=8080) + parser.add_argument('--limit', '-n', type=int, help='Close the server after limit requests', default=-1) + parser.add_argument('command', metavar='COMMAND', type=str, nargs=1, help='command to call') + parser.add_argument('args', metavar='ARG', type=str, nargs='*', help='args of the command to call') + + args = parser.parse_args() + + command = args.command + args.args + request_limit = args.limit + + server = HTTPServer((args.host, args.port), server_class_factory(command)) + print("Server started http://%s:%s" % (args.host, args.port), file=sys.stderr) + + if request_limit < 0: + try: + server.serve_forever() + except KeyboardInterrupt: + pass + else: + for _ in range(request_limit): + server.handle_request() + + server.server_close() \ No newline at end of file