Skip to content

Standardizing the use of settings directly #5632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 9, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions readthedocs/builds/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
from .version_slug import VersionSlugField


DEFAULT_VERSION_PRIVACY_LEVEL = settings.DEFAULT_VERSION_PRIVACY_LEVEL

log = logging.getLogger(__name__)


Expand Down Expand Up @@ -101,7 +99,7 @@ class Version(models.Model):
_('Privacy Level'),
max_length=20,
choices=PRIVACY_CHOICES,
default=DEFAULT_VERSION_PRIVACY_LEVEL,
default=settings.DEFAULT_VERSION_PRIVACY_LEVEL,
help_text=_('Level of privacy for this Version.'),
)
tags = TaggableManager(blank=True)
Expand Down
27 changes: 13 additions & 14 deletions readthedocs/builds/syncers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ def copy(cls, path, target, is_file=False, **kwargs):

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
app_servers = settings.MULTIPLE_APP_SERVERS
if app_servers:
log.info('Remote Copy %s to %s on %s', path, target, app_servers)
for server in app_servers:
if settings.MULTIPLE_APP_SERVERS:
log.info(
'Remote Copy %s to %s on %s',
path, target,
settings.MULTIPLE_APP_SERVERS
)
for server in settings.MULTIPLE_APP_SERVERS:
mkdir_cmd = (
'ssh {}@{} mkdir -p {}'.format(sync_user, server, target)
'ssh {}@{} mkdir -p {}'.format(settings.SYNC_USER, server, target)
)
ret = os.system(mkdir_cmd)
if ret != 0:
Expand All @@ -83,7 +85,7 @@ def copy(cls, path, target, is_file=False, **kwargs):
"rsync -e 'ssh -T' -av --delete {path}{slash} {user}@{server}:{target}".format(
path=path,
slash=slash,
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -102,15 +104,13 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
app_servers = settings.MULTIPLE_APP_SERVERS
if not is_file:
path += '/'
log.info('Remote Copy %s to %s', path, target)
for server in app_servers:
for server in settings.MULTIPLE_APP_SERVERS:
if not is_file:
mkdir_cmd = 'ssh {user}@{server} mkdir -p {target}'.format(
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -123,7 +123,7 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a
"--delete --exclude projects {user}@{host}:{path} {target}'".format(
host=host,
path=path,
user=sync_user,
user=settings.SYNC_USER,
server=server,
target=target,
)
Expand All @@ -142,7 +142,6 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a

Respects the ``MULTIPLE_APP_SERVERS`` setting when copying.
"""
sync_user = settings.SYNC_USER
if not is_file:
path += '/'
log.info('Remote Pull %s to %s', path, target)
Expand All @@ -156,7 +155,7 @@ def copy(cls, path, target, host, is_file=False, **kwargs): # pylint: disable=a
sync_cmd = "rsync -e 'ssh -T' -av --delete {user}@{host}:{path} {target}".format(
host=host,
path=path,
user=sync_user,
user=settings.SYNC_USER,
target=target,
)
ret = os.system(sync_cmd)
Expand Down
36 changes: 15 additions & 21 deletions readthedocs/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@
INVALID_KEYS_COMBINATION = 'invalid-keys-combination'
INVALID_KEY = 'invalid-key'

DOCKER_DEFAULT_IMAGE = settings.DOCKER_DEFAULT_IMAGE
DOCKER_DEFAULT_VERSION = settings.DOCKER_DEFAULT_VERSION
# These map to corresponding settings in the .org,
# so they haven't been renamed.
DOCKER_IMAGE = settings.DOCKER_IMAGE
DOCKER_IMAGE_SETTINGS = settings.DOCKER_IMAGE_SETTINGS

LATEST_CONFIGURATION_VERSION = 2


Expand Down Expand Up @@ -159,7 +152,6 @@ class BuildConfigBase:
'submodules',
]

default_build_image = DOCKER_DEFAULT_VERSION
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this one can stay

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different configuration files can have a different default image

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay

version = None

def __init__(self, env_config, raw_config, source_file):
Expand Down Expand Up @@ -268,13 +260,13 @@ def valid_build_images(self):
``readthedocs/build`` part) plus ``stable`` and ``latest``.
"""
images = {'stable', 'latest'}
for k in DOCKER_IMAGE_SETTINGS:
for k in settings.DOCKER_IMAGE_SETTINGS:
_, version = k.split(':')
if re.fullmatch(r'^[\d\.]+$', version):
images.add(version)
return images

def get_valid_python_versions_for_image(self, build_image):
def get_valid_python_versions_for_image(self, build_image): # pylint: disable=no-self-use
"""
Return all the valid Python versions for a Docker image.

Expand All @@ -284,12 +276,12 @@ def get_valid_python_versions_for_image(self, build_image):
Returns supported versions for the ``DOCKER_DEFAULT_VERSION`` if not
``build_image`` found.
"""
if build_image not in DOCKER_IMAGE_SETTINGS:
if build_image not in settings.DOCKER_IMAGE_SETTINGS:
build_image = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
self.default_build_image,
settings.DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_VERSION,
)
return DOCKER_IMAGE_SETTINGS[build_image]['python']['supported_versions']
return settings.DOCKER_IMAGE_SETTINGS[build_image]['python']['supported_versions']

def as_dict(self):
config = {}
Expand Down Expand Up @@ -326,7 +318,7 @@ def get_valid_python_versions(self):
return self.env_config['python']['supported_versions']
except (KeyError, TypeError):
versions = set()
for _, options in DOCKER_IMAGE_SETTINGS.items():
for _, options in settings.DOCKER_IMAGE_SETTINGS.items():
versions = versions.union(
options['python']['supported_versions']
)
Expand Down Expand Up @@ -381,7 +373,7 @@ def validate_build(self):
if 'build' in self.env_config:
build = self.env_config['build'].copy()
else:
build = {'image': DOCKER_IMAGE}
build = {'image': settings.DOCKER_IMAGE}

# User specified
if 'build' in self.raw_config:
Expand All @@ -395,12 +387,12 @@ def validate_build(self):
if ':' not in build['image']:
# Prepend proper image name to user's image name
build['image'] = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_IMAGE,
build['image'],
)
# Update docker default settings from image name
if build['image'] in DOCKER_IMAGE_SETTINGS:
self.env_config.update(DOCKER_IMAGE_SETTINGS[build['image']])
if build['image'] in settings.DOCKER_IMAGE_SETTINGS:
self.env_config.update(settings.DOCKER_IMAGE_SETTINGS[build['image']])

# Allow to override specific project
config_image = self.defaults.get('build_image')
Expand Down Expand Up @@ -700,9 +692,11 @@ def validate_build(self):
validate_dict(raw_build)
build = {}
with self.catch_validation_error('build.image'):
image = self.pop_config('build.image', self.default_build_image)
image = self.pop_config(
'build.image', settings.DOCKER_DEFAULT_VERSION
)
build['image'] = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
settings.DOCKER_DEFAULT_IMAGE,
validate_choice(
image,
self.valid_build_images,
Expand Down
17 changes: 7 additions & 10 deletions readthedocs/core/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
log = logging.getLogger(__name__)

LOG_TEMPLATE = '(Middleware) {msg} [{host}{path}]'
SUBDOMAIN_URLCONF = settings.SUBDOMAIN_URLCONF
SINGLE_VERSION_URLCONF = settings.SINGLE_VERSION_URLCONF


class SubdomainMiddleware(MiddlewareMixin):
Expand All @@ -38,10 +36,9 @@ def process_request(self, request):
path = request.get_full_path()
log_kwargs = dict(host=host, path=path)
public_domain = settings.PUBLIC_DOMAIN
production_domain = settings.PRODUCTION_DOMAIN

if public_domain is None:
public_domain = production_domain
public_domain = settings.PRODUCTION_DOMAIN
if ':' in host:
host = host.split(':')[0]
domain_parts = host.split('.')
Expand All @@ -57,21 +54,21 @@ def process_request(self, request):
raise Http404(_('Project not found'))
request.subdomain = True
request.slug = subdomain
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
return None

# Serve CNAMEs
if (
public_domain not in host and production_domain not in host and
'localhost' not in host and 'testserver' not in host
public_domain not in host and settings.PRODUCTION_DOMAIN not in host
and 'localhost' not in host and 'testserver' not in host
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't start a line with an operator

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, maybe this can be written like

if  all(test_host not in host for test_host in ('localhost', 'testserver', public_domain, settings.PRODUCTION_DOMAIN)):

(not sure if that is more readable)

):
request.cname = True
domains = Domain.objects.filter(domain=host)
if domains.count():
for domain in domains:
if domain.domain == host:
request.slug = domain.project.slug
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
request.domain_object = True
log.debug(
LOG_TEMPLATE.format(
Expand All @@ -85,7 +82,7 @@ def process_request(self, request):
'HTTP_X_RTD_SLUG' in request.META
):
request.slug = request.META['HTTP_X_RTD_SLUG'].lower()
request.urlconf = SUBDOMAIN_URLCONF
request.urlconf = settings.SUBDOMAIN_URLCONF
request.rtdheader = True
log.debug(
LOG_TEMPLATE.format(
Expand Down Expand Up @@ -161,7 +158,7 @@ def process_request(self, request):
return None

if getattr(proj, 'single_version', False):
request.urlconf = SINGLE_VERSION_URLCONF
request.urlconf = settings.SINGLE_VERSION_URLCONF
# Logging
host = request.get_host()
path = request.get_full_path()
Expand Down
14 changes: 5 additions & 9 deletions readthedocs/core/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,15 @@ def resolve(
else:
domain = settings.PRODUCTION_DOMAIN

public_domain = settings.PUBLIC_DOMAIN
use_https = settings.PUBLIC_DOMAIN_USES_HTTPS

use_https_protocol = any([
# Rely on the ``Domain.https`` field
use_custom_domain and custom_domain.https,
# or force it if specified
require_https,
# or fallback to settings
use_https and public_domain and public_domain in domain,
settings.PUBLIC_DOMAIN_USES_HTTPS
and settings.PUBLIC_DOMAIN
and settings.PUBLIC_DOMAIN in domain,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't start with an operator

])
protocol = 'https' if use_https_protocol else 'http'

Expand Down Expand Up @@ -229,11 +228,10 @@ def _get_canonical_project(self, project, projects=None):

def _get_project_subdomain(self, project):
"""Determine canonical project domain as subdomain."""
public_domain = settings.PUBLIC_DOMAIN
if self._use_subdomain():
project = self._get_canonical_project(project)
subdomain_slug = project.slug.replace('_', '-')
return '{}.{}'.format(subdomain_slug, public_domain)
return '{}.{}'.format(subdomain_slug, settings.PUBLIC_DOMAIN)

def _get_private(self, project, version_slug):
from readthedocs.builds.models import Version
Expand Down Expand Up @@ -266,9 +264,7 @@ def _use_custom_domain(self, custom_domain):

def _use_subdomain(self):
"""Make decision about whether to use a subdomain to serve docs."""
use_subdomain = settings.USE_SUBDOMAIN
public_domain = settings.PUBLIC_DOMAIN
return use_subdomain and public_domain is not None
return settings.USE_SUBDOMAIN and settings.PUBLIC_DOMAIN is not None


class Resolver(SettingsOverrideObject):
Expand Down
2 changes: 0 additions & 2 deletions readthedocs/core/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@

log = logging.getLogger(__name__)

SYNC_USER = settings.SYNC_USER


def broadcast(type, task, args, kwargs=None, callback=None): # pylint: disable=redefined-builtin
"""
Expand Down
6 changes: 2 additions & 4 deletions readthedocs/core/views/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,17 +242,15 @@ def _serve_symlink_docs(request, project, privacy_level, filename=''):

files_tried = []

serve_docs = settings.SERVE_DOCS

if (settings.DEBUG or constants.PUBLIC in serve_docs) and privacy_level != constants.PRIVATE: # yapf: disable # noqa
if (settings.DEBUG or constants.PUBLIC in settings.SERVE_DOCS) and privacy_level != constants.PRIVATE: # yapf: disable # noqa
public_symlink = PublicSymlink(project)
basepath = public_symlink.project_root
if os.path.exists(os.path.join(basepath, filename)):
return _serve_file(request, filename, basepath)

files_tried.append(os.path.join(basepath, filename))

if (settings.DEBUG or constants.PRIVATE in serve_docs) and privacy_level == constants.PRIVATE: # yapf: disable # noqa
if (settings.DEBUG or constants.PRIVATE in settings.SERVE_DOCS) and privacy_level == constants.PRIVATE: # yapf: disable # noqa
# Handle private
private_symlink = PrivateSymlink(project)
basepath = private_symlink.project_root
Expand Down
8 changes: 3 additions & 5 deletions readthedocs/doc_builder/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@
DOCKER_IMAGE = settings.DOCKER_IMAGE
DOCKER_IMAGE_SETTINGS = settings.DOCKER_IMAGE_SETTINGS

old_config = settings.DOCKER_BUILD_IMAGES
if old_config:
if settings.DOCKER_BUILD_IMAGES:
log.warning(
'Old config detected, DOCKER_BUILD_IMAGES->DOCKER_IMAGE_SETTINGS',
)
DOCKER_IMAGE_SETTINGS.update(old_config)
DOCKER_IMAGE_SETTINGS.update(settings.DOCKER_BUILD_IMAGES)

DOCKER_LIMITS = {'memory': '200m', 'time': 600}
DOCKER_LIMITS.update(settings.DOCKER_LIMITS)
DOCKER_LIMITS = settings.DOCKER_LIMITS

DOCKER_TIMEOUT_EXIT_CODE = 42
DOCKER_OOM_EXIT_CODE = 137
Expand Down
7 changes: 3 additions & 4 deletions readthedocs/notifications/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ def send_notification(request, notification):
should be a list of class paths to be loaded, using the standard Django
string module loader.
"""
backends = settings.NOTIFICATION_BACKENDS
for cls_name in backends:
for cls_name in settings.NOTIFICATION_BACKENDS:
backend = import_string(cls_name)(request)
backend.send(notification)

Expand Down Expand Up @@ -93,8 +92,8 @@ def send(self, notification):
# manipulates the storage directly. This is because we don't have a
# request object and need to mock one out to fool the message storage
# into saving a message for a separate user.
cls_name = settings.MESSAGE_STORAGE
cls = import_string(cls_name)

cls = import_string(settings.MESSAGE_STORAGE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are losing readability here

req = HttpRequest()
setattr(req, 'session', '')
storage = cls(req)
Expand Down
5 changes: 2 additions & 3 deletions readthedocs/projects/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,11 @@ class RepositoryURLValidator:
re_git_user = re.compile(r'^[\w]+@.+')

def __call__(self, value):
allow_private_repos = settings.ALLOW_PRIVATE_REPOS
public_schemes = ['https', 'http', 'git', 'ftps', 'ftp']
private_schemes = ['ssh', 'ssh+git']
local_schemes = ['file']
valid_schemes = public_schemes
if allow_private_repos:
if settings.ALLOW_PRIVATE_REPOS:
valid_schemes += private_schemes
if settings.DEBUG: # allow `file://` urls in dev
valid_schemes += local_schemes
Expand All @@ -86,7 +85,7 @@ def __call__(self, value):
return value
# SSH cloning and ``[email protected]:user/project.git``
elif self.re_git_user.search(value) or url.scheme in private_schemes:
if allow_private_repos:
if settings.ALLOW_PRIVATE_REPOS:
return value

# Throw a more helpful error message
Expand Down
Loading