From 95a41a395fa778680b3dc93c845407eb8a1a0ae1 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Mon, 25 Jun 2018 13:01:27 -0400 Subject: [PATCH] Use a multithreaded python server to serve RPMs SimpleHTTPServer is single threaded and so a long download will cause liveness checks to fail. This is a more complicated variant that runs multiple threads. --- pkg/steps/rpm_server.go | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/pkg/steps/rpm_server.go b/pkg/steps/rpm_server.go index cd14bbc1..b91dcb23 100644 --- a/pkg/steps/rpm_server.go +++ b/pkg/steps/rpm_server.go @@ -93,9 +93,46 @@ func (s *rpmServerStep) Run(ctx context.Context, dry bool) error { Name: RPMRepoName, Image: imageReference, ImagePullPolicy: coreapi.PullAlways, - Command: []string{"/bin/python"}, - Args: []string{"-m", "SimpleHTTPServer", "8080"}, - WorkingDir: RPMServeLocation, + + // SimpleHTTPServer is too simple - it can't handle threading. Use a threaded implementation + // that binds multiple simple servers to the same port. + Command: []string{"/bin/bash", "-c"}, + Args: []string{ + ` +#!/bin/bash +cat <>/tmp/serve.py +import time, threading, socket, SocketServer, BaseHTTPServer, SimpleHTTPServer + +# Create socket +addr = ('', 8080) +sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.bind(addr) +sock.listen(5) + +# Launch multiple listeners as threads +class Thread(threading.Thread): + def __init__(self, i): + threading.Thread.__init__(self) + self.i = i + self.daemon = True + self.start() + def run(self): + httpd = BaseHTTPServer.HTTPServer(addr, SimpleHTTPServer.SimpleHTTPRequestHandler, False) + + # Prevent the HTTP server from re-binding every handler. + # https://stackoverflow.com/questions/46210672/ + httpd.socket = sock + httpd.server_bind = self.server_close = lambda self: None + + httpd.serve_forever() +[Thread(i) for i in range(100)] +time.sleep(9e9) +END +python /tmp/serve.py + `, + }, + WorkingDir: RPMServeLocation, Ports: []coreapi.ContainerPort{{ ContainerPort: 8080, Protocol: coreapi.ProtocolTCP,