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