ci: parameterize / update settings (#7248)

* ci: parameterize gunicorn in datatracker-start.sh

* fix: typo

* ci: update settings_local for helm chart

* ci: Add todo comment

* ci: Drop redundant USE_TZ setting

* ci: Require secrets in production

* ci: fix indentation

* style: Black

* ci: memcached cfg from env in settings.py

* ci: set SITE_URL in settings.py

* refactor: /www/htpasswd -> /a/www/htpasswd

(it's a symlink on production)

* refactor: Remove obsolete SECR_ settings

* refactor: SECR_MAX_UPLOAD_SIZE -> DATATRACKER_...

* refactor: SECR_PPT2PDF_COMMAND -> PPT2PDF_COMMAND

* ci: Fix up helm/settings_local

* ci: Remove commented-out settings

* ci: Refactor/improve env var guards

* ci: More env refactoring / guards
This commit is contained in:
Jennifer Richards 2024-03-27 16:04:30 -03:00 committed by Nicolas Giard
parent e3d0290480
commit f58bbc3caa
7 changed files with 275 additions and 144 deletions

View file

@ -12,11 +12,11 @@ echo "Running collectstatic..."
echo "Starting Datatracker..."
gunicorn \
--workers 9 \
--max-requests 32768 \
--timeout 180 \
--workers ${DATATRACKER_GUNICORN_WORKERS:-9} \
--max-requests ${DATATRACKER_GUNICORN_MAX_REQUESTS:-32768} \
--timeout ${DATATRACKER_GUNICORN_TIMEOUT:-180} \
--bind :8000 \
--log-level info \
--log-level ${DATATRACKER_GUNICORN_LOG_LEVEL:-info} \
ietf.wsgi:application
# Leaving this here as a reminder to set up the env in the chart

View file

@ -1,22 +1,100 @@
# Copyright The IETF Trust 2007-2024, All Rights Reserved
# -*- coding: utf-8 -*-
from base64 import b64decode
from email.utils import parseaddr
from ietf import __release_hash__
from ietf.settings import * # pyflakes:ignore
ALLOWED_HOSTS = ['*']
# Default to "development". Production _must_ set DATATRACKER_SERVER_MODE="production" in the env!
SERVER_MODE = os.environ.get("DATATRACKER_SERVER_MODE", "development")
# Secrets
_SECRET_KEY = os.environ.get("DATATRACKER_DJANGO_SECRET_KEY", None)
if _SECRET_KEY is not None:
SECRET_KEY = _SECRET_KEY
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_DJANGO_SECRET_KEY must be set in production")
_NOMCOM_APP_SECRET_B64 = os.environ.get("DATATRACKER_NOMCOM_APP_SECRET_B64", None)
if _NOMCOM_APP_SECRET_B64 is not None:
NOMCOM_APP_SECRET = b64decode(_NOMCOM_APP_SECRET_B64)
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_NOMCOM_APP_SECRET_B64 must be set in production")
_IANA_SYNC_PASSWORD = os.environ.get("DATATRACKER_IANA_SYNC_PASSWORD", None)
if _IANA_SYNC_PASSWORD is not None:
IANA_SYNC_PASSWORD = _IANA_SYNC_PASSWORD
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_IANA_SYNC_PASSWORD must be set in production")
_RFC_EDITOR_SYNC_PASSWORD = os.environ.get("DATATRACKER_RFC_EDITOR_SYNC_PASSWORD", None)
if _RFC_EDITOR_SYNC_PASSWORD is not None:
RFC_EDITOR_SYNC_PASSWORD = os.environ.get("DATATRACKER_RFC_EDITOR_SYNC_PASSWORD")
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_RFC_EDITOR_SYNC_PASSWORD must be set in production")
_YOUTUBE_API_KEY = os.environ.get("DATATRACKER_YOUTUBE_API_KEY", None)
if _YOUTUBE_API_KEY is not None:
YOUTUBE_API_KEY = _YOUTUBE_API_KEY
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_YOUTUBE_API_KEY must be set in production")
_GITHUB_BACKUP_API_KEY = os.environ.get("DATATRACKER_GITHUB_BACKUP_API_KEY", None)
if _GITHUB_BACKUP_API_KEY is not None:
GITHUB_BACKUP_API_KEY = _GITHUB_BACKUP_API_KEY
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_GITHUB_BACKUP_API_KEY must be set in production")
_API_KEY_TYPE = os.environ.get("DATATRACKER_API_KEY_TYPE", None)
if _API_KEY_TYPE is not None:
API_KEY_TYPE = _API_KEY_TYPE
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_API_KEY_TYPE must be set in production")
_API_PUBLIC_KEY_PEM_B64 = os.environ.get("DATATRACKER_API_PUBLIC_KEY_PEM_B64", None)
if _API_PUBLIC_KEY_PEM_B64 is not None:
API_PUBLIC_KEY_PEM = b64decode(_API_PUBLIC_KEY_PEM_B64)
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_API_PUBLIC_KEY_PEM_B64 must be set in production")
_API_PRIVATE_KEY_PEM_B64 = os.environ.get("DATATRACKER_API_PRIVATE_KEY_PEM_B64", None)
if _API_PRIVATE_KEY_PEM_B64 is not None:
API_PRIVATE_KEY_PEM = b64decode(_API_PRIVATE_KEY_PEM_B64)
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_API_PRIVATE_KEY_PEM_B64 must be set in production")
# Set DEBUG if DATATRACKER_DEBUG env var is the word "true"
DEBUG = os.environ.get("DATATRACKER_DEBUG", "false").lower() == "true"
# DATATRACKER_ALLOWED_HOSTS env var is a comma-separated list of allowed hosts
_allowed_hosts_str = os.environ.get("DATATRACKER_ALLOWED_HOSTS", None)
if _allowed_hosts_str is not None:
ALLOWED_HOSTS = [h.strip() for h in _allowed_hosts_str.split(",")]
DATABASES = {
"default": {
"HOST": os.environ.get("DBHOST", "db"),
"PORT": os.environ.get("DBPORT", "5432"),
"NAME": os.environ.get("DBNAME", "datatracker"),
"HOST": os.environ.get("DATATRACKER_DBHOST", "db"),
"PORT": os.environ.get("DATATRACKER_DBPORT", "5432"),
"NAME": os.environ.get("DATATRACKER_DBNAME", "datatracker"),
"ENGINE": "django.db.backends.postgresql",
"USER": os.environ.get("DBUSER", "django"),
"PASSWORD": os.environ.get("DBPASS", ""),
"USER": os.environ.get("DATATRACKER_DBUSER", "django"),
"PASSWORD": os.environ.get("DATATRACKER_DBPASS", ""),
},
}
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY")
# DATATRACKER_ADMINS is a newline-delimited list of addresses parseable by email.utils.parseaddr
_ADMINS = os.environ.get("DATATRACKER_ADMINS", None)
if _ADMINS is not None:
ADMINS = [parseaddr(admin) for admin in _ADMINS.split("\n")]
elif SERVER_MODE == "production":
raise RuntimeError("DATATRACKER_ADMINS must be set in production")
USING_DEBUG_EMAIL_SERVER = os.environ.get("DATATRACKER_EMAIL_DEBUG", "false").lower() == "true"
EMAIL_HOST = os.environ.get("DATATRACKER_EMAIL_HOST", "localhost")
EMAIL_PORT = int(os.environ.get("DATATRACKER_EMAIL_PORT", "2025"))
CELERY_BROKER_URL = "amqp://datatracker:{password}@{host}/{queue}".format(
host=os.environ.get("RABBITMQ_HOSTNAME", "rabbitmq"),
@ -24,62 +102,99 @@ CELERY_BROKER_URL = "amqp://datatracker:{password}@{host}/{queue}".format(
queue=os.environ.get("RABBITMQ_QUEUE", "dt")
)
IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits"
IDSUBMIT_REPOSITORY_PATH = "/test/id/"
IDSUBMIT_STAGING_PATH = "/test/staging/"
IANA_SYNC_USERNAME = "ietfsync"
IANA_SYNC_CHANGES_URL = "https://datatracker.iana.org:4443/data-tracker/changes"
IANA_SYNC_PROTOCOLS_URL = "http://www.iana.org/protocols/"
AGENDA_PATH = "/assets/www6s/proceedings/"
MEETINGHOST_LOGO_PATH = AGENDA_PATH
RFC_EDITOR_NOTIFICATION_URL = "http://www.rfc-editor.org/parser/parser.php"
USING_DEBUG_EMAIL_SERVER=True
EMAIL_HOST= "localhost"
EMAIL_PORT=2025
STATS_REGISTRATION_ATTENDEES_JSON_URL = 'https://registration.ietf.org/{number}/attendees/?apikey=redacted'
MEDIA_BASE_DIR = "/assets"
MEDIA_ROOT = MEDIA_BASE_DIR + "/media/"
MEDIA_URL = "/media/"
#FIRST_CUTOFF_DAYS = 12
#SECOND_CUTOFF_DAYS = 12
#SUBMISSION_CUTOFF_DAYS = 26
#SUBMISSION_CORRECTION_DAYS = 57
MEETING_MATERIALS_SUBMISSION_CUTOFF_DAYS = 26
MEETING_MATERIALS_SUBMISSION_CORRECTION_DAYS = 54
HTPASSWD_COMMAND = "/usr/bin/htpasswd2"
_MEETECHO_CLIENT_ID = os.environ.get("DATATRACKER_MEETECHO_CLIENT_ID", None)
_MEETECHO_CLIENT_SECRET = os.environ.get("DATATRACKER_MEETECHO_CLIENT_SECRET", None)
if _MEETECHO_CLIENT_ID is not None and _MEETECHO_CLIENT_SECRET is not None:
MEETECHO_API_CONFIG = {
"api_base": os.environ.get(
"DATATRACKER_MEETECHO_API_BASE",
"https://meetings.conf.meetecho.com/api/v1/",
),
"client_id": _MEETECHO_CLIENT_ID,
"client_secret": _MEETECHO_CLIENT_SECRET,
"request_timeout": 3.01, # python-requests doc recommend slightly > a multiple of 3 seconds
}
elif SERVER_MODE == "production":
raise RuntimeError(
"DATATRACKER_MEETECHO_CLIENT_ID and DATATRACKER_MEETECHO_CLIENT_SECRET must be set in production"
)
APP_API_TOKENS = {
"ietf.api.views.directauth": ["redacted",],
"ietf.api.views.email_aliases": ["redacted"],
"ietf.api.views.active_email_list": ["redacted"],
}
EMAIL_COPY_TO = ""
# Until we teach the datatracker to look beyond cloudflare for this check
IDSUBMIT_MAX_DAILY_SAME_SUBMITTER = 5000
# Leave DATATRACKER_MATOMO_SITE_ID unset to disable Matomo reporting
if "DATATRACKER_MATOMO_SITE_ID" in os.environ:
MATOMO_DOMAIN_PATH = os.environ.get("DATATRACKER_MATOMO_DOMAIN_PATH", "analytics.ietf.org")
MATOMO_SITE_ID = os.environ.get("DATATRACKER_MATOMO_SITE_ID")
MATOMO_DISABLE_COOKIES = True
# Leave DATATRACKER_SCOUT_KEY unset to disable Scout APM agent
_SCOUT_KEY = os.environ.get("DATATRACKER_SCOUT_KEY", None)
if _SCOUT_KEY is not None:
if SERVER_MODE == "production":
PROD_PRE_APPS = ["scout_apm.django", ]
else:
DEV_PRE_APPS = ["scout_apm.django", ]
SCOUT_MONITOR = True
SCOUT_KEY = _SCOUT_KEY
SCOUT_NAME = "Datatracker"
SCOUT_ERRORS_ENABLED = True
SCOUT_SHUTDOWN_MESSAGE_ENABLED = False
SCOUT_CORE_AGENT_DIR = "/a/core-agent/1.4.0"
SCOUT_CORE_AGENT_FULL_NAME = "scout_apm_core-v1.4.0-x86_64-unknown-linux-musl"
SCOUT_CORE_AGENT_SOCKET_PATH = "tcp://{host}:{port}".format(
host=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_HOST", "scout"),
port=os.environ.get("DATATRACKER_SCOUT_CORE_AGENT_PORT", "16590"),
),
SCOUT_CORE_AGENT_DOWNLOAD = False
SCOUT_CORE_AGENT_LAUNCH = False
SCOUT_REVISION_SHA = __release_hash__[:7]
# Path to the email alias lists. Used by ietf.utils.aliases
DRAFT_ALIASES_PATH = "/a/postfix/draft-aliases"
DRAFT_VIRTUAL_PATH = "/a/postfix/draft-virtual"
GROUP_ALIASES_PATH = "/a/postfix/group-aliases"
GROUP_VIRTUAL_PATH = "/a/postfix/group-virtual"
# Set these to the same as "production" in settings.py, whether production mode or not
MEDIA_ROOT = "/a/www/www6s/lib/dt/media/"
MEDIA_URL = "https://www.ietf.org/lib/dt/media/"
PHOTOS_DIRNAME = "photo"
PHOTOS_DIR = MEDIA_ROOT + PHOTOS_DIRNAME
SUBMIT_YANG_CATALOG_MODEL_DIR = "/assets/ietf-ftp/yang/catalogmod/"
SUBMIT_YANG_DRAFT_MODEL_DIR = "/assets/ietf-ftp/yang/draftmod/"
SUBMIT_YANG_INVAL_MODEL_DIR = "/assets/ietf-ftp/yang/invalmod/"
SUBMIT_YANG_IANA_MODEL_DIR = "/assets/ietf-ftp/yang/ianamod/"
SUBMIT_YANG_RFC_MODEL_DIR = "/assets/ietf-ftp/yang/rfcmod/"
# Set INTERNAL_IPS for use within Docker. See https://knasmueller.net/fix-djangos-debug-toolbar-not-showing-inside-docker
import socket
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS = [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
# DEV_TEMPLATE_CONTEXT_PROCESSORS = [
# 'ietf.context_processors.sql_debug',
# ]
DOCUMENT_PATH_PATTERN = "/assets/ietfdata/doc/{doc.type_id}/"
INTERNET_DRAFT_PATH = "/assets/ietf-ftp/internet-drafts/"
RFC_PATH = "/assets/ietf-ftp/rfc/"
CHARTER_PATH = "/assets/ietf-ftp/charter/"
BOFREQ_PATH = "/assets/ietf-ftp/bofreq/"
CONFLICT_REVIEW_PATH = "/assets/ietf-ftp/conflict-reviews/"
STATUS_CHANGE_PATH = "/assets/ietf-ftp/status-changes/"
INTERNET_DRAFT_ARCHIVE_DIR = "/assets/archive/id"
INTERNET_ALL_DRAFTS_ARCHIVE_DIR = "/assets/archive/id"
BIBXML_BASE_PATH = "/assets/ietfdata/derived/bibxml"
IDSUBMIT_REPOSITORY_PATH = INTERNET_DRAFT_PATH
NOMCOM_PUBLIC_KEYS_DIR = "data/nomcom_keys/public_keys/"
SLIDE_STAGING_PATH = "/test/staging/"
# Normally only set for debug, but needed until we have a real FS
DJANGO_VITE_MANIFEST_PATH = os.path.join(BASE_DIR, 'static/dist-neue/manifest.json')
# Binaries that are different in the docker image
DE_GFM_BINARY = "/usr/local/bin/de-gfm"
IDSUBMIT_IDNITS_BINARY = "/usr/local/bin/idnits"
# OIDC configuration
SITE_URL = os.environ.get("OIDC_SITE_URL")
# todo: parameterize memcached url in settings.py
MEMCACHED_HOST = os.environ.get("MEMCACHED_SERVICE_HOST", "127.0.0.1")
MEMCACHED_PORT = os.environ.get("MEMCACHED_SERVICE_PORT", "11211")
# Duplicating production cache from settings.py and using it whether we're in production mode or not
from ietf import __version__
CACHES = {
"default": {
@ -119,6 +234,3 @@ CACHES = {
},
},
}
# Normally only set for debug, but needed until we have a real FS
DJANGO_VITE_MANIFEST_PATH = os.path.join(BASE_DIR, 'static/dist-neue/manifest.json')

View file

@ -561,10 +561,35 @@ autoscaling:
env:
# n.b., these are debug values / non-secret secrets
# DBHOST: "host.minikube.internal"
# DBPORT: "5432"
DBNAME: "datatracker"
DBUSER: "django"
DBPASS: "RkTkDPFnKpko"
DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk"
DATATRACKER_SERVER_MODE: "development" # defaults to "production"
DATATRACKER_ADMINS: |-
Robert Sparks <rjsparks@nostrum.com>
Ryan Cross <rcross@amsl.com>
Kesara Rathnayake <kesara@staff.ietf.org>
Jennifer Richards <jennifer@staff.ietf.org>
Nicolas Giard <nick@staff.ietf.org>
DATATRACKER_ALLOWED_HOSTS: "*" # empty for production
# DATATRACKER_DATATRACKER_DEBUG: "false"
# DATATRACKER_DBHOST: "db"
# DATATRACKER_DBPORT: "5432"
# DATATRACKER_DBNAME: "datatracker"
# DATATRACKER_DBUSER: "django"
DATATRACKER_DBPASS: "RkTkDPFnKpko"
DATATRACKER_DJANGO_SECRET_KEY: "PDwXboUq!=hPjnrtG2=ge#N$Dwy+wn@uivrugwpic8mxyPfHk"
DATATRACKER_EMAIL_DEBUG: "true"
DATATRACKER_EMAIL_HOST: "localhost"
DATATRACKER_EMAIL_PORT: "2025"
# DATATRACKER_NOMCOM_APP_SECRET_B64: "<base64-encoded bytes>"
DATATRACKER_IANA_SYNC_PASSWORD: "this-is-the-iana-sync-password"
DATATRACKER_RFC_EDITOR_SYNC_PASSWORD: "this-is-the-rfc-editor-sync-password"
DATATRACKER_YOUTUBE_API_KEY: "this-is-the-youtube-api-key"
DATATRACKER_GITHUB_BACKUP_API_KEY: "this-is-the-github-backup-api-key"
# DATATRACKER_API_KEY_TYPE: "ES265"
# DATATRACKER_API_PUBLIC_KEY_PEM_B64: "<base64-encoded PEM"
# DATATRACKER_API_PRIVATE_KEY_PEM_B64: "<base64-encoded PEM"
# DATATRACKER_MEETECHO_API_BASE: "https://meetings.conf.meetecho.com/api/v1/"
DATATRACKER_MEETECHO_CLIENT_ID: "this-is-the-meetecho-client-id"
DATATRACKER_MEETECHO_CLIENT_SECRET: "this-is-the-meetecho-client-secret"
# DATATRACKER_MATOMO_SITE_ID: "7" # must be present to enable Matomo
# DATATRACKER_MATOMO_DOMAIN_PATH: "analytics.ietf.org"
CELERY_PASSWORD: "this-is-a-secret"

View file

@ -949,9 +949,9 @@ def post_process(doc):
Does post processing on uploaded file.
- Convert PPT to PDF
'''
if is_powerpoint(doc) and hasattr(settings, 'SECR_PPT2PDF_COMMAND'):
if is_powerpoint(doc) and hasattr(settings, 'PPT2PDF_COMMAND'):
try:
cmd = list(settings.SECR_PPT2PDF_COMMAND) # Don't operate on the list actually in settings
cmd = list(settings.PPT2PDF_COMMAND) # Don't operate on the list actually in settings
cmd.append(doc.get_file_path()) # outdir
cmd.append(os.path.join(doc.get_file_path(), doc.uploaded_filename)) # filename
subprocess.check_call(cmd)

View file

@ -27,24 +27,6 @@ from ietf.utils.test_utils import TestCase
class SecrMeetingTestCase(TestCase):
settings_temp_path_overrides = TestCase.settings_temp_path_overrides + ['AGENDA_PATH']
def setUp(self):
super().setUp()
self.bluesheet_dir = self.tempdir('bluesheet')
self.bluesheet_path = os.path.join(self.bluesheet_dir,'blue_sheet.rtf')
self.saved_secr_blue_sheet_path = settings.SECR_BLUE_SHEET_PATH
settings.SECR_BLUE_SHEET_PATH = self.bluesheet_path
# n.b., the bluesheet upload relies on SECR_PROCEEDINGS_DIR being the same
# as AGENDA_PATH. This is probably a bug, but may not be worth fixing if
# the secr app is on the way out.
self.saved_secr_proceedings_dir = settings.SECR_PROCEEDINGS_DIR
settings.SECR_PROCEEDINGS_DIR = settings.AGENDA_PATH
def tearDown(self):
settings.SECR_PROCEEDINGS_DIR = self.saved_secr_proceedings_dir
settings.SECR_BLUE_SHEET_PATH = self.saved_secr_blue_sheet_path
shutil.rmtree(self.bluesheet_dir)
super().tearDown()
def test_main(self):
"Main Test"
@ -416,4 +398,4 @@ class SecrMeetingTestCase(TestCase):
times = get_times(meeting,day)
values = [ x[0] for x in times ]
self.assertTrue(times)
self.assertTrue(timeslot.time.strftime('%H%M') in values)
self.assertTrue(timeslot.time.strftime('%H%M') in values)

View file

@ -125,6 +125,10 @@ FORM_RENDERER = "django.forms.renderers.DjangoDivFormRenderer"
# In the future (relative to 4.2), the default will become 'django.db.models.BigAutoField.'
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# OIDC configuration
_SITE_URL = os.environ.get("OIDC_SITE_URL", None)
if _SITE_URL is not None:
SITE_URL = _SITE_URL
if SERVER_MODE == 'production':
MEDIA_ROOT = '/a/www/www6s/lib/dt/media/'
@ -978,7 +982,7 @@ DE_GFM_BINARY = '/usr/bin/de-gfm.ruby2.5'
DAYS_TO_EXPIRE_REGISTRATION_LINK = 3
MINUTES_TO_EXPIRE_RESET_PASSWORD_LINK = 60
HTPASSWD_COMMAND = "/usr/bin/htpasswd"
HTPASSWD_FILE = "/www/htpasswd"
HTPASSWD_FILE = "/a/www/htpasswd"
# Generation of pdf files
GHOSTSCRIPT_COMMAND = "/usr/bin/gs"
@ -989,12 +993,11 @@ BIBXML_BASE_PATH = '/a/ietfdata/derived/bibxml'
# Timezone files for iCalendar
TZDATA_ICS_PATH = BASE_DIR + '/../vzic/zoneinfo/'
SECR_BLUE_SHEET_PATH = '/a/www/ietf-datatracker/documents/blue_sheet.rtf'
SECR_BLUE_SHEET_URL = IDTRACKER_BASE_URL + '/documents/blue_sheet.rtf'
SECR_INTERIM_LISTING_DIR = '/a/www/www6/meeting/interim'
SECR_MAX_UPLOAD_SIZE = 40960000
SECR_PROCEEDINGS_DIR = '/a/www/www6s/proceedings/'
SECR_PPT2PDF_COMMAND = ['/usr/bin/soffice','--headless','--convert-to','pdf:writer_globaldocument_pdf_Export','--outdir']
DATATRACKER_MAX_UPLOAD_SIZE = 40960000
PPT2PDF_COMMAND = [
"/usr/bin/soffice", "--headless", "--convert-to", "pdf:writer_globaldocument_pdf_Export", "--outdir"
]
STATS_REGISTRATION_ATTENDEES_JSON_URL = 'https://registration.ietf.org/{number}/attendees/'
PROCEEDINGS_VERSION_CHANGES = [
0, # version 1
@ -1206,81 +1209,83 @@ else:
MIDDLEWARE += DEV_MIDDLEWARE
TEMPLATES[0]['OPTIONS']['context_processors'] += DEV_TEMPLATE_CONTEXT_PROCESSORS
if 'CACHES' not in locals():
if SERVER_MODE == 'production':
if "CACHES" not in locals():
if SERVER_MODE == "production":
MEMCACHED_HOST = os.environ.get("MEMCACHED_SERVICE_HOST", "127.0.0.1")
MEMCACHED_PORT = os.environ.get("MEMCACHED_SERVICE_PORT", "11211")
CACHES = {
'default': {
'BACKEND': 'ietf.utils.cache.LenientMemcacheCache',
'LOCATION': '127.0.0.1:11211',
'VERSION': __version__,
'KEY_PREFIX': 'ietf:dt',
'KEY_FUNCTION': lambda key, key_prefix, version: (
"default": {
"BACKEND": "ietf.utils.cache.LenientMemcacheCache",
"LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}",
"VERSION": __version__,
"KEY_PREFIX": "ietf:dt",
"KEY_FUNCTION": lambda key, key_prefix, version: (
f"{key_prefix}:{version}:{sha384(str(key).encode('utf8')).hexdigest()}"
),
},
'sessions': {
'BACKEND': 'ietf.utils.cache.LenientMemcacheCache',
'LOCATION': '127.0.0.1:11211',
"sessions": {
"BACKEND": "ietf.utils.cache.LenientMemcacheCache",
"LOCATION": f"{MEMCACHED_HOST}:{MEMCACHED_PORT}",
# No release-specific VERSION setting.
'KEY_PREFIX': 'ietf:dt',
"KEY_PREFIX": "ietf:dt",
},
'htmlized': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/a/cache/datatracker/htmlized',
'OPTIONS': {
'MAX_ENTRIES': 100000, # 100,000
"htmlized": {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": "/a/cache/datatracker/htmlized",
"OPTIONS": {
"MAX_ENTRIES": 100000, # 100,000
},
},
'pdfized': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/a/cache/datatracker/pdfized',
'OPTIONS': {
'MAX_ENTRIES': 100000, # 100,000
"pdfized": {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": "/a/cache/datatracker/pdfized",
"OPTIONS": {
"MAX_ENTRIES": 100000, # 100,000
},
},
'slowpages': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/a/cache/datatracker/slowpages',
'OPTIONS': {
'MAX_ENTRIES': 5000,
"slowpages": {
"BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
"LOCATION": "/a/cache/datatracker/slowpages",
"OPTIONS": {
"MAX_ENTRIES": 5000,
},
},
}
else:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
"default": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
#'BACKEND': 'ietf.utils.cache.LenientMemcacheCache',
#'LOCATION': '127.0.0.1:11211',
#'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'VERSION': __version__,
'KEY_PREFIX': 'ietf:dt',
"VERSION": __version__,
"KEY_PREFIX": "ietf:dt",
},
'sessions': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
"sessions": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
},
'htmlized': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
"htmlized": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
#'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/cache/datatracker/htmlized',
'OPTIONS': {
'MAX_ENTRIES': 1000,
"LOCATION": "/var/cache/datatracker/htmlized",
"OPTIONS": {
"MAX_ENTRIES": 1000,
},
},
'pdfized': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
"pdfized": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
#'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/cache/datatracker/pdfized',
'OPTIONS': {
'MAX_ENTRIES': 1000,
"LOCATION": "/var/cache/datatracker/pdfized",
"OPTIONS": {
"MAX_ENTRIES": 1000,
},
},
'slowpages': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
"slowpages": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
#'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/cache/datatracker/',
'OPTIONS': {
'MAX_ENTRIES': 5000,
"LOCATION": "/var/cache/datatracker/",
"OPTIONS": {
"MAX_ENTRIES": 5000,
},
},
}

View file

@ -60,6 +60,7 @@ class RegexStringValidator(object):
validate_regular_expression_string = RegexStringValidator()
def validate_file_size(file, missing_ok=False):
try:
size = file.size
@ -69,8 +70,14 @@ def validate_file_size(file, missing_ok=False):
else:
raise
if size > settings.SECR_MAX_UPLOAD_SIZE:
raise ValidationError('Please keep filesize under %s. Requested upload size was %s' % (filesizeformat(settings.SECR_MAX_UPLOAD_SIZE), filesizeformat(file.size)))
if size > settings.DATATRACKER_MAX_UPLOAD_SIZE:
raise ValidationError(
"Please keep filesize under {}. Requested upload size was {}".format(
filesizeformat(settings.DATATRACKE_MAX_UPLOAD_SIZE),
filesizeformat(file.size)
)
)
def validate_mime_type(file, valid, missing_ok=False):
try: