Commit 6a2edf34 authored by Łukasz Nowak's avatar Łukasz Nowak

Update release candidate

parents 98a5fab8 9631b57e
......@@ -7,8 +7,11 @@ url = https://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.46.tar.
md5sum = efce5529c1f0a39dafdd532c619503f1
# See https://download.pureftpd.org/pub/pure-ftpd/doc/README for more configurations
# We need the trick about UPLOAD_PIPE_FILE and UPLOAD_PIPE_LOCK so that the files are created inside the $CWD/var/run
# WARNING: this means that both pure-ftpd and pure-uploadscript binaries must be launched in $HOME !
configure-options =
--with-uploadscript
#environment =
# Probably it is missing dependencies to be set here.
--with-puredb
--with-nonroot
environment=
CFLAGS=-DUPLOAD_PIPE_FILE='"/proc/self/cwd/var/run/pure-ftpd.upload.pipe"' -DUPLOAD_PIPE_LOCK='"/proc/self/cwd/var/run/pure-ftpd.upload.lock"'
......@@ -30,7 +30,7 @@ md5sum = 99ec567c429ff82571d08818eaaed390
[template-slave-list]
filename = templates/apache-custom-slave-list.cfg.in
md5sum = d2e0132dded2f65e3590c72a154f6dd6
md5sum = 3faad78c80b0e9235849f0b5346eebbc
[template-slave-configuration]
filename = templates/custom-virtualhost.conf.in
......@@ -102,7 +102,7 @@ md5sum = 89839a3f4ab71cab459afd1c27d00326
[template-configuration-state-script]
filename = templates/configuration-state-script.sh.in
md5sum = 8d55aea0a4ebc262d2f7c2f96dd5428c
md5sum = 4d2537d2698d32a7e909989f8778d144
[template-rotate-script]
filename = templates/rotate-script.sh.in
......
......@@ -117,7 +117,9 @@ output = {{ plugin_directory }}/${:name}
{% if enable_cache and 'url' in slave_instance %}
{% if 'domain' in slave_instance %}
{% do slave_instance.__setitem__('custom_domain', slave_instance.get('domain')) %}
{% if not slave_instance.get('custom_domain') %}
{% do slave_instance.__setitem__('custom_domain', slave_instance.get('domain')) %}
{% endif %}
{% endif %}
{% do slave_instance.__setitem__('backend_url', slave_instance.get('url')) %}
{% do slave_instance.__setitem__('https_backend_url', slave_instance.get('https-url', slave_instance.get('url'))) %}
......
......@@ -10,9 +10,9 @@ touch $SIGNATURE_FILE
if diff "$SIGNATURE_FILE" "$NSIGNATURE_FILE" > /dev/null ; then
# No changes since last run just propagate information
rm -f ${NSIGNATURE_FILE}
exit 0
exit 1
else
# Changes since last run, so store new value and propagate information
mv "$NSIGNATURE_FILE" "$SIGNATURE_FILE"
exit 1
exit 0
fi
......@@ -1080,12 +1080,17 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
},
'custom_domain': {
'url': cls.backend_url,
'custom_domain': 'customdomain.example.com',
'custom_domain': 'mycustomdomain.example.com',
},
'custom_domain_wildcard': {
'url': cls.backend_url,
'custom_domain': '*.customdomain.example.com',
},
'custom_domain_server_alias': {
'url': cls.backend_url,
'custom_domain': 'mycustomdomainserveralias.example.com',
'server-alias': 'mycustomdomainserveralias1.example.com',
},
'custom_domain_ssl_crt_ssl_key': {
'url': cls.backend_url,
'custom_domain': 'customdomainsslcrtsslkey.example.com',
......@@ -1185,6 +1190,16 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
'url': cls.backend_url,
'enable_cache': True,
},
'enable_cache_custom_domain': {
'url': cls.backend_url,
'enable_cache': True,
'custom_domain': 'customdomainenablecache.example.com',
},
'enable_cache_server_alias': {
'url': cls.backend_url,
'enable_cache': True,
'server-alias': 'enablecacheserveralias1.example.com',
},
'enable_cache-disable-no-cache-request': {
'url': cls.backend_url,
'enable_cache': True,
......@@ -1343,9 +1358,9 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
expected_parameter_dict = {
'monitor-base-url': None,
'domain': 'example.com',
'accepted-slave-amount': '48',
'accepted-slave-amount': '51',
'rejected-slave-amount': '5',
'slave-amount': '53',
'slave-amount': '56',
'rejected-slave-dict': {
"_apache_custom_http_s-rejected": ["slave not authorized"],
"_caddy_custom_http_s": ["slave not authorized"],
......@@ -1932,7 +1947,22 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
)
def test_custom_domain(self):
parameter_dict = self.assertSlaveBase('custom_domain')
reference = 'custom_domain'
hostname = 'mycustomdomain'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': SLAPOS_TEST_IPV4,
},
parameter_dict
)
result = self.fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
......@@ -1943,6 +1973,43 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
self.assertEqualResultJson(result, 'Path', '/test-path')
def test_custom_domain_server_alias(self):
reference = 'custom_domain_server_alias'
hostname = 'mycustomdomainserveralias'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': SLAPOS_TEST_IPV4,
},
parameter_dict
)
result = self.fakeHTTPSResult(
parameter_dict['domain'], parameter_dict['public-ipv4'], 'test-path')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path')
result = self.fakeHTTPSResult(
'mycustomdomainserveralias1.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper')
self.assertEqual(
self.certificate_pem,
der2pem(result.peercert))
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
def test_custom_domain_wildcard(self):
parameter_dict = self.parseSlaveParameterDict('custom_domain_wildcard')
self.assertLogAccessUrlWithPop(parameter_dict)
......@@ -2884,6 +2951,141 @@ http://apachecustomhttpsaccepted.example.com:%%(http_port)s {
}
)
def test_enable_cache_custom_domain(self):
reference = 'enable_cache_custom_domain'
hostname = 'customdomainenablecache'
parameter_dict = self.parseSlaveParameterDict(reference)
self.assertLogAccessUrlWithPop(parameter_dict)
self.assertKedifaKeysWithPop(parameter_dict, '')
self.assertEqual(
{
'domain': '%s.example.com' % (hostname,),
'replication_number': '1',
'url': 'http://%s.example.com' % (hostname, ),
'site_url': 'http://%s.example.com' % (hostname, ),
'secure_access': 'https://%s.example.com' % (hostname, ),
'public-ipv4': SLAPOS_TEST_IPV4,
},
parameter_dict
)
result = self.fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.6\)$'
)
def test_enable_cache_server_alias(self):
parameter_dict = self.assertSlaveBase('enable_cache_server_alias')
result = self.fakeHTTPResult(
parameter_dict['domain'], parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.6\)$'
)
result = self.fakeHTTPResult(
'enablecacheserveralias1.example.com', parameter_dict['public-ipv4'],
'test-path/deep/.././deeper', headers={
'X-Reply-Header-Cache-Control': 'max-age=1, stale-while-'
'revalidate=3600, stale-if-error=3600'})
self.assertEqualResultJson(result, 'Path', '/test-path/deeper')
headers = result.headers.copy()
self.assertKeyWithPop('Server', headers)
self.assertKeyWithPop('Date', headers)
self.assertKeyWithPop('Age', headers)
# drop keys appearing randomly in headers
headers.pop('Transfer-Encoding', None)
headers.pop('Content-Length', None)
headers.pop('Connection', None)
headers.pop('Keep-Alive', None)
self.assertEqual(
{
'Content-type': 'application/json',
'Set-Cookie': 'secured=value;secure, nonsecured=value',
'Cache-Control': 'max-age=1, stale-while-revalidate=3600, '
'stale-if-error=3600'
},
headers
)
backend_headers = result.json()['Incoming Headers']
via = backend_headers.pop('via', None)
self.assertNotEqual(via, None)
self.assertRegexpMatches(
via,
r'^http\/1.1 caddy-frontend-1\[.*\] \(ApacheTrafficServer\/7.1.6\)$'
)
def test_enable_cache(self):
parameter_dict = self.assertSlaveBase('enable_cache')
......@@ -4038,6 +4240,10 @@ class TestQuicEnabled(SlaveHttpFrontendTestCase, TestDataMixin):
if 'frontend_caddy' in q['name']][0]
os.kill(caddy_pid, signal.SIGUSR1)
# give caddy a moment to refresh its config, as sending signal does not
# block until caddy is refreshed
time.sleep(2)
assertQUIC()
......
......@@ -14,7 +14,11 @@ T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-u
T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_custom_domain_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_custom_domain_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_server_alias_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_server_alias_error_log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_Url_access_log
T-2/var/log/httpd/_Url_error_log
......@@ -24,6 +28,8 @@ T-2/var/log/httpd/_caddy_custom_http_s-accepted_access_log
T-2/var/log/httpd/_caddy_custom_http_s-accepted_error_log
T-2/var/log/httpd/_custom_domain_access_log
T-2/var/log/httpd/_custom_domain_error_log
T-2/var/log/httpd/_custom_domain_server_alias_access_log
T-2/var/log/httpd/_custom_domain_server_alias_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_access_log
......@@ -49,7 +55,11 @@ T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_err
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_enable_cache_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_error_log
T-2/var/log/httpd/_enable_cache_error_log
T-2/var/log/httpd/_enable_cache_server_alias_access_log
T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log
......
......@@ -14,7 +14,11 @@ T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-u
T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd-cache-direct/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_custom_domain_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_custom_domain_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_error_log
T-2/var/log/httpd-cache-direct/_enable_cache_server_alias_access_log
T-2/var/log/httpd-cache-direct/_enable_cache_server_alias_error_log
T-2/var/log/httpd-csr_id/expose-csr_id.log
T-2/var/log/httpd/_Url_access_log
T-2/var/log/httpd/_Url_error_log
......@@ -24,6 +28,8 @@ T-2/var/log/httpd/_caddy_custom_http_s-accepted_access_log
T-2/var/log/httpd/_caddy_custom_http_s-accepted_error_log
T-2/var/log/httpd/_custom_domain_access_log
T-2/var/log/httpd/_custom_domain_error_log
T-2/var/log/httpd/_custom_domain_server_alias_access_log
T-2/var/log/httpd/_custom_domain_server_alias_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_access_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_error_log
T-2/var/log/httpd/_custom_domain_ssl_crt_ssl_key_ssl_ca_crt_access_log
......@@ -49,7 +55,11 @@ T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt-unverified_err
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_access_log
T-2/var/log/httpd/_enable_cache-ssl-proxy-verify_ssl_proxy_ca_crt_error_log
T-2/var/log/httpd/_enable_cache_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_access_log
T-2/var/log/httpd/_enable_cache_custom_domain_error_log
T-2/var/log/httpd/_enable_cache_error_log
T-2/var/log/httpd/_enable_cache_server_alias_access_log
T-2/var/log/httpd/_enable_cache_server_alias_error_log
T-2/var/log/httpd/_https-only_access_log
T-2/var/log/httpd/_https-only_error_log
T-2/var/log/httpd/_monitor-ipv4-test_access_log
......
......@@ -97,6 +97,16 @@ class TestDefaultParameters(ERP5TestCase, TestPublishedURLIsReachableMixin):
__partition_reference__ = 'defp'
class TestWSGI(ERP5TestCase, TestPublishedURLIsReachableMixin):
"""Test ERP5 WSGI server
"""
__partition_reference__ = 'wsgi'
@classmethod
def getInstanceParameterDict(cls):
return {'_': json.dumps({'wsgi': True})}
class TestApacheBalancerPorts(ERP5TestCase):
"""Instanciate with two zope families, this should create for each family:
- a balancer entry point with corresponding haproxy
......
[buildout]
extends = https://lab.nexedi.com/nexedi/slapos/raw/8deeab28fb7d4fd527c2df05f74fcaf27c8df218/software/kvm/software.cfg
extends = https://lab.nexedi.com/nexedi/slapos/raw/1.0.111/software/kvm/software.cfg
# PyPi servers from new host since some time and change is not incorporated in extended KVM SR
allow-hosts +=
......
......@@ -73,7 +73,7 @@ jupyter-client = 5.0.0
jupyter-core = 4.3.0
jupyterlab = 0.26.3
jupyterlab-launcher = 0.3.1
matplotlib = 2.0.0
matplotlib = 2.0.1
mistune = 0.7.3
nbformat = 4.3.0
notebook = 4.4.1
......
......@@ -59,7 +59,7 @@ md5sum = 2036bf145f472f62ef8dee5e729328fd
[template-kvm-run]
filename = template/template-kvm-run.in
md5sum = c8ca875bf246997137552538ab9d8b1a
md5sum = 2a49e6065a3f46f871318ba88f0cd235
[template-kvm-controller]
filename = template/kvm-controller-run.in
......
......@@ -302,7 +302,7 @@ kvm_argument_list = [qemu_path,
disk_aio, additional_disk_options),
'-vnc', '%s:1,ipv4,password' % listen_ip,
'-boot', 'order=cd,menu=on',
'-qmp', 'unix:%s,server' % socket_path,
'-qmp', 'unix:%s,server,nowait' % socket_path,
'-pidfile', pid_file_path, '-msg', 'timestamp=on',
'-D', logfile,
]
......
Pureftpd with upload script
https://www.pureftpd.org/project/pure-ftpd
# Features
* After each upload, call the script /opt/pureftpd/upload_script
# THIS IS NOT A BUILDOUT FILE, despite purposedly using a compatible syntax.
# The only allowed lines here are (regexes):
# - "^#" comments, copied verbatim
# - "^[" section beginings, copied verbatim
# - lines containing an "=" sign which must fit in the following categorie.
# - "^\s*filename\s*=\s*path\s*$" where "path" is relative to this file
# Copied verbatim.
# - "^\s*hashtype\s*=.*" where "hashtype" is one of the values supported
# by the re-generation script.
# Re-generated.
# - other lines are copied verbatim
# Substitution (${...:...}), extension ([buildout] extends = ...) and
# section inheritance (< = ...) are NOT supported (but you should really
# not need these here).
[instance-profile]
filename = instance.cfg.in
md5sum = c352c6f11b7a00dca0a544f7ecddeb52
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Parameters to instantiate Pure-FTPd",
"additionalProperties": false,
"properties": {
"port": {
"title": "FTP port",
"description": "Port number to listen to - default to 8021",
"type": "number"
}
}
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Values returned by Pure-FTPd instantiation",
"additionalProperties": false,
"properties": {
"url": {
"description": "URL of the FTP service",
"pattern": "^ftp://",
"type": "string"
},
"username": {
"description": "Default username",
"type": "string",
"optional": true
},
"password": {
"description": "Password for default username",
"type": "string",
"optional": true
},
"videos": {
"description": "Location of the videos",
"type": "string",
"optional": true
}
},
"type": "object"
}
[buildout]
extends =
{{ monitor_rendered }}
parts =
promises
publish-connection-parameter
monitor-base
eggs-directory = {{ buildout['eggs-directory'] }}
develop-eggs-directory = {{ buildout['develop-eggs-directory'] }}
[slap-configuration]
recipe = slapos.cookbook:slapconfiguration
computer = ${slap-connection:computer-id}
partition = ${slap-connection:partition-id}
url = ${slap-connection:server-url}
key = ${slap-connection:key-file}
cert = ${slap-connection:cert-file}
configuration.port = 8021
[directory]
recipe = slapos.cookbook:mkdirectory
home = ${buildout:directory}
etc = ${:home}/etc
var = ${:home}/var
run = ${:var}/run
log = ${:var}/log
srv = ${:home}/srv
service = ${:etc}/service
promise = ${:etc}/promise
plugin = ${:etc}/plugin
pureftpd-dir = ${:srv}/pureftpd/
[check-port-listening-promise]
recipe = slapos.cookbook:promise.plugin
eggs =
slapos.toolbox
output = ${directory:plugin}/${:_buildout_section_name_}
content =
from slapos.promise.plugin.check_port_listening import RunPromise
[pureftpd-listen-promise]
<= check-port-listening-promise
config-hostname = ${pureftpd:ipv6}
config-port = ${pureftpd:ftp-port}
[pureftpd-userinfo]
recipe = slapos.cookbook:userinfo
[pureftpd-password]
recipe = slapos.cookbook:generate.password
username = nexedi_cdn
bytes = 12
[pureftpd]
ipv6 = ${slap-configuration:ipv6-random}
ipv4 = ${slap-configuration:ipv4-random}
host = ${:ipv6}
ftp-port = ${slap-configuration:configuration.port}
url = ftp://[${:host}]:${:ftp-port}
data-dir = ${directory:pureftpd-dir}
pid-file=${directory:run}/pureftpd.pid
auth-user-file=${auth-user-file:output}
recipe =slapos.recipe.template:jinja2
# WARNING pure-uploadscript must be launched AFTER pure-ftpd so keep them in the same wrapper
# and make sure they are both killed if one of them is killed.
template = inline:
#!{{ bash_location }}/bin/bash
{{ pureftpd_bin }} --uploadscript --customerproof --bind ${:host},${:ftp-port} --login puredb:${:auth-user-file} --pidfile ${:pid-file} &
while ! [ -p ${directory:run}/pure-ftpd.upload.pipe ]
do
sleep 1
done
{{ pureuploadscript_bin }} -r /opt/pureftpd/upload_script &
wait -n
kill 0
rendered = ${directory:service}/pureftpd
wrapper-path = ${:rendered}
[pure-pw]
# command line to add a user, invoke with:
# pure-pw useradd bob
# it will prompt for password twice
recipe = slapos.cookbook:wrapper
wrapper-path =${buildout:bin-directory}/${:_buildout_section_name_}
command-line =
{{ purepw_bin }} useradd ${pureftpd-password:username} -d ${pureftpd:data-dir} -u ${pureftpd-userinfo:pw-uid} -g ${pureftpd-userinfo:gr-gid} -f ${auth-user-file:passwd-file} "$@"
[auth-user-file]
recipe = plone.recipe.command
passwd-file = ${directory:etc}/pureftpd.passwd
output = ${directory:etc}/pureftpd.pdb
command =
if [ -f ${:passwd-file} ] && {{ purepw_bin }} show ${pureftpd-password:username} -f ${:passwd-file}
then
( echo ${pureftpd-password:passwd} ; echo ${pureftpd-password:passwd}) | {{ purepw_bin }} passwd ${pureftpd-password:username} -f ${:passwd-file}
else
( echo ${pureftpd-password:passwd} ; echo ${pureftpd-password:passwd}) | ${pure-pw:wrapper-path}
fi
{{ purepw_bin }} mkdb ${:output} -f ${:passwd-file}
update-command = ${:command}
[promises]
recipe =
instance-promises =
${pureftpd-listen-promise:output}
[publish-connection-parameter]
recipe = slapos.cookbook:publish
<= monitor-publish
url = ${pureftpd:url}
username = ${pureftpd-password:username}
password = ${pureftpd-password:passwd}
videos = To see the videos, go to http://nexedi-cdndemo-cdn-p.hexaglobe.net/ and enter the name "${pureftpd-userinfo:pw-name}-[video_name_without_extension]"
[buildout]
extends =
../../stack/slapos.cfg
../../component/pure-ftpd/buildout.cfg
../../component/bash/buildout.cfg
buildout.hash.cfg
../../stack/monitor/buildout.cfg
parts =
slapos-cookbook
instance-profile
# force to install plone.recipe.command and slapos.toolbox as it will be used during instanciation
[slapos-cookbook]
eggs +=
plone.recipe.command
slapos.toolbox
[instance-profile]
recipe = slapos.recipe.template:jinja2
template = ${:_profile_base_location_}/${:filename}
rendered = ${buildout:directory}/instance.cfg
mode = 0644
extensions = jinja2.ext.do
context =
section buildout buildout
key bash_location bash:location
raw monitor_rendered ${monitor-template:rendered}
raw pureftpd_bin ${pure-ftpd:location}/sbin/pure-ftpd
raw pureuploadscript_bin ${pure-ftpd:location}/sbin/pure-uploadscript
raw purepw_bin ${pure-ftpd:location}/bin/pure-pw
[versions]
slapos.recipe.template = 4.3
{
"name": "Pure-FTPd",
"description": "Pure-FTPd as a FTP server with virtual users and uploadscript",
"serialisation": "json-in-xml",
"software-type": {
"default": {
"title": "Default",
"description": "Pure-FTPd, with a default user",
"request": "instance-input-schema.json",
"response": "instance-output-schema.json",
"index": 0
}
}
}
......@@ -46,7 +46,7 @@ md5sum = d21472f0e58f928fb827f2cbf22c4d4a
[resilient-web-takeover-cgi-script-download]
filename = resilient-web-takeover-cgi-script.py.in
md5sum = 9d258d41eeef66f44f361adaa15cbd71
md5sum = 60d4912fdf5e8dafaba9d9f333aa9e36
[template-wrapper]
filename = templates/wrapper.in
......
......@@ -42,7 +42,7 @@ def getLatestBackupDate():
if not db.keys():
result = False
else:
last_backup = db[db.keys()[0]]
last_backup = db[db.keys()[-1]]
for callback in db.keys():
timestamp = float(db[callback])
if timestamp < last_backup:
......
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