mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 01:19:11 +00:00 
			
		
		
		
	Better starttup/shutdown notification
This commit is contained in:
		| @@ -1284,15 +1284,14 @@ def certidude_cron(): | ||||
|  | ||||
|  | ||||
| @click.command("serve", help="Run server") | ||||
| @click.option("-e", "--exit-handler", default=False, is_flag=True, help="Install /api/exit/ handler") | ||||
| @click.option("-p", "--port", default=8080, help="Listen port") | ||||
| @click.option("-l", "--listen", default="127.0.1.1", help="Listen address") | ||||
| @click.option("-f", "--fork", default=False, is_flag=True, help="Fork to background") | ||||
| def certidude_serve(port, listen, fork, exit_handler): | ||||
| def certidude_serve(port, listen, fork): | ||||
|     import pwd | ||||
|     from setproctitle import setproctitle | ||||
|     from certidude.signer import SignServer | ||||
|     from certidude import authority, const | ||||
|     from certidude import authority, const, push | ||||
|  | ||||
|     if port == 80: | ||||
|         click.echo("WARNING: Please run Certidude behind nginx, remote address is assumed to be forwarded by nginx!") | ||||
| @@ -1332,7 +1331,8 @@ def certidude_serve(port, listen, fork, exit_handler): | ||||
|     if os.path.exists(const.SIGNER_SOCKET_PATH): | ||||
|         os.unlink(const.SIGNER_SOCKET_PATH) | ||||
|  | ||||
|     if not os.fork(): | ||||
|     signer_pid = os.fork() | ||||
|     if not signer_pid: | ||||
|         click.echo("Signer process spawned with PID %d at %s" % (os.getpid(), const.SIGNER_SOCKET_PATH)) | ||||
|         setproctitle("[signer]") | ||||
|  | ||||
| @@ -1421,29 +1421,23 @@ def certidude_serve(port, listen, fork, exit_handler): | ||||
|         with open(const.SERVER_PID_PATH, "w") as pidfile: | ||||
|             pidfile.write("%d\n" % pid) | ||||
|  | ||||
|         def exit_handler(): | ||||
|         def cleanup_handler(*args): | ||||
|             push.publish("server-stopped") | ||||
|             logger.debug(u"Shutting down Certidude") | ||||
|         import atexit | ||||
|         atexit.register(exit_handler) | ||||
|             assert authority.signer_exec("exit") == "ok" | ||||
|             sys.exit(0) # TODO: use another code, needs test refactor | ||||
|  | ||||
|         import signal | ||||
|         signal.signal(signal.SIGTERM, cleanup_handler) # Handle SIGTERM from systemd | ||||
|  | ||||
|         push.publish("server-started") | ||||
|         logger.debug(u"Started Certidude at %s", const.FQDN) | ||||
|  | ||||
|         drop_privileges() | ||||
|  | ||||
|         class ExitResource(): | ||||
|             """ | ||||
|             Provide way to gracefully shutdown server | ||||
|             """ | ||||
|             def on_get(self, req, resp): | ||||
|                 assert httpd._BaseServer__shutdown_request == False | ||||
|                 httpd._BaseServer__shutdown_request = True | ||||
|  | ||||
|         if exit_handler: | ||||
|             app.add_route("/api/exit/", ExitResource()) | ||||
|         try: | ||||
|             httpd.serve_forever() | ||||
|  | ||||
|         # Shut down signer as well | ||||
|         assert authority.signer_exec("exit") == "ok" | ||||
|  | ||||
|         except KeyboardInterrupt: | ||||
|             cleanup_handler() # FIXME | ||||
|  | ||||
|  | ||||
| @click.command("yubikey", help="Set up Yubikey as client authentication token") | ||||
|   | ||||
| @@ -7,12 +7,11 @@ from datetime import datetime | ||||
| from certidude import config | ||||
|  | ||||
|  | ||||
| def publish(event_type, event_data): | ||||
| def publish(event_type, event_data=''): | ||||
|     """ | ||||
|     Publish event on nchan EventSource publisher | ||||
|     """ | ||||
|     assert event_type, "No event type specified" | ||||
|     assert event_data, "No event data specified" | ||||
|  | ||||
|     if not isinstance(event_data, basestring): | ||||
|         from certidude.decorators import MyEncoder | ||||
|   | ||||
| @@ -22,6 +22,9 @@ | ||||
|           <li id="section-log" data-section="log" style="display:none;">Log</li> | ||||
|         </ul> | ||||
|     </nav> | ||||
|     <div id="under_maintenance" class="container" style="display:none;"> | ||||
|         Server under maintenance... | ||||
|     </div> | ||||
|     <div id="container" class="container"> | ||||
|         Loading certificate authority... | ||||
|     </div> | ||||
|   | ||||
| @@ -199,6 +199,18 @@ function onAttributeUpdated(e) { | ||||
|     }) | ||||
| } | ||||
|  | ||||
| function onServerStarted() { | ||||
|     console.info("Server started"); | ||||
|     location.reload(); | ||||
| } | ||||
|  | ||||
| function onServerStopped() { | ||||
|     $("#container").hide(); | ||||
|     $("#under_maintenance").show(); | ||||
|     console.info("Server stopped"); | ||||
|  | ||||
| } | ||||
|  | ||||
| $(document).ready(function() { | ||||
|     console.info("Loading CA, to debug: curl " + window.location.href + " --negotiate -u : -H 'Accept: application/json'"); | ||||
|     $.ajax({ | ||||
| @@ -247,6 +259,8 @@ $(document).ready(function() { | ||||
|                 source.addEventListener("certificate-revoked", onCertificateRevoked); | ||||
|                 source.addEventListener("tag-update", onTagUpdated); | ||||
|                 source.addEventListener("attribute-update", onAttributeUpdated); | ||||
|                 source.addEventListener("server-started", onServerStarted); | ||||
|                 source.addEventListener("server-stopped", onServerStopped); | ||||
|  | ||||
|                 console.info("Swtiching to requests section"); | ||||
|                 $("section").hide(); | ||||
|   | ||||
| @@ -5,7 +5,6 @@ After=network.target | ||||
| [Service] | ||||
| Environment=PYTHON_EGG_CACHE=/tmp/.cache | ||||
| PIDFile=/run/certidude/server.pid | ||||
| ExecReload=/bin/kill -s HUP $MAINPID | ||||
| ExecStop=/bin/kill -s TERM $MAINPID | ||||
| ExecStart={{ certidude_path }} serve | ||||
|  | ||||
|   | ||||
| @@ -270,7 +270,7 @@ def test_cli_setup_authority(): | ||||
|     server_pid = os.fork() | ||||
|     if not server_pid: | ||||
|         # Fork to prevent umask, setuid, setgid side effects | ||||
|         result = runner.invoke(cli, ['serve', '-p', '8080', '-l', '127.0.1.1', '-e']) | ||||
|         result = runner.invoke(cli, ['serve']) | ||||
|         assert not result.exception, result.output | ||||
|         return | ||||
|  | ||||
| @@ -988,7 +988,7 @@ def test_cli_setup_authority(): | ||||
|     #################################### | ||||
|  | ||||
|     # Shut down current instance | ||||
|     requests.get("http://ca.example.lan/api/exit") | ||||
|     os.kill(server_pid, 15) | ||||
|     requests.get("http://ca.example.lan/api/") | ||||
|     os.waitpid(server_pid, 0) | ||||
|  | ||||
| @@ -1051,7 +1051,7 @@ def test_cli_setup_authority(): | ||||
|         assert "admin;adminbot;Admin;Bot;adminbot@example.lan" in result.output | ||||
|         assert "admin;Administrator;Administrator;;Administrator@example.lan" in result.output | ||||
|  | ||||
|         result = runner.invoke(cli, ['serve', '-p', '8080', '-l', '127.0.1.1', '-e']) | ||||
|         result = runner.invoke(cli, ['serve']) | ||||
|         assert not result.exception, result.output | ||||
|         return | ||||
|  | ||||
| @@ -1179,7 +1179,7 @@ def test_cli_setup_authority(): | ||||
|  | ||||
|     # Shut down server | ||||
|     assert os.path.exists("/proc/%d" % server_pid) | ||||
|     requests.get("http://ca.example.lan/api/exit") | ||||
|     os.kill(server_pid, 15) | ||||
|     os.waitpid(server_pid, 0) | ||||
|  | ||||
|     # Note: STORAGE_PATH was mangled above, hence it's /tmp not /var/lib/certidude | ||||
|   | ||||
		Reference in New Issue
	
	Block a user