Commit c3e974d4 authored by Jérome Perrin's avatar Jérome Perrin

software/dufs: handle certificate renewal

Because dufs only reads certificate on startup it does not detect when
the certificate was renewed.

The only thing supported by dufs is to restart, but we can not restart
the service, because the partition can not communicate with the
supervisor.
To solve this, use another level of process supervisor: using zdaemon
we can run a process in the foreground, so that it stays under
slapos' supervisor control, but still expose a way to restart the
process using zdaemon API.
parent 40836b97
......@@ -15,4 +15,4 @@
[instance.cfg.in]
filename = instance.cfg.in
md5sum = 0cb3cbac5479581985e5446078217686
md5sum = 75f81b613078004304c6a0d39037caf6
......@@ -74,6 +74,7 @@ caucase.updater(
crl_path='${dufs-certificate:crl-file}',
key_path='${dufs-certificate:key-file}',
template_csr='${dufs-certificate-prepare-csr:csr}',
on_renew='${dufs-server-restart:wrapper-path}',
openssl=openssl_bin,
)}}
......@@ -134,25 +135,43 @@ caucase.caucased(
recipe = slapos.cookbook:generate.password
user = admin
[dufs-zdaemon-cfg]
recipe = slapos.recipe.template
inline =
<runner>
program ${dufs-server-bin:wrapper-path}
socket-name ${directory:var}/zds
daemon off
</runner>
output = ${directory:etc}/${:_buildout_section_name_}
[dufs-server]
recipe = slapos.cookbook:wrapper
command-line = {{ zdaemon_bin }} -C ${dufs-zdaemon-cfg:output} start
wrapper-path = ${directory:service}/${:_buildout_section_name_}
port = 19080
ip = ${instance-parameter:ipv6-random}
url = https://[${:ip}]:${:port}
[dufs-server-restart]
recipe = slapos.cookbook:wrapper
command-line = {{ zdaemon_bin }} -C ${dufs-zdaemon-cfg:output} restart
wrapper-path = ${directory:bin}/${:_buildout_section_name_}
[dufs-server-bin]
recipe = slapos.cookbook:wrapper
command-line =
{{ dufs_bin }}
--enable-cors
--bind ${:ip}
--port ${:port}
--bind ${dufs-server:ip}
--port ${dufs-server:port}
--allow-all
--auth /@${admin-password:user}:${admin-password:passwd}
--auth /pub@${admin-password:user}:${admin-password:passwd}@*
--tls-cert ${dufs-certificate:cert-file}
--tls-key ${dufs-certificate:key-file}
${directory:dufs-data-dir}
wrapper-path = ${directory:service}/${:_buildout_section_name_}
port = 19080
ip = ${instance-parameter:ipv6-random}
url = https://[${:ip}]:${:port}
wrapper-path = ${directory:bin}/${:_buildout_section_name_}
[dufs-listen-promise]
<= check-port-listening-promise
......
......@@ -10,6 +10,9 @@ parts =
caucase-eggs
instance.cfg.in
[zdaemon]
recipe = zc.recipe.egg
egg = ${:_buildout_section_name_}
[dufs]
recipe = slapos.recipe.cmmi
......@@ -33,6 +36,7 @@ context =
raw dash_bin ${dash:location}/bin/dash
raw curl_bin ${curl:location}/bin/curl
raw dufs_bin ${dufs:location}/bin/dufs
raw zdaemon_bin ${buildout:bin-directory}/${zdaemon:egg}
key template_monitor monitor2-template:output
import-list =
file caucase caucase-jinja2-library:target
......@@ -25,8 +25,10 @@
#
##############################################################################
import contextlib
import io
import os
import subprocess
import tempfile
import urllib.parse
......@@ -103,3 +105,32 @@ class TestFileServer(SlapOSInstanceTestCase):
)
self.assertEqual(resp.text, 'hello')
self.assertEqual(resp.status_code, requests.codes.ok)
def test_renew_cert(self):
def _getpeercert():
# XXX low level way to get get the server certificate
with requests.Session() as session:
pool = session.get(
self.connection_parameters['public-url'],
verify=self.ca_cert,
).raw._pool.pool
with contextlib.closing(pool.get()) as cnx:
return cnx.sock._sslobj.getpeercert()
cert_before = _getpeercert()
# execute certificate updater two month later, when it's time to renew certificate.
# use a timeout, because this service runs forever
subprocess.run(
(
'timeout',
'5',
'faketime',
'+2 months',
os.path.join(
self.computer_partition_root_path,
'etc/service/dufs-certificate-updater'),
),
capture_output=not self._debug,
)
cert_after = _getpeercert()
self.assertNotEqual(cert_before['notAfter'], cert_after['notAfter'])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment