diff --git a/cdist/trigger.py b/cdist/trigger.py index 88986dd8..b53f4ad1 100644 --- a/cdist/trigger.py +++ b/cdist/trigger.py @@ -21,35 +21,90 @@ # import logging -import os -import sys -import time -import tempfile +import re +import socket +import http.server + from http.server import BaseHTTPRequestHandler, HTTPServer +import multiprocessing import cdist -from cdist import core + +log = logging.getLogger(__name__) class Trigger(): """cdist trigger handling""" - def __init__(self, dry_run=False): + def __init__(self, http_port=None, dry_run=False, ipv4only=False): self.log = logging.getLogger("trigger") self.dry_run = dry_run + self.http_port = int(http_port) + self.ipv4only = ipv4only + + # can only be set once + multiprocessing.set_start_method('forkserver') + + def run_httpd(self): + server_address = ('', self.http_port) + + if self.ipv4only: + httpd = HTTPServerV4(server_address, TriggerHttp) + else: + httpd = HTTPServerV6(server_address, TriggerHttp) - def run_http(self): - server_address = ('0.0.0.0', 8000) - httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) - print('running server...') httpd.serve_forever() + def run(self): + if self.http_port: + self.run_httpd() + @staticmethod def commandline(args): - print("all good") - pass - + t = Trigger(http_port=args.http_port, ipv4only=args.ipv4) + t.run() class TriggerHttp(BaseHTTPRequestHandler): + def __init__(self, *args, **kwargs): + http.server.BaseHTTPRequestHandler.__init__(self, *args, **kwargs) + def do_GET(self): - pass + # FIXME: dispatch to pool instead of single process + host = self.client_address[0] + code = 200 + mode = None + + m = re.match("^/(?Pconfig|install)/.*", self.path) + if m: + mode = m.group('mode') + else: + code = 404 + + if mode: + self.run_cdist(mode, host) + + self.send_response(code) + self.end_headers() + + def do_HEAD(self): + self.do_GET() + + def do_POST(self): + self.do_GET() + + def run_cdist(self, mode, host): + log.debug("Running cdist {} {}".format(mode, host)) + + +class HTTPServerV4(http.server.HTTPServer): + """ + Server that listens to IPv4 and IPv6 requests + """ + address_family = socket.AF_INET + + +class HTTPServerV6(http.server.HTTPServer): + """ + Server that listens both to IPv4 and IPv6 requests + """ + address_family = socket.AF_INET6 diff --git a/scripts/cdist b/scripts/cdist index 2b11827b..8c6b62db 100755 --- a/scripts/cdist +++ b/scripts/cdist @@ -175,12 +175,18 @@ def commandline(): ' should be POSIX compatible shell.')) parser['shell'].set_defaults(func=cdist.shell.Shell.commandline) + # Trigger parser['trigger'] = parser['sub'].add_parser( 'trigger', parents=[parser['loglevel'], parser['beta']]) + parser['trigger'].add_argument( + '-4', '--ipv4', + help=('Listen only to IPv4 (instead of IPv4 and IPv4)'), action='store_true') parser['trigger'].add_argument( '-H', '--http-port', - help=('Create trigger listener via http on specified port'), - action='append') + help=('Create trigger listener via http on specified port')) + parser['trigger'].add_argument( + '-n', '--dry-run', + help='Do not execute code', action='store_true') parser['trigger'].set_defaults(func=cdist.trigger.Trigger.commandline) # Install