Update to Django 2.2, drop py2 support

OpenStack is dropping the py2.7 support in Ussuri cycle.

Adjutant is also upgrading to Django 2.2 at the same time
which is the new Django LTS, and only supports python 3.

Complete discussion & schedule can be found in
-
http://lists.openstack.org/pipermail/openstack-discuss/2019-October/010142.html
- https://etherpad.openstack.org/p/drop-python2-support

Ussuri Communtiy-wide goal:
https://governance.openstack.org/tc/goals/selected/ussuri/drop-py27.html

Ussuri Communtiy-wide goal:
https://governance.openstack.org/tc/goals/selected/ussuri/drop-py27.html

Change-Id: I2a429ebd6bc20385e814da03b222a1f61214a683
This commit is contained in:
Adrian Turjak 2020-02-05 11:41:32 +13:00
parent e71a1c2a5c
commit ad81fdf706
12 changed files with 53 additions and 35 deletions

View File

@ -3,5 +3,4 @@
- publish-openstack-docs-pti
- build-release-notes-jobs-python3
- openstack-cover-jobs
- openstack-python-jobs
- openstack-python3-ussuri-jobs

View File

@ -25,7 +25,7 @@ class Migration(migrations.Migration):
('need_token', models.BooleanField(default=False)),
('order', models.IntegerField()),
('created', models.DateTimeField(default=django.utils.timezone.now)),
('task', models.ForeignKey(to='api.Task')),
('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Task')),
],
),
]

View File

@ -30,7 +30,7 @@ class Action(models.Model):
state = models.CharField(max_length=200, default="default")
valid = models.BooleanField(default=False)
need_token = models.BooleanField(default=False)
task = models.ForeignKey('tasks.Task')
task = models.ForeignKey('tasks.Task', on_delete=models.CASCADE)
# NOTE(amelia): Auto approve is technically a ternary operator
# If all in a task are None it will not auto approve
# However if at least one action has it set to True it

View File

@ -47,12 +47,12 @@ class Migration(migrations.Migration):
('token', models.CharField(max_length=32, serialize=False, primary_key=True)),
('created_on', models.DateTimeField(default=django.utils.timezone.now)),
('expires', models.DateTimeField(db_index=True)),
('task', models.ForeignKey(to='api.Task')),
('task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Task')),
],
),
migrations.AddField(
model_name='notification',
name='task',
field=models.ForeignKey(to='api.Task'),
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Task'),
),
]

View File

@ -7,6 +7,8 @@ from django.db import migrations
class Migration(migrations.Migration):
atomic = False
dependencies = [
('api', '0004_auto_20160929_0317'),
]

View File

@ -29,7 +29,7 @@ class Token(models.Model):
UUID token object bound to a task.
"""
task = models.ForeignKey(Task)
task = models.ForeignKey(Task, on_delete=models.CASCADE)
token = models.CharField(max_length=32, primary_key=True)
created_on = models.DateTimeField(default=timezone.now)
expires = models.DateTimeField(db_index=True)
@ -56,7 +56,7 @@ class Notification(models.Model):
uuid = models.CharField(max_length=32, default=hex_uuid,
primary_key=True)
notes = JSONField(default={})
task = models.ForeignKey(Task)
task = models.ForeignKey(Task, on_delete=models.CASCADE)
error = models.BooleanField(default=False, db_index=True)
created_on = models.DateTimeField(default=timezone.now)
acknowledged = models.BooleanField(default=False, db_index=True)

View File

@ -17,12 +17,15 @@ from logging import getLogger
from django.utils import timezone
class KeystoneHeaderUnwrapper(object):
class KeystoneHeaderUnwrapper:
"""
Middleware to build an easy to use dict of important data from
what the keystone wsgi middleware gives us.
"""
def process_request(self, request):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
token_data = {
'project_domain_id': request.META['HTTP_X_PROJECT_DOMAIN_ID'],
@ -38,12 +41,18 @@ class KeystoneHeaderUnwrapper(object):
token_data = {}
request.keystone_user = token_data
response = self.get_response(request)
return response
class TestingHeaderUnwrapper(object):
class TestingHeaderUnwrapper:
"""
Replacement for the KeystoneHeaderUnwrapper for testing purposes.
"""
def process_request(self, request):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
token_data = {
# TODO(adriant): follow up patch to update all the test
@ -65,17 +74,21 @@ class TestingHeaderUnwrapper(object):
token_data = {}
request.keystone_user = token_data
response = self.get_response(request)
return response
class RequestLoggingMiddleware(object):
class RequestLoggingMiddleware:
"""
Middleware to log the requests and responses.
Will time the duration of a request and log that.
"""
def __init__(self):
def __init__(self, get_response):
self.get_response = get_response
self.logger = getLogger('adjutant')
def process_request(self, request):
def __call__(self, request):
self.logger.info(
'(%s) - <%s> %s [%s]',
timezone.now(),
@ -85,7 +98,8 @@ class RequestLoggingMiddleware(object):
)
request.timer = time()
def process_response(self, request, response):
response = self.get_response(request)
if hasattr(request, 'timer'):
time_delta = time() - request.timer
else:

View File

@ -33,7 +33,6 @@ BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
@ -50,23 +49,17 @@ INSTALLED_APPS = (
'adjutant.startup',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
MIDDLEWARE = (
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'adjutant.middleware.KeystoneHeaderUnwrapper',
'adjutant.middleware.RequestLoggingMiddleware'
)
if 'test' in sys.argv:
# modify MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = list(MIDDLEWARE_CLASSES)
MIDDLEWARE_CLASSES.remove('adjutant.middleware.KeystoneHeaderUnwrapper')
MIDDLEWARE_CLASSES.append('adjutant.middleware.TestingHeaderUnwrapper')
# modify MIDDLEWARE
MIDDLEWARE = list(MIDDLEWARE)
MIDDLEWARE.remove('adjutant.middleware.KeystoneHeaderUnwrapper')
MIDDLEWARE.append('adjutant.middleware.TestingHeaderUnwrapper')
ROOT_URLCONF = 'adjutant.urls'
@ -98,6 +91,8 @@ TEMPLATES = [
},
]
AUTHENTICATION_BACKENDS = []
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'adjutant.api.exception_handler.exception_handler',
'DEFAULT_RENDERER_CLASSES': [

View File

@ -0,0 +1,12 @@
---
upgrade:
- |
Adjutant will now officially only support Python3.6 onwards, and will
start introducing features only applicable to that version onwards.
deprecations:
- |
Python2 support has been officially deprecated. The code may still be
compatible for a bit longer, but we are also switching to Django 2.2,
and python2 can no longer be tested. Support for Python less than 3.6
has also been deprecated, but may still work for older python3 versions
for a little longer, although not officially.

View File

@ -1,5 +1,6 @@
pbr>=5.2.0
Django>=2.2,<2.3
Babel>=2.6.0
decorator>=4.4.0
django-rest-swagger>=2.2.0
@ -15,8 +16,4 @@ python-octaviaclient>=1.8.0
PyYAML>=5.1
six>=1.12.0
confspirator>=0.1.6
# Address soon:
Django>=1.11,<1.12
# was pinned because of django 1.11
mysqlclient>=1.3.10,<1.4
mysqlclient>=1.4.6

View File

@ -16,8 +16,7 @@ classifier =
Intended Audience :: Developers
Intended Audience :: System Administrators
License :: OSI Approved :: Apache Software License
Framework :: Django :: 1.11
Programming Language :: Python :: 2.7
Framework :: Django :: 2.2
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7

View File

@ -1,5 +1,5 @@
[tox]
envlist = py3,py27,pep8,cover_report
envlist = py3,pep8,cover_report
skipsdist = True
[testenv]