Commit 11f5304f authored by Rafael Monnerat's avatar Rafael Monnerat

Update Release Candidate

parents d2f27c8e 3fc96ff5
......@@ -18,8 +18,8 @@ parts =
[git]
recipe = slapos.recipe.cmmi
shared = true
url = https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.39.2.tar.xz
md5sum = 32d34dc65ae0955cc68c7152b5ca8b13
url = https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.40.1.tar.xz
md5sum = 125d13c374a9ec9253f42c483bacec31
configure-options =
--with-curl=${curl:location}
--with-openssl=${openssl:location}
......
......@@ -3,22 +3,14 @@ parts =
[macro.pythonpath.eggs]
recipe = slapos.recipe.build
_name_ = ${:_buildout_section_name_}
init =
prerequisite = """
[.%(_name_)s.prerequisite]
recipe = slapos.recipe.build
init =
section = self.buildout['%(_name_)s']
self.eggs = [e.strip() for e in section['eggs'].splitlines() if e.strip()]
update =
from zc.buildout.easy_install import working_set
buildout = self.buildout['buildout']
eggs_directory = buildout['eggs-directory']
develop_eggs_directory = buildout['develop-eggs-directory']
dists = working_set(self.eggs, [develop_eggs_directory, eggs_directory])
paths = ':'.join(dist.location for dist in dists)
self.buildout['%(environment)s']['PYTHONPATH'] = paths
print("PYTHONPATH=" + paths)
""" % options
self.buildout.parse(prerequisite)
self.eggs = [e.strip() for e in options['eggs'].splitlines() if e.strip()]
update =
from zc.buildout.easy_install import working_set
buildout = self.buildout['buildout']
eggs_directory = buildout['eggs-directory']
develop_eggs_directory = buildout['develop-eggs-directory']
dists = working_set(self.eggs, [develop_eggs_directory, eggs_directory])
paths = ':'.join(dist.location for dist in dists)
self.buildout[options['environment']]['PYTHONPATH'] = paths
print("PYTHONPATH=" + paths)
......@@ -15,4 +15,4 @@
[instance.cfg.in]
filename = instance.cfg.in
md5sum = 0cb3cbac5479581985e5446078217686
md5sum = 9ed5d03f4f0cdc022f28b39e8ff1323e
......@@ -143,8 +143,9 @@ command-line =
--bind ${:ip}
--port ${:port}
--allow-all
--auth /@${admin-password:user}:${admin-password:passwd}
--auth /pub@${admin-password:user}:${admin-password:passwd}@*
--auth-method basic
--auth ${admin-password:user}:${admin-password:passwd}@/:rw
--auth @/pub
--tls-cert ${dufs-certificate:cert-file}
--tls-key ${dufs-certificate:key-file}
${directory:dufs-data-dir}
......
......@@ -14,8 +14,8 @@ parts =
[dufs]
recipe = slapos.recipe.cmmi
shared = true
url = https://github.com/sigoden/dufs/archive/refs/tags/v0.31.0.tar.gz
md5sum = 4340e59915605e30dcdb70aa9eb06acb
url = https://github.com/sigoden/dufs/archive/refs/tags/v0.34.1.tar.gz
md5sum = 77cbb2523aca8dad90fd77ee0277704f
configure-command = :
make-binary = cargo install --root=%(location)s --path .
make-targets =
......
......@@ -67,38 +67,50 @@ class TestFileServer(SlapOSInstanceTestCase):
)
self.assertEqual(resp.status_code, requests.codes.ok)
resp = requests.get(
urllib.parse.urljoin(self.connection_parameters['public-url'], '..'),
verify=self.ca_cert,
)
self.assertEqual(resp.status_code, requests.codes.unauthorized)
with open(os.path.join(self.computer_partition_root_path, 'srv', 'www', 'secret.txt'), 'w'):
resp = requests.get(
urllib.parse.urljoin(self.connection_parameters['public-url'], '../secret.txt'),
verify=self.ca_cert,
)
self.assertEqual(resp.status_code, requests.codes.unauthorized)
resp = requests.get(
urllib.parse.urljoin(self.connection_parameters['public-url'], '../not-exist.txt'),
verify=self.ca_cert,
)
self.assertEqual(resp.status_code, requests.codes.unauthorized)
def test_upload_file_refused_without_digest_auth(self):
# index is allowed on / but it only shows /pub/
resp = requests.get(
urllib.parse.urljoin(self.connection_parameters['public-url'], '..'),
verify=self.ca_cert,
)
self.assertIn('pub', resp.text)
self.assertNotIn('secret', resp.text)
self.assertEqual(resp.status_code, requests.codes.ok)
def test_upload_file_refused_without_auth(self):
parsed_upload_url = urllib.parse.urlparse(self.connection_parameters['upload-url'])
# upload-url has username:password, remove it
self.assertTrue(parsed_upload_url.password)
upload_url = parsed_upload_url._replace(
netloc=f'[{parsed_upload_url.hostname}]:{parsed_upload_url.port}').geturl()
resp = requests.put(
urllib.parse.urljoin(self.connection_parameters['upload-url'], 'hello.txt'),
urllib.parse.urljoin(upload_url, 'hello.txt'),
data=io.BytesIO(b'hello'),
verify=self.ca_cert,
)
self.assertEqual(resp.status_code, requests.codes.unauthorized)
def test_upload_file(self):
parsed_url = urllib.parse.urlparse(self.connection_parameters['upload-url'])
auth = requests.auth.HTTPDigestAuth(
parsed_url.username,
parsed_url.password,
)
resp = requests.put(
urllib.parse.urljoin(self.connection_parameters['upload-url'], 'hello.txt'),
data=io.BytesIO(b'hello'),
auth=auth,
verify=self.ca_cert,
)
self.assertEqual(resp.status_code, requests.codes.created)
resp = requests.get(
urllib.parse.urljoin(self.connection_parameters['upload-url'], 'hello.txt'),
auth=auth,
verify=self.ca_cert,
)
self.assertEqual(resp.text, 'hello')
......
......@@ -32,6 +32,7 @@ import os
import requests
import sqlite3
import subprocess
import tempfile
from slapos.proxy.db_version import DB_VERSION
from slapos.testing.testcase import makeModuleSetUpAndTestCaseClass
......@@ -271,65 +272,75 @@ class TestJupyterCustomAdditional(SelectMixin, InstanceTestCase):
r.destroyed()
class TestIPython(InstanceTestCase):
converted_notebook = 'test.nbconvert.ipynb'
notebook_filename = 'test.ipynb'
test_sentence = 'test'
class IPythonNotebook(object):
def __init__(self, name, binary):
self.tempdir = tempdir = tempfile.TemporaryDirectory()
path = os.path.join(tempdir.name, name)
self.path = path + '.ipynb'# input notebook
self.output_path = path + '.nbconvert.ipynb' # output notebook
self.binary = binary
def setUp(self):
super().setUp()
notebook_source = {
def write(self, code):
content = {
"cells": [
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"print('" + self.test_sentence + "')"
]
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": code.splitlines(keepends=True)
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}
with open(self.notebook_filename, 'w') as notebook:
notebook.write(json.dumps(notebook_source))
with open(self.path, 'w') as notebook:
notebook.write(json.dumps(content))
def tearDown(self):
os.remove(self.notebook_filename)
if os.path.exists(self.converted_notebook):
os.remove(self.converted_notebook)
super().tearDown()
def run(self):
return subprocess.check_output(
(self.binary,'--execute', '--to', 'notebook', self.path),
stderr=subprocess.STDOUT, text=True)
def test(self):
conversion_output = subprocess.check_output([
os.path.join(
self.computer_partition_root_path,
'software_release',
'bin',
'jupyter-nbconvert',
),
'--execute',
'--to',
'notebook',
self.notebook_filename,
], stderr=subprocess.STDOUT, text=True)
self.assertIn(
'[NbConvertApp] Converting notebook %s to notebook' % self.notebook_filename,
conversion_output,
)
self.assertRegex(
conversion_output,
r'\[NbConvertApp\] Writing \d+ bytes to %s' % self.converted_notebook
)
def readResult(self):
with open(self.output_path) as result:
return json.loads(result.read())['cells'][0]['outputs'][0]['text'][0]
self.assertTrue(os.path.exists(self.converted_notebook))
with open(self.converted_notebook) as json_result:
self.assertEqual(
json.loads(json_result.read())['cells'][0]['outputs'][0]['text'][0],
self.test_sentence + '\n',
def __enter__(self):
return self
def __exit__(self, *args):
if self.tempdir:
self.tempdir.cleanup()
del self.tempdir
class TestIPython(InstanceTestCase):
message = 'test_sys'
module = 'sys'
def test(self):
binary = os.path.join(
self.computer_partition_root_path,
'software_release', 'bin', 'jupyter-nbconvert')
with IPythonNotebook('test', binary) as notebook:
notebook.write("import %s\nprint(%r)" % (self.module, self.message))
out = notebook.run()
self.assertIn(
"[NbConvertApp] Converting notebook %s to notebook" % notebook.path,
out,
)
self.assertRegex(
out,
r"\[NbConvertApp\] Writing \d+ bytes to %s" % notebook.output_path
)
self.assertTrue(os.path.exists(notebook.output_path))
self.assertEqual(notebook.readResult(), self.message + '\n')
class TestIPythonNumpy(TestIPython):
message = 'test_numpy'
module = 'numpy'
......@@ -64,7 +64,7 @@ md5sum = dcaac06553a3222b14c0013a13f4a149
[enb.jinja2.cfg]
filename = config/enb.jinja2.cfg
md5sum = 90e0d38ff42dc0f65245496d3809f3b3
md5sum = e4b31e8ced0e2ffa08a877e59b8a9793
[sib23.asn]
filename = config/sib23.asn
......@@ -72,7 +72,7 @@ md5sum = b377dac7f1fcf94fb9ce9ebed617f36a
[gnb.jinja2.cfg]
filename = config/gnb.jinja2.cfg
md5sum = 96236b6e55be2fd3dcc128a19a5fc344
md5sum = 91648b9f70a10eb8a89465a88d3975aa
[ltelogs.jinja2.sh]
filename = ltelogs.jinja2.sh
......
......@@ -19,6 +19,7 @@
sync: "gps",
{% endif %}
rx_antenna: "tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ slapparameter_dict.get('tx_gain', slap_configuration['configuration.default_nr_tx_gain']) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', slap_configuration['configuration.default_nr_rx_gain']) }},
......
......@@ -28,9 +28,10 @@
name: "sdr",
args: "dev0=/dev/sdr0",
{% if slapparameter_dict.get('gps_sync', False) %}
sync: "gps",
sync: "gps",
{% endif %}
rx_antenna:"tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ slapparameter_dict.get('tx_gain', slap_configuration['configuration.default_lte_tx_gain']) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', slap_configuration['configuration.default_lte_rx_gain']) }},
......
......@@ -9,16 +9,17 @@
log_filename: "{{ directory['log'] }}/gnb.log",
com_addr: "0.0.0.0:9001",
rf_driver: {
name: "sdr",
name: "sdr",
#if N_ANTENNA_DL >= 4
args: "dev0=/dev/sdr0,dev1=/dev/sdr1",
args: "dev0=/dev/sdr0,dev1=/dev/sdr1",
#else
args: "dev0=/dev/sdr0",
args: "dev0=/dev/sdr0",
#endif
{% if slapparameter_dict.get('gps_sync', False) %}
sync: "gps",
sync: "gps",
{% endif %}
rx_antenna: "tx_rx",
rx_antenna: "tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ slapparameter_dict.get('tx_gain', slap_configuration['configuration.default_nr_tx_gain']) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', slap_configuration['configuration.default_nr_rx_gain']) }},
......
......@@ -26,12 +26,13 @@
rx_gain: 0,
{% else %}
rf_driver: {
name: "sdr",
args: "dev0=/dev/sdr0",
name: "sdr",
args: "dev0=/dev/sdr0",
{% if slapparameter_dict.get('gps_sync', False) %}
sync: "gps",
sync: "gps",
{% endif %}
rx_antenna: "tx_rx",
rx_antenna: "tx_rx",
tdd_tx_mod: 1,
},
tx_gain: {{ slapparameter_dict.get('tx_gain', slap_configuration['configuration.default_nr_tx_gain']) }},
rx_gain: {{ slapparameter_dict.get('rx_gain', slap_configuration['configuration.default_nr_rx_gain']) }},
......
......@@ -30,7 +30,7 @@ md5sum = 3006197ddce87bd92866b76b5ce8ce08
[profile-slave-list]
filename = instance-slave-list.cfg.in
md5sum = f6b3d4c6502cc0fa3a5021e436b4771b
md5sum = 8289620cb32dbdfcca6ba112c7ec7b2b
[profile-master-publish-slave-information]
filename = instance-master-publish-slave-information.cfg.in
......
......@@ -247,7 +247,7 @@ context =
{%- endif %}
{%- endif %}
{%- set websocket_path_list = [] %}
{%- for websocket_path in slave_instance.get('websocket-path-list', '').split() %}
{%- for websocket_path in ('' ~ (slave_instance.get('websocket-path-list', '')) or '').split() %}
{%- set websocket_path = websocket_path.strip('/') %}
{#- Unquote the path, so %20 and similar can be represented correctly #}
{%- set websocket_path = urllib_module.parse.unquote(websocket_path.strip()) %}
......
......@@ -1799,6 +1799,23 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin, AtsMixin):
'type': 'websocket',
'websocket-path-list': '////ws//// /with%20space/',
},
'type-websocket-websocket-path-list-none': {
'url': cls.backend_url,
'type': 'websocket',
# Note: With reference SlapOS Master requesting
# 'websocket-path-list': '' leads to a problem, as the value for
# the partition is None (type: None), but with slapproxy it is
# required to use None (type: None) in the **request** to lead
# to the same problem. See also
# type-websocket-websocket-path-list-empty
'websocket-path-list': None,
},
'type-websocket-websocket-path-list-empty': {
'url': cls.backend_url,
'type': 'websocket',
# Note: See also type-websocket-websocket-path-list-none
'websocket-path-list': '',
},
'type-websocket-websocket-transparent-false': {
'url': cls.backend_url,
'type': 'websocket',
......@@ -2084,9 +2101,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin, AtsMixin):
'monitor-base-url': 'https://[%s]:8401' % self._ipv6_address,
'backend-client-caucase-url': 'http://[%s]:8990' % self._ipv6_address,
'domain': 'example.com',
'accepted-slave-amount': '60',
'accepted-slave-amount': '62',
'rejected-slave-amount': '0',
'slave-amount': '60',
'slave-amount': '62',
'rejected-slave-dict': {
},
'warning-slave-dict': {
......@@ -3293,12 +3310,9 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin, AtsMixin):
self.assertTrue('x-real-ip' in j['Incoming Headers'])
self.assertHttp1(parameter_dict['domain'])
def test_type_websocket(self):
parameter_dict = self.assertSlaveBase(
'type-websocket')
def _test_type_websocket(self, parameter_dict, path='test-path'):
result = fakeHTTPSResult(
parameter_dict['domain'], 'test-path',
parameter_dict['domain'], path,
headers={'Connection': 'Upgrade'})
self.assertEqual(
......@@ -3308,7 +3322,7 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin, AtsMixin):
self.assertEqualResultJson(
result,
'Path',
'/test-path'
'/' + path
)
try:
j = result.json()
......@@ -3323,6 +3337,17 @@ class TestSlave(SlaveHttpFrontendTestCase, TestDataMixin, AtsMixin):
self.assertTrue('x-real-ip' in j['Incoming Headers'])
self.assertHttp1(parameter_dict['domain'])
def test_type_websocket(self):
self._test_type_websocket(self.assertSlaveBase('type-websocket'))
def test_type_websocket_websocket_path_list_none(self):
self._test_type_websocket(self.assertSlaveBase(
'type-websocket-websocket-path-list-none'), 'None')
def test_type_websocket_websocket_path_list_empty(self):
self._test_type_websocket(self.assertSlaveBase(
'type-websocket-websocket-path-list-empty'))
def test_type_websocket_websocket_transparent_false(self):
parameter_dict = self.assertSlaveBase(
'type-websocket-websocket-transparent-false')
......
......@@ -141,6 +141,12 @@ T-2/var/log/httpd/_type-redirect-custom_domain_access_log
T-2/var/log/httpd/_type-redirect-custom_domain_frontend_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_frontend_log
......
......@@ -141,6 +141,12 @@ T-2/var/log/httpd/_type-redirect-custom_domain_access_log
T-2/var/log/httpd/_type-redirect-custom_domain_frontend_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_frontend_log
......
......@@ -141,6 +141,12 @@ T-2/var/log/httpd/_type-redirect-custom_domain_access_log
T-2/var/log/httpd/_type-redirect-custom_domain_frontend_log
T-2/var/log/httpd/_type-redirect_access_log
T-2/var/log/httpd/_type-redirect_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-empty_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-none_frontend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_access_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_backend_log
T-2/var/log/httpd/_type-websocket-websocket-path-list-websocket-transparent-false_frontend_log
......
......@@ -168,13 +168,14 @@ Listen {{ ip }}:{{ port }}
# Custom block we use for now different parameters.
RequestHeader set Remote-User %{SSL_CLIENT_S_DN_CN}s
SSLCACertificateFile {{ parameter_dict['shared-ca-cert'] }}
SSLCARevocationCheck chain
SSLCARevocationPath {{ parameter_dict['shared-crl'] }}
LogFormat "%h %l %{REMOTE_USER}i %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined
LogFormat "%h %l %{Remote-User}i %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" service
# We would like to separate the the authentificated logs.
ErrorLog "{{ parameter_dict['log-dir'] }}/apache-service-error.log"
CustomLog "{{ parameter_dict['log-dir'] }}/apache-service-access.log" combined
CustomLog "{{ parameter_dict['log-dir'] }}/apache-service-access.log" service
{% endif -%}
RewriteRule ^/(.*) {{ backend }}/$1 [L,P]
</VirtualHost>
......
......@@ -22,7 +22,7 @@ md5sum = da8399562377b472c9488a337d0230dc
[template-apache-backend-conf]
filename = apache-backend.conf.in
md5sum = 9d7104ce18f79a7a84988efc11f5ed23
md5sum = 6cf13e8f5545d241e6514503f9824b02
[template-haproxy-cfg]
filename = haproxy.cfg.in
......
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