Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
103
Merge Requests
103
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos
Commits
f3b158f9
Commit
f3b158f9
authored
Sep 28, 2023
by
Thomas Gambier
🚴🏼
Browse files
Options
Browse Files
Download
Plain Diff
Update Release Candidate
parents
fe0bc124
2ffda605
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
111 additions
and
58 deletions
+111
-58
component/egg-patch/Zope/0001-WSGIPublisher-set-REMOTE_USER-even-in-case-of-error-.patch
...SGIPublisher-set-REMOTE_USER-even-in-case-of-error-.patch
+64
-0
component/gdal/buildout.cfg
component/gdal/buildout.cfg
+2
-3
component/imagemagick/buildout.cfg
component/imagemagick/buildout.cfg
+2
-3
component/leptonica/buildout.cfg
component/leptonica/buildout.cfg
+5
-3
component/pillow/buildout.cfg
component/pillow/buildout.cfg
+0
-4
component/webp/buildout.cfg
component/webp/buildout.cfg
+3
-2
software/ors-amarisoft/buildout.hash.cfg
software/ors-amarisoft/buildout.hash.cfg
+1
-1
software/ors-amarisoft/config/gnb.jinja2.cfg
software/ors-amarisoft/config/gnb.jinja2.cfg
+1
-1
software/ors-amarisoft/instance-gnb-input-schema.json.jinja2
software/ors-amarisoft/instance-gnb-input-schema.json.jinja2
+1
-1
software/ors-amarisoft/instance-tdd-gnb-input-schema.json
software/ors-amarisoft/instance-tdd-gnb-input-schema.json
+1
-1
software/ors-amarisoft/instance-tdd-m2ru-gnb-input-schema.json
...are/ors-amarisoft/instance-tdd-m2ru-gnb-input-schema.json
+1
-1
software/ors-amarisoft/instance-tdd-ors-gnb-input-schema.json
...ware/ors-amarisoft/instance-tdd-ors-gnb-input-schema.json
+1
-1
software/ors-amarisoft/slapos-render-config.py
software/ors-amarisoft/slapos-render-config.py
+12
-30
stack/erp5/buildout.cfg
stack/erp5/buildout.cfg
+6
-2
stack/erp5/zope-versions.cfg
stack/erp5/zope-versions.cfg
+10
-4
stack/slapos.cfg
stack/slapos.cfg
+1
-1
No files found.
component/egg-patch/Zope/0001-WSGIPublisher-set-REMOTE_USER-even-in-case-of-error-.patch
0 → 100644
View file @
f3b158f9
From 1f0be881320f440cec05eb838fa42c5ddf56a57c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Tue, 19 Sep 2023 15:19:51 +0900
Subject: [PATCH] WSGIPublisher: set REMOTE_USER even in case of error (#1156)
This fixes a problem that user name was empty in access log for error pages.
Fixes #1155
---------
Co-authored-by: Michael Howitz <icemac@gmx.net>
---
src/ZPublisher/WSGIPublisher.py | 13 +++++++------
src/ZPublisher/tests/test_WSGIPublisher.py | 9 +++++++++
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/ZPublisher/WSGIPublisher.py b/src/ZPublisher/WSGIPublisher.py
index bd0ae1d17..09b2c44c9 100644
--- a/src/ZPublisher/WSGIPublisher.py
+++ b/src/ZPublisher/WSGIPublisher.py
@@ -382,12 +382,13 @@
def publish_module(environ, start_response,
try:
with load_app(module_info) as new_mod_info:
with transaction_pubevents(request, response):
- response = _publish(request, new_mod_info)
-
- user = getSecurityManager().getUser()
- if user is not None and \
- user.getUserName() != 'Anonymous User':
- environ['REMOTE_USER'] = user.getUserName()
+ try:
+ response = _publish(request, new_mod_info)
+ finally:
+ user = getSecurityManager().getUser()
+ if user is not None and \
+ user.getUserName() != 'Anonymous User':
+ environ['REMOTE_USER'] = user.getUserName()
break
except TransientError:
if request.supports_retry():
diff --git a/src/ZPublisher/tests/test_WSGIPublisher.py b/src/ZPublisher/tests/test_WSGIPublisher.py
index 989970f24..38e402ab3 100644
--- a/src/ZPublisher/tests/test_WSGIPublisher.py
+++ b/src/ZPublisher/tests/test_WSGIPublisher.py
@@ -822,6 +822,15 @@
class TestPublishModule(ZopeTestCase):
self._callFUT(environ, start_response, _publish)
self.assertFalse('REMOTE_USER' in environ)
+ def test_set_REMOTE_USER_environ_error(self):
+ environ = self._makeEnviron()
+ start_response = DummyCallable()
+ _publish = DummyCallable()
+ _publish._raise = ValueError()
+ with self.assertRaises(ValueError):
+ self._callFUT(environ, start_response, _publish)
+ self.assertEqual(environ['REMOTE_USER'], user_name)
+
def test_webdav_source_port(self):
from ZPublisher import WSGIPublisher
old_webdav_source_port = WSGIPublisher._WEBDAV_SOURCE_PORT
--
2.39.2
component/gdal/buildout.cfg
View file @
f3b158f9
...
...
@@ -9,7 +9,6 @@ extends =
../pcre/buildout.cfg
../proj4/buildout.cfg
../sqlite3/buildout.cfg
../webp/buildout.cfg
../xz-utils/buildout.cfg
parts =
...
...
@@ -32,12 +31,12 @@ configure-options =
--with-png=${libpng:location}
--with-static-proj4=${proj4:location}
--with-sqlite3=${sqlite3:location}
--with-webp=${webp:location}
--with-xml2=${libxml2:location}/bin/xml2-config
--without-webp
environment =
PATH=${xz-utils:location}/bin:%(PATH)s
CPPFLAGS=-I${pcre:location}/include
LDFLAGS=-L${pcre:location}/lib -Wl,-rpath=${buildout:parts-directory}/${:_buildout_section_name_}/lib -Wl,-rpath=${curl:location}/lib -Wl,-rpath=${geos:location}/lib -Wl,-rpath=${giflib:location}/lib -Wl,-rpath=${jasper:location}/lib -Wl,-rpath=${jbigkit:location}/lib -Wl,-rpath=${libexpat:location}/lib -Wl,-rpath=${libjpeg:location}/lib -Wl,-rpath=${libpng:location}/lib -Wl,-rpath=${libtiff:location}/lib -Wl,-rpath=${libxml2:location}/lib -Wl,-rpath=${openssl:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${sqlite3:location}/lib -Wl,-rpath=${
webp:location}/lib -Wl,-rpath=${
zlib:location}/lib
LDFLAGS=-L${pcre:location}/lib -Wl,-rpath=${buildout:parts-directory}/${:_buildout_section_name_}/lib -Wl,-rpath=${curl:location}/lib -Wl,-rpath=${geos:location}/lib -Wl,-rpath=${giflib:location}/lib -Wl,-rpath=${jasper:location}/lib -Wl,-rpath=${jbigkit:location}/lib -Wl,-rpath=${libexpat:location}/lib -Wl,-rpath=${libjpeg:location}/lib -Wl,-rpath=${libpng:location}/lib -Wl,-rpath=${libtiff:location}/lib -Wl,-rpath=${libxml2:location}/lib -Wl,-rpath=${openssl:location}/lib -Wl,-rpath=${pcre:location}/lib -Wl,-rpath=${sqlite3:location}/lib -Wl,-rpath=${zlib:location}/lib
[gdal-python]
recipe = zc.recipe.egg:custom
...
...
component/imagemagick/buildout.cfg
View file @
f3b158f9
...
...
@@ -19,7 +19,6 @@ extends =
../jbigkit/buildout.cfg
../patch/buildout.cfg
../pkgconfig/buildout.cfg
../webp/buildout.cfg
../xz-utils/buildout.cfg
../zlib/buildout.cfg
...
...
@@ -63,5 +62,5 @@ patches =
environment =
PATH=${freetype:location}/bin:${ghostscript:location}/bin:${inkscape:location}/bin:${libxml2:location}/bin:${patch:location}/bin:${pkgconfig:location}/bin:${xz-utils:location}/bin:%(PATH)s
PKG_CONFIG_PATH=${:pkg_config_depends}
CPPFLAGS=-I${bzip2:location}/include -I${zlib:location}/include -I${jbigkit:location}/include -I${libjpeg:location}/include -I${libtiff:location}/include -I${libtool:location}/include -I${libpng:location}/include -I${jasper:location}/include -I${freetype:location}/include
-I${webp:location}/include
LDFLAGS=-L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${jbigkit:location}/lib -Wl,-rpath=${jbigkit:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${libtool:location}/lib -Wl,-rpath=${libtool:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${jasper:location}/lib -Wl,-rpath=${jasper:location}/lib -L${freetype:location}/lib -Wl,-rpath=${freetype:location}/lib
-L${webp:location}/lib -Wl,-rpath=${webp:location}/lib
CPPFLAGS=-I${bzip2:location}/include -I${zlib:location}/include -I${jbigkit:location}/include -I${libjpeg:location}/include -I${libtiff:location}/include -I${libtool:location}/include -I${libpng:location}/include -I${jasper:location}/include -I${freetype:location}/include
LDFLAGS=-L${bzip2:location}/lib -Wl,-rpath=${bzip2:location}/lib -L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${jbigkit:location}/lib -Wl,-rpath=${jbigkit:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${libtool:location}/lib -Wl,-rpath=${libtool:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${jasper:location}/lib -Wl,-rpath=${jasper:location}/lib -L${freetype:location}/lib -Wl,-rpath=${freetype:location}/lib
component/leptonica/buildout.cfg
View file @
f3b158f9
...
...
@@ -5,7 +5,6 @@ extends =
../libjpeg/buildout.cfg
../libpng/buildout.cfg
../libtiff/buildout.cfg
../webp/buildout.cfg
../giflib/buildout.cfg
[leptonica]
...
...
@@ -15,6 +14,9 @@ url = http://www.leptonica.org/source/leptonica-1.80.0.tar.gz
md5sum = d640d684234442a84c9e8902f0b3ff36
configure-options =
--disable-static
--without-libwebp
--without-libwebpmux
--without-libopenjpeg
environment =
CPPFLAGS=-I${zlib:location}/include -I${libjpeg:location}/include -I${libpng:location}/include -I${libtiff:location}/include -I${
webp:location}/include -I${
giflib:location}/include
LDFLAGS=-L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${
webp:location}/lib -Wl,-rpath=${webp:location}/lib -L${
giflib:location}/lib -Wl,-rpath=${giflib:location}/lib
CPPFLAGS=-I${zlib:location}/include -I${libjpeg:location}/include -I${libpng:location}/include -I${libtiff:location}/include -I${giflib:location}/include
LDFLAGS=-L${zlib:location}/lib -Wl,-rpath=${zlib:location}/lib -L${libjpeg:location}/lib -Wl,-rpath=${libjpeg:location}/lib -L${libpng:location}/lib -Wl,-rpath=${libpng:location}/lib -L${libtiff:location}/lib -Wl,-rpath=${libtiff:location}/lib -L${giflib:location}/lib -Wl,-rpath=${giflib:location}/lib
component/pillow/buildout.cfg
View file @
f3b158f9
...
...
@@ -5,7 +5,6 @@ extends =
../lcms/buildout.cfg
../libjpeg/buildout.cfg
../libtiff/buildout.cfg
../webp/buildout.cfg
../zlib/buildout.cfg
parts =
...
...
@@ -20,7 +19,6 @@ include-dirs =
${lcms2:location}/include
${libjpeg:location}/include
${libtiff:location}/include
${webp:location}/include
${zlib:location}/include
library-dirs =
${freetype:location}/lib
...
...
@@ -28,7 +26,6 @@ library-dirs =
${lcms2:location}/lib
${libjpeg:location}/lib
${libtiff:location}/lib
${webp:location}/lib
${zlib:location}/lib
rpath =
${freetype:location}/lib
...
...
@@ -36,5 +33,4 @@ rpath =
${lcms2:location}/lib
${libjpeg:location}/lib
${libtiff:location}/lib
${webp:location}/lib
${zlib:location}/lib
component/webp/buildout.cfg
View file @
f3b158f9
...
...
@@ -13,11 +13,12 @@ extends =
[webp]
recipe = slapos.recipe.cmmi
shared = true
url = http://downloads.webmproject.org/releases/webp/libwebp-
0.4.1
.tar.gz
md5sum =
42bc79613ec5ee5b0e68ba97839c981e
url = http://downloads.webmproject.org/releases/webp/libwebp-
1.3.2
.tar.gz
md5sum =
34869086761c0e2da6361035f7b64771
configure-options =
--disable-static
--disable-gl
--disable-sdl
--disable-wic
--enable-everything
--with-jpegincludedir=${libjpeg:location}/include
...
...
software/ors-amarisoft/buildout.hash.cfg
View file @
f3b158f9
...
...
@@ -84,7 +84,7 @@ md5sum = a1973ba6e43d40e510d61d461c2d13ac
[gnb.jinja2.cfg]
filename = config/gnb.jinja2.cfg
md5sum = 2f
7b70b6225ca94feaf1ba512643b0d1
md5sum = 2f
db4812960bec30118e61e61554652b
[ltelogs.jinja2.sh]
filename = ltelogs.jinja2.sh
...
...
software/ors-amarisoft/config/gnb.jinja2.cfg
View file @
f3b158f9
...
...
@@ -2,7 +2,7 @@
{%- set tdd_config = 1 %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '2.5ms 1UL 3DL 2/10' %}
{%- set tdd_config = 2 %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '5ms 8UL
3
DL 2/10 (maximum uplink)' %}
{%- elif slapparameter_dict.get('tdd_ul_dl_config', '5ms 2UL 7DL 4/6 (default)') == '5ms 8UL
1
DL 2/10 (maximum uplink)' %}
{%- set tdd_config = 3 %}
{%- endif %}
...
...
software/ors-amarisoft/instance-gnb-input-schema.json.jinja2
View file @
f3b158f9
...
...
@@ -37,7 +37,7 @@
"enum": [
"5ms 2UL 7DL 4/6 (default)",
"2.5ms 1UL 3DL 2/10",
"5ms 8UL
3
DL 2/10 (maximum uplink)"
"5ms 8UL
1
DL 2/10 (maximum uplink)"
],
"default": "5ms 2UL 7DL 4/6 (default)"
},
...
...
software/ors-amarisoft/instance-tdd-gnb-input-schema.json
View file @
f3b158f9
...
...
@@ -28,7 +28,7 @@
"enum"
:
[
"5ms 2UL 7DL 4/6 (default)"
,
"2.5ms 1UL 3DL 2/10"
,
"5ms 8UL
3
DL 2/10 (maximum uplink)"
"5ms 8UL
1
DL 2/10 (maximum uplink)"
],
"default"
:
"5ms 2UL 7DL 4/6 (default)"
},
...
...
software/ors-amarisoft/instance-tdd-m2ru-gnb-input-schema.json
View file @
f3b158f9
...
...
@@ -28,7 +28,7 @@
"enum"
:
[
"5ms 2UL 7DL 4/6 (default)"
,
"2.5ms 1UL 3DL 2/10"
,
"5ms 8UL
3
DL 2/10 (maximum uplink)"
"5ms 8UL
1
DL 2/10 (maximum uplink)"
],
"default"
:
"5ms 2UL 7DL 4/6 (default)"
},
...
...
software/ors-amarisoft/instance-tdd-ors-gnb-input-schema.json
View file @
f3b158f9
...
...
@@ -28,7 +28,7 @@
"enum"
:
[
"5ms 2UL 7DL 4/6 (default)"
,
"2.5ms 1UL 3DL 2/10"
,
"5ms 8UL
3
DL 2/10 (maximum uplink)"
"5ms 8UL
1
DL 2/10 (maximum uplink)"
],
"default"
:
"5ms 2UL 7DL 4/6 (default)"
},
...
...
software/ors-amarisoft/slapos-render-config.py
View file @
f3b158f9
config
=
"
e
nb"
config
=
"
g
nb"
json_params_empty
=
"""{
"rf_mode": 'fdd',
"slap_configuration": {
...
...
@@ -9,11 +9,17 @@ json_params_empty = """{
}
}"""
json_params
=
"""{
"earfcn": 126357,
"tx_gain": 50,
"rx_gain": 50,
"rf_mode": "tdd",
"trx": "sdr",
"bbu": "ors",
"ru": "ors",
"one_watt": "True",
"earfcn": 646666,
"nr_arfcn": 646666,
"nr_band": 43,
"tx_gain": 62,
"rx_gain": 43,
"sib23_file": "sib",
"rf_mode": "fdd",
"slap_configuration": {
"tap-name": "slaptap9",
"configuration.default_lte_bandwidth": "10 MHz",
...
...
@@ -34,31 +40,7 @@ json_params = """{
"var": "var"
},
"slapparameter_dict": {
"rrh": "Lopcomm ORAN",
"sdr_number": 3,
"cpri_mult": 8,
"cell_list": {
"RRH2": {
"cpri_rx_delay": 10,
"cpri_tx_delay": 10,
"cpri_tx_dbm": 50,
"dl_earfcn": 100000,
"pci": 4,
"cell_id": "0x04",
"cpri_port_number": 0
},
"RRH1": {
"cpri_rx_delay": 15.4,
"cpri_tx_delay": 15.1,
"cpri_tx_dbm": 20,
"dl_earfcn": 546115,
"pci": 3,
"cell_id": "0x03",
"cpri_port_number": 1
},
"RRH3": {
}
}
"tdd_ul_dl_config": "5ms 8UL 1DL 2/10 (maximum uplink)"
}
}"""
import
os
...
...
stack/erp5/buildout.cfg
View file @
f3b158f9
...
...
@@ -2,7 +2,7 @@
extends =
# versions pins from zope, vendored with:
# curl https://zopefoundation.github.io/Zope/releases/4.8.
8
/versions-prod.cfg > zope-versions.cfg
# curl https://zopefoundation.github.io/Zope/releases/4.8.
9
/versions-prod.cfg > zope-versions.cfg
# When updating, keep in mind that some versions are defined in other places,
# for example component/ZEO , component/ZODB and stack/slapos
zope-versions.cfg
...
...
@@ -709,6 +709,9 @@ waitress-patches =
${:_profile_base_location_}/../../component/egg-patch/waitress/CVE-2022-24761-5.patch#ad2765822397cd1e28e02a68a52d7768
${:_profile_base_location_}/../../component/egg-patch/waitress/CVE-2022-24761-6.patch#85fc9c4105eabee3ff71c800b2ddf63b
waitress-patch-options = -p1
Zope-patches =
${:_profile_base_location_}/../../component/egg-patch/Zope/0001-WSGIPublisher-set-REMOTE_USER-even-in-case-of-error-.patch#a437f4da28975f94dd07db0b02954111
Zope-patch-options = -p1
# neoppod installs bin/coverage so we inject erp5 plugin here so that coverage script can use it in report
[neoppod]
...
...
@@ -743,11 +746,12 @@ depends =
Acquisition = 4.7+SlapOSPatched001
Products.DCWorkflow = 2.4.1+SlapOSPatched001
ocropy = 1.0+SlapOSPatched001
PyPDF2 = 1.26.0+SlapOSPatched001
pysvn = 1.9.15+SlapOSPatched001
python-ldap = 2.4.32+SlapOSPatched001
python-magic = 0.4.12+SlapOSPatched001
PyPDF2 = 1.26.0+SlapOSPatched001
waitress = 1.4.4+SlapOSPatched006
Zope = 4.8.9+SlapOSPatched001
## https://lab.nexedi.com/nexedi/slapos/merge_requests/648
pylint = 1.4.4+SlapOSPatched002
# astroid 1.4.1 breaks testDynamicClassGeneration
...
...
stack/erp5/zope-versions.cfg
View file @
f3b158f9
...
...
@@ -2,10 +2,10 @@
# Version pins for required and commonly used dependencies.
[versions]
Zope = 4.8.
8
Zope = 4.8.
9
Zope2 = 4.0
# AccessControl 5+ no longer supports Zope 4.
AccessControl = 4.
3
AccessControl = 4.
4
Acquisition = 4.13
AuthEncoding = 4.3
BTrees = 4.11.3
...
...
@@ -23,7 +23,7 @@ Products.BTreeFolder2 = 4.4
Products.ZCatalog = 5.4
Record = 3.6
# RestrictedPython >= 6 no longer supports Zope 4
RestrictedPython = 5.
2
RestrictedPython = 5.
4
WSGIProxy2 = 0.5.1
WebOb = 1.8.7
WebTest = 3.0.0
...
...
@@ -59,7 +59,7 @@ zope.cachedescriptors = 4.4
zope.component = 5.0.1
zope.componentvocabulary = 2.3.0
zope.configuration = 4.4.1
zope.container =
4.10
zope.container =
5.1
zope.contentprovider = 4.2.1
zope.contenttype = 4.6
zope.datetime = 4.3.0
...
...
@@ -119,6 +119,8 @@ multipart = 0.1.1
waitress = 1.4.4
# zope.dottedname >= 5 requires Python 3.6 or higher
zope.dottedname = 4.3
# zope.container 5.x requires Python 3.7 or higher
zope.container = 4.10
[versions:python35]
# DocumentTemplate 4+ cannot be installed on Zope 4 for Python 3.5
...
...
@@ -135,6 +137,8 @@ mock = 3.0.5
waitress = 1.4.4
# zope.dottedname >= 5 requires Python 3.6 or higher
zope.dottedname = 4.3
# zope.container 5.x requires Python 3.7 or higher
zope.container = 4.10
[versions:python36]
# PasteDeploy >3 requires Python 3.7
...
...
@@ -143,3 +147,5 @@ PasteDeploy = 2.1.1
WSGIProxy2 = 0.4.6
# waitress 2.1 requires Python 3.7 or higher
waitress = 2.0.0
# zope.container 5.x requires Python 3.7 or higher
zope.container = 4.10
stack/slapos.cfg
View file @
f3b158f9
...
...
@@ -297,7 +297,7 @@ simplegeneric = 0.8.1
singledispatch = 3.4.0.3
six = 1.16.0
slapos.cookbook = 1.0.329
slapos.core = 1.10.
2
slapos.core = 1.10.
3
slapos.extension.shared = 1.0
slapos.libnetworkcache = 0.25
slapos.rebootstrap = 4.5
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment