mirror of
https://github.com/laurivosandi/certidude
synced 2024-12-22 16:25:17 +00:00
Better starttup/shutdown notification
This commit is contained in:
parent
d44b6035c2
commit
03b9778170
@ -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())
|
||||
httpd.serve_forever()
|
||||
|
||||
# Shut down signer as well
|
||||
assert authority.signer_exec("exit") == "ok"
|
||||
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user