From 4c053b1aac344b9963040fcca87d65508c5bf8f7 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Thu, 6 Feb 2020 23:58:16 +0000 Subject: [PATCH 01/13] migrate to django.urls.path instead of django.conf.urls.url --- hosts/urls.py | 11 +++++------ operatingsystems/urls.py | 16 +++++++--------- packages/urls.py | 7 +++---- patchman/urls.py | 25 +++++++++++++------------ reports/urls.py | 15 ++++++--------- reports/views.py | 12 ++++++------ repos/urls.py | 28 +++++++++++----------------- util/urls.py | 6 +++--- 8 files changed, 54 insertions(+), 66 deletions(-) diff --git a/hosts/urls.py b/hosts/urls.py index 0fb6cb43..7343225a 100644 --- a/hosts/urls.py +++ b/hosts/urls.py @@ -17,16 +17,15 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from hosts import views app_name = 'hosts' urlpatterns = [ - url(r'^$', views.host_list, name='host_list'), - url(r'^(?P[-.\w]+)/$', views.host_detail, name='host_detail'), - url(r'^(?P[-.\w]+)/delete/$', views.host_delete, - name='host_delete'), - url(r'^(?P[-.\w]+)/edit/$', views.host_edit, name='host_edit'), + path('', views.host_list, name='host_list'), + path('/', views.host_detail, name='host_detail'), + path('/delete/', views.host_delete, name='host_delete'), + path('/edit/', views.host_edit, name='host_edit'), ] diff --git a/operatingsystems/urls.py b/operatingsystems/urls.py index e53ad219..e49edebc 100644 --- a/operatingsystems/urls.py +++ b/operatingsystems/urls.py @@ -17,19 +17,17 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from operatingsystems import views app_name = 'operatingsystems' urlpatterns = [ - url(r'^$', views.os_list, name='os_list'), - url(r'^groups/$', views.osgroup_list, name='osgroup_list'), - url(r'^(?P[-.\w]+)/$', views.os_detail, name='os_detail'), - url(r'^(?P[-.\w]+)/delete/$', views.os_delete, name='os_delete'), - url(r'^groups/(?P[-.\w]+)/$', views.osgroup_detail, - name='osgroup_detail'), - url(r'^groups/(?P[-.\w]+)/delete/$', views.osgroup_delete, - name='osgroup_delete'), + path('', views.os_list, name='os_list'), + path('/', views.os_detail, name='os_detail'), + path('/delete/', views.os_delete, name='os_delete'), + path('groups/', views.osgroup_list, name='osgroup_list'), + path('groups//', views.osgroup_detail, name='osgroup_detail'), # noqa + path('groups//delete/', views.osgroup_delete, name='osgroup_delete'), # noqa ] diff --git a/packages/urls.py b/packages/urls.py index d74f5c89..322cb121 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -17,14 +17,13 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from packages import views app_name = 'packages' urlpatterns = [ - url(r'^$', views.package_list, name='package_list'), - url(r'^(?P[_+-.\w]+)/$', views.package_detail, - name='package_detail'), + path('', views.package_list, name='package_list'), + path('/', views.package_detail, name='package_detail'), ] diff --git a/patchman/urls.py b/patchman/urls.py index 38474ed6..e8a24c01 100644 --- a/patchman/urls.py +++ b/patchman/urls.py @@ -17,9 +17,10 @@ from __future__ import unicode_literals -from django.conf.urls import url, include, handler404, handler500 # noqa +from django.conf.urls import include, handler404, handler500 # noqa from django.conf import settings from django.contrib import admin +from django.urls import path from django.views import static from rest_framework import routers @@ -51,17 +52,17 @@ admin.autodiscover() urlpatterns = [ - url(r'^', include('django.contrib.auth.urls')), - url(r'^admin/', admin.site.urls), - url(r'^api/', include(router.urls)), - url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), # noqa - url(r'^', include('util.urls', namespace='util')), - url(r'^reports/', include('reports.urls', namespace='reports')), - url(r'^hosts/', include('hosts.urls', namespace='hosts')), - url(r'^packages/', include('packages.urls', namespace='packages')), - url(r'^repos/', include('repos.urls', namespace='repos')), - url(r'^os/', include('operatingsystems.urls', namespace='operatingsystems')), # noqa + path('', include('django.contrib.auth.urls')), + path('admin/', admin.site.urls), + path('api/', include(router.urls)), + path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), # noqa + path('', include('util.urls', namespace='util')), + path('reports/', include('reports.urls', namespace='reports')), + path('hosts/', include('hosts.urls', namespace='hosts')), + path('packages/', include('packages.urls', namespace='packages')), + path('repos/', include('repos.urls', namespace='repos')), + path('os/', include('operatingsystems.urls', namespace='operatingsystems')), # noqa ] if settings.DEBUG: - urlpatterns += [url(r'^static/(?P.*)$', static.serve)] + urlpatterns += [path('static/', static.serve)] diff --git a/reports/urls.py b/reports/urls.py index ae74cb07..3968a9a8 100644 --- a/reports/urls.py +++ b/reports/urls.py @@ -17,19 +17,16 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from reports import views app_name = 'reports' urlpatterns = [ - url(r'^$', views.report_list, name='report_list'), - url(r'^upload/$', views.upload), - url(r'^(?P[-.\w]+)/$', views.report_detail, - name='report_detail'), - url(r'^(?P[-.\w]+)/delete/$', views.report_delete, - name='report_delete'), - url(r'^(?P[-.\w]+)/process/$', views.report_process, - name='report_process'), + path('', views.report_list, name='report_list'), + path('upload/', views.upload), + path('/', views.report_detail, name='report_detail'), + path('/delete/', views.report_delete, name='report_delete'), + path('/process/', views.report_process, name='report_process'), # noqa ] diff --git a/reports/views.py b/reports/views.py index dad977dc..df927e5e 100644 --- a/reports/views.py +++ b/reports/views.py @@ -112,9 +112,9 @@ def report_list(request): @login_required -def report_detail(request, report): +def report_detail(request, report_id): - report = get_object_or_404(Report, id=report) + report = get_object_or_404(Report, id=report_id) return render(request, 'reports/report_detail.html', @@ -122,9 +122,9 @@ def report_detail(request, report): @login_required -def report_process(request, report): +def report_process(request, report_id): - report = get_object_or_404(Report, id=report) + report = get_object_or_404(Report, id=report_id) report.process() return render(request, @@ -133,9 +133,9 @@ def report_process(request, report): @login_required -def report_delete(request, report): +def report_delete(request, report_id): - report = get_object_or_404(Report, id=report) + report = get_object_or_404(Report, id=report_id) if request.method == 'POST': if 'delete' in request.POST: diff --git a/repos/urls.py b/repos/urls.py index 6a103111..aa52a25a 100644 --- a/repos/urls.py +++ b/repos/urls.py @@ -17,27 +17,21 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from repos import views app_name = 'repos' urlpatterns = [ - url(r'^$', views.repo_list, name='repo_list'), - url(r'^(?P[-.\w]+)/delete/$', views.repo_delete, - name='repo_delete'), - url(r'^(?P[-.\w]+)/toggle_enabled/$', views.repo_toggle_enabled, - name='repo_toggle_enabled'), - url(r'^(?P[-.\w]+)/toggle_security/$', views.repo_toggle_security, - name='repo_toggle_security'), - url(r'^(?P[-.\w]+)/edit/$', views.repo_edit, name='repo_edit'), - url(r'^mirrors/$', views.mirror_list, name='mirror_list'), - url(r'^(?P[-.\w]+)/$', views.repo_detail, name='repo_detail'), - url(r'^mirrors/mirror/(?P[-.\w]+)/$', - views.mirror_detail, name='mirror_detail'), - url(r'^mirrors/mirror/(?P[-.\w]+)/delete/$', - views.mirror_delete, name='mirror_delete'), - url(r'^mirrors/mirror/(?P[-.\w]+)/edit/$', - views.mirror_edit, name='mirror_edit'), + path('', views.repo_list, name='repo_list'), + path('/', views.repo_detail, name='repo_detail'), + path('/toggle_enabled/', views.repo_toggle_enabled, name='repo_toggle_enabled'), # noqa + path('/toggle_security/', views.repo_toggle_security, name='repo_toggle_security'), # noqa + path('/edit/', views.repo_edit, name='repo_edit'), + path('/delete/', views.repo_delete, name='repo_delete'), + path('mirrors/', views.mirror_list, name='mirror_list'), + path('mirrors/mirror//', views.mirror_detail, name='mirror_detail'), # noqa + path('mirrors/mirror//edit/', views.mirror_edit, name='mirror_edit'), # noqa + path('mirrors/mirror//delete/', views.mirror_delete, name='mirror_delete'), # noqa ] diff --git a/util/urls.py b/util/urls.py index 990584c0..36661015 100644 --- a/util/urls.py +++ b/util/urls.py @@ -17,7 +17,7 @@ from __future__ import unicode_literals -from django.conf.urls import url +from django.urls import path from django.views.generic import RedirectView from util import views @@ -25,6 +25,6 @@ app_name = 'util' urlpatterns = [ - url(r'^$', RedirectView.as_view(pattern_name='util:dashboard', permanent=True)), # noqa - url(r'^dashboard/$', views.dashboard, name='dashboard'), + path('', RedirectView.as_view(pattern_name='util:dashboard', permanent=True)), # noqa + path('dashboard/', views.dashboard, name='dashboard'), ] From 167e88351e7b13f9c6a355e0413dff0df037849a Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 7 Feb 2020 00:17:05 +0000 Subject: [PATCH 02/13] python 3 / django 2.2 support --- .../create-release-and-upload-assets.yml | 10 ++--- .github/workflows/lint-and-test.yml | 2 +- INSTALL.md | 40 +++++++++-------- README.md | 27 ++++++------ TODO | 6 +-- arch/admin.py | 4 +- arch/apps.py | 4 +- arch/models.py | 6 +-- arch/serializers.py | 4 +- arch/views.py | 4 +- debian/README.Debian | 8 +--- debian/control | 22 +++++----- ...cron.daily => python3-patchman.cron.daily} | 0 ...chman.install => python3-patchman.install} | 0 ...man.postinst => python3-patchman.postinst} | 4 +- ...-patchman.prerm => python3-patchman.prerm} | 0 debian/rules | 5 ++- domains/admin.py | 4 +- domains/apps.py | 4 +- domains/models.py | 6 +-- domains/serializers.py | 4 +- domains/views.py | 4 +- hosts/admin.py | 4 +- hosts/apps.py | 4 +- hosts/forms.py | 4 +- hosts/managers.py | 4 +- hosts/models.py | 9 +--- hosts/serializers.py | 4 +- hosts/templatetags/report_alert.py | 6 +-- hosts/urls.py | 4 +- hosts/utils.py | 4 +- hosts/views.py | 4 +- manage.py | 6 +-- operatingsystems/admin.py | 4 +- operatingsystems/apps.py | 4 +- operatingsystems/forms.py | 4 +- operatingsystems/models.py | 7 +-- operatingsystems/serializers.py | 4 +- operatingsystems/urls.py | 4 +- operatingsystems/views.py | 4 +- packages/admin.py | 4 +- packages/apps.py | 4 +- packages/managers.py | 4 +- packages/models.py | 11 +---- packages/serializers.py | 4 +- packages/urls.py | 4 +- packages/utils.py | 6 +-- packages/views.py | 4 +- patchman/__init__.py | 4 +- patchman/celery.py | 4 +- patchman/receivers.py | 4 +- patchman/settings.py | 44 +++++++++++++------ patchman/signals.py | 4 +- patchman/urls.py | 4 +- patchman/wsgi.py | 9 +--- reports/admin.py | 4 +- reports/apps.py | 4 +- reports/models.py | 6 +-- reports/tasks.py | 4 +- reports/urls.py | 4 +- reports/utils.py | 4 +- reports/views.py | 4 +- repos/admin.py | 4 +- repos/apps.py | 4 +- repos/forms.py | 4 +- repos/managers.py | 4 +- repos/models.py | 7 +-- repos/serializers.py | 4 +- repos/templates/repos/repo_edit.html | 2 +- repos/templatetags/repo_buttons.py | 6 +-- repos/urls.py | 4 +- repos/utils.py | 7 +-- repos/views.py | 4 +- requirements.txt | 20 ++++----- sbin/patchman | 4 +- sbin/patchman-manage | 4 +- sbin/patchman-set-secret-key | 41 ++++++++--------- scripts/rpm-install.sh | 5 +-- scripts/rpm-post-install.sh | 4 +- setup.cfg | 30 ++++++------- setup.py | 4 +- tox.ini | 25 +++++------ util/__init__.py | 4 +- util/apps.py | 4 +- util/filterspecs.py | 7 +-- util/templates/base.html | 2 +- util/templatetags/common.py | 10 ++--- util/urls.py | 4 +- util/views.py | 4 +- 89 files changed, 235 insertions(+), 383 deletions(-) rename debian/{python-patchman.cron.daily => python3-patchman.cron.daily} (100%) rename debian/{python-patchman.install => python3-patchman.install} (100%) rename debian/{python-patchman.postinst => python3-patchman.postinst} (80%) rename debian/{python-patchman.prerm => python3-patchman.prerm} (100%) diff --git a/.github/workflows/create-release-and-upload-assets.yml b/.github/workflows/create-release-and-upload-assets.yml index 1995bda8..285d01bc 100644 --- a/.github/workflows/create-release-and-upload-assets.yml +++ b/.github/workflows/create-release-and-upload-assets.yml @@ -50,7 +50,7 @@ jobs: git config user.name 'Marcus Furlong' - name: Install dependencies run: | - sudo apt -y install python-setuptools debhelper dh-exec dh-python git-buildpackage + sudo apt -y install python3-setuptools debhelper dh-exec dh-python git-buildpackage - name: Update repo version if required env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -143,14 +143,12 @@ jobs: needs: update-version-and-changelog runs-on: ubuntu-latest container: - image: centos:7 + image: centos:8 steps: - name: Install build dependencies run: | - yum -y install epel-release - yum -y install https://repo.ius.io/ius-release-el7.rpm - yum makecache - yum -y install rpm-build python-setuptools git222 + dnf -y install epel-release + dnf -y install rpm-build python-setuptools git - uses: actions/checkout@v2 with: fetch-depth: 0 diff --git a/.github/workflows/lint-and-test.yml b/.github/workflows/lint-and-test.yml index 684b4eb1..f971a292 100644 --- a/.github/workflows/lint-and-test.yml +++ b/.github/workflows/lint-and-test.yml @@ -8,7 +8,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [2.7] + python-version: [3.6, 3.7, 3.8] steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python-version }} diff --git a/INSTALL.md b/INSTALL.md index 55cd9f28..7d58767f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -5,20 +5,20 @@ mysql or postgresql instead, see the database configuration section. ## Supported Install Options - - [Ubuntu 18.04](#ubuntu-1804-bionic) + - [Ubuntu 20.04](#ubuntu-2004-bionic) - [Debian 10](#debian-10-buster) - [CentOS 7](#centos-7) - [virtualenv + pip](#virtualenv--pip) - [Source](#source) -### Ubuntu 18.04 (bionic) +### Ubuntu 20.04 (focal) ```shell apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0412F522 -echo "deb https://repo.openbytes.ie/ubuntu bionic main" > /etc/apt/sources.list.d/patchman.list +echo "deb https://repo.openbytes.ie/ubuntu focal main" > /etc/apt/sources.list.d/patchman.list apt update -apt -y install python-patchman patchman-client +apt -y install python3-patchman patchman-client patchman-manage createsuperuser ``` @@ -28,7 +28,8 @@ patchman-manage createsuperuser apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 0412F522 echo "deb https://repo.openbytes.ie/debian buster main" > /etc/apt/sources.list.d/patchman.list apt update -apt -y install python-patchman patchman-client +apt -t buster-backports -y install python3-django +apt -y install python3-patchman patchman-client patchman-manage createsuperuser ``` @@ -54,8 +55,8 @@ patchman-manage createsuperuser TBD - not working yet ```shell -apt -y install gcc libxml2-dev libxslt1-dev virtualenv python-dev zlib1g-dev # (debian/ubuntu) -yum -y install gcc libxml2-devel libxslt-devel python-virtualenv # (centos/rhel) +apt -y install gcc libxml2-dev libxslt1-dev virtualenv python3-dev zlib1g-dev # (debian/ubuntu) +yum -y install gcc libxml2-devel libxslt-devel python3-virtualenv # (centos/rhel) mkdir /srv/patchman cd /srv/patchman virtualenv . @@ -74,17 +75,18 @@ gunicorn patchman.wsgi -b 0.0.0.0:80 1. Install dependencies ```shell -apt -y install python-django-tagging python-django python-requests \ -python-django-extensions python-argparse python-defusedxml python-rpm python-debian \ -python-pygooglechart python-cracklib python-progressbar libapache2-mod-wsgi \ -python-djangorestframework apache2 python-colorama python-humanize liblzma-dev \ -python-magic python-lxml +apt -y install -t buster-backports python3-django +apt -y install python3-django-tagging python3-django-extensions +python3-djangorestframework python3-defusedxml python3-lxml \ +python3-requests python3-rpm python3-debian \ +python3-colorama python3-humanize python3-magic \ +apache2 libapache2-mod-wsgi ``` 2. Install django-bootstrap3 ```shell -pip install django-bootstrap3 +pip3 install django-bootstrap3 ``` 3. Clone git repo to e.g. /srv/patchman @@ -152,7 +154,7 @@ To configure the mysql database backend: 1. Ensure mysql-server and the python mysql bindings are installed: ```shell -apt -y install default-mysql-server python-mysqldb python-pymysql +apt -y install default-mysql-server python3-mysqldb ``` 2. Create database and users: @@ -193,7 +195,7 @@ To configure the postgresql database backend: 1. Ensure the postgresql server and the python postgres bindings are installed: ```shell -apt -y install postgresql python-psycopg2 +apt -y install postgresql python3-psycopg2 ``` 2. Create database and users: @@ -311,14 +313,14 @@ Install Celery for realtime processing of reports from clients: #### Ubuntu / Debian ```shell -apt -y install python-celery python-celery-common rabbitmq-server +apt -y install python3-celery rabbitmq-server C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman ``` #### CentOS / RHEL ```shell -yum -y install python-celery rabbitmq-server +yum -y install python3-celery rabbitmq-server systemctl restart rabbitmq-server semanage port -a -t http_port_t -p tcp 5672 C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman @@ -333,8 +335,8 @@ persistent over reboot. Memcached can optionally be run to reduce the load on the server. ```shell -apt -y install memcached python-memcache # (debian/ubuntu) -yum -y install memcached python-memcached # (centos/rhel) +apt -y install memcached python3-memcache # (debian/ubuntu) +yum -y install memcached python3-memcached # (centos/rhel) systemctl restart memcached ``` diff --git a/README.md b/README.md index eb4e3a8d..f4f9bfe2 100644 --- a/README.md +++ b/README.md @@ -92,19 +92,20 @@ optional arguments: ``` -python-django -python-django-tagging -python-django-extensions -python-django-bootstrap3 -python-djangorestframework -python-debian -python-rpm -python-progressbar -python-lxml -python-defusedxml -python-argparse -python-requests -python-humanize +python3-django +python3-django-tagging +python3-django-extensions +python3-django-bootstrap3 +python3-djangorestframework +python3-debian +python3-rpm +python3-progressbar +python3-lxml +python3-defusedxml +python3-requests +python3-colorama +python3-magic +python3-humanize ``` The server can optionally make use of celery to asynchronously process the diff --git a/TODO b/TODO index 47dd7612..a2576ec8 100644 --- a/TODO +++ b/TODO @@ -7,12 +7,8 @@ * record the history of installed packages on a host * also store package descriptions/tags/urls * check for unused repos -* rdns checks off by default * suggest names for repos with the same checksum -* helper script to change paths (e.g. /usr/lib/python2.7/dist-packages/patchman) -* process reports in background +* helper script to change paths (e.g. /usr/lib/python3/dist-packages/patchman) * Dockerfile/Dockerimage * compressed reports * modularity support -* add cronjobs to built packages -* install celery/rabbit/memcache with packages diff --git a/arch/admin.py b/arch/admin.py index 04c0a9c3..d003ca60 100644 --- a/arch/admin.py +++ b/arch/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from arch.models import PackageArchitecture, MachineArchitecture diff --git a/arch/apps.py b/arch/apps.py index 7b90e236..ff1718ea 100644 --- a/arch/apps.py +++ b/arch/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/arch/models.py b/arch/models.py index d1b92166..a19834be 100644 --- a/arch/models.py +++ b/arch/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,13 +15,9 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models -@python_2_unicode_compatible class Architecture(models.Model): name = models.CharField(unique=True, max_length=255) diff --git a/arch/serializers.py b/arch/serializers.py index a6b60ce1..916b9f83 100644 --- a/arch/serializers.py +++ b/arch/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from arch.models import PackageArchitecture, MachineArchitecture diff --git a/arch/views.py b/arch/views.py index 6b1cee1b..7ad05ec5 100644 --- a/arch/views.py +++ b/arch/views.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import viewsets, permissions from arch.models import PackageArchitecture, MachineArchitecture diff --git a/debian/README.Debian b/debian/README.Debian index 7d8ba73d..f93646dd 100644 --- a/debian/README.Debian +++ b/debian/README.Debian @@ -6,10 +6,6 @@ Configuration of patchman under Ubuntu/Debian sqlite3 backend --------------- - Install the python sqlite bindings: - - $ apt -y install python-pysqlite2 - Update /etc/patchman/local_settings.py: DATABASES = { @@ -31,7 +27,7 @@ Configuration of patchman under Ubuntu/Debian Install mysql-server and the python mysql bindings: - $ apt -y install mysql-server python-mysqldb + $ apt -y install mysql-server python3-mysqldb Create database and users: @@ -62,7 +58,7 @@ Configuration of patchman under Ubuntu/Debian Install postgresql server and the python postgres bindings: - $ apt -y install postgresql python-psycopg2 + $ apt -y install postgresql python3-psycopg2 Create database and users: diff --git a/debian/control b/debian/control index 1bc03774..4c344b28 100644 --- a/debian/control +++ b/debian/control @@ -3,23 +3,23 @@ Section: python Priority: optional Maintainer: Marcus Furlong Uploaders: Marcus Furlong -Build-Depends: debhelper (>=9.0.0), python (>= 2.7), dh-python, dh-exec -Standards-Version: 3.9.7 +Build-Depends: debhelper (>=12), python3 (>= 3.6), dh-python, dh-exec +Standards-Version: 4.3.0 Homepage: https://github.com/furlongm/patchman Vcs-Git: git://github.com/furlongm/patchman Vcs-Browser: https://github.com/furlongm/patchman -X-Python-Version: >= 2.7 +X-Python3-Version: >= 3.6 -Package: python-patchman +Package: python3-patchman Architecture: all Homepage: https://github.com/furlongm/patchman -Depends: ${misc:Depends}, python (>= 2.7), python-django (>= 1.11.0), - python-django-tagging, python-debian, python-rpm, python-progressbar, - python-defusedxml, python-django-extensions, python-colorama, python-requests, - python-humanize, python-django-bootstrap3, python-lzma, python-humanize, - python-magic, python-memcache, python-pip, python-lxml, - python-djangorestframework, memcached, libapache2-mod-wsgi,apache2 -Suggests: python-django-celery +Depends: ${misc:Depends}, python3 (>= 3.6), python3-django (>= 2.2), + python3-django-tagging, python3-django-extensions, python3-django-bootstrap3, + python3-djangorestframework, python3-debian, python3-rpm, python3-progressbar, + python3-lxml, python3-defusedxml, python3-requests, python3-colorama, + python3-magic, python3-humanize, python3-pip, python3-memcache, memcached, + libapache2-mod-wsgi-py3, apache2 +Suggests: python3-django-celery, python3-mysqldb, python3-psycopg2 Description: Django-based patch status monitoring tool for linux systems. . Patchman provides a web interface for monitoring host package updates. diff --git a/debian/python-patchman.cron.daily b/debian/python3-patchman.cron.daily similarity index 100% rename from debian/python-patchman.cron.daily rename to debian/python3-patchman.cron.daily diff --git a/debian/python-patchman.install b/debian/python3-patchman.install similarity index 100% rename from debian/python-patchman.install rename to debian/python3-patchman.install diff --git a/debian/python-patchman.postinst b/debian/python3-patchman.postinst similarity index 80% rename from debian/python-patchman.postinst rename to debian/python3-patchman.postinst index 1a0b2bb4..b897b9d6 100644 --- a/debian/python-patchman.postinst +++ b/debian/python3-patchman.postinst @@ -4,8 +4,8 @@ if [ "$1" = "configure" ] ; then - if ! grep /usr/lib/python2.7/dist-packages/patchman /etc/apache2/conf-available/patchman.conf >/dev/null 2>&1 ; then - sed -i -e "s/^\(Define patchman_pythonpath\).*/\1 \/usr\/lib\/python2.7\/dist-packages/" \ + if ! grep /usr/lib/python3/dist-packages/patchman /etc/apache2/conf-available/patchman.conf >/dev/null 2>&1 ; then + sed -i -e "s/^\(Define patchman_pythonpath\).*/\1 \/usr\/lib\/python3\/dist-packages/" \ /etc/apache2/conf-available/patchman.conf fi diff --git a/debian/python-patchman.prerm b/debian/python3-patchman.prerm similarity index 100% rename from debian/python-patchman.prerm rename to debian/python3-patchman.prerm diff --git a/debian/rules b/debian/rules index 76d7bdc4..63a1916b 100755 --- a/debian/rules +++ b/debian/rules @@ -2,13 +2,14 @@ # -*- makefile -*- clean:: - rm -rf build MANIFEST dist .pybuild + find -name *.pyc -exec rm {} \; + rm -rf debian/python3-patchman build MANIFEST dist .pybuild patchman.egg-info .tox dh_clean export PYBUILD_NAME=patchman %: - dh $@ --with python2 --buildsystem=pybuild + dh $@ --with python3 --buildsystem=pybuild override_dh_auto_test: true diff --git a/domains/admin.py b/domains/admin.py index 62356818..5bdc7804 100644 --- a/domains/admin.py +++ b/domains/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from domains.models import Domain diff --git a/domains/apps.py b/domains/apps.py index 076f0678..1a1c4c1f 100644 --- a/domains/apps.py +++ b/domains/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/domains/models.py b/domains/models.py index c6d0f88c..cde07342 100644 --- a/domains/models.py +++ b/domains/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,13 +15,9 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models -@python_2_unicode_compatible class Domain(models.Model): name = models.CharField(max_length=255, unique=True) diff --git a/domains/serializers.py b/domains/serializers.py index 47447826..27b188b9 100644 --- a/domains/serializers.py +++ b/domains/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from domains.models import Domain diff --git a/domains/views.py b/domains/views.py index ae333583..f3e38837 100644 --- a/domains/views.py +++ b/domains/views.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import viewsets, permissions from domains.models import Domain diff --git a/hosts/admin.py b/hosts/admin.py index 2b9e52c2..f52c47be 100644 --- a/hosts/admin.py +++ b/hosts/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from hosts.models import Host, HostRepo diff --git a/hosts/apps.py b/hosts/apps.py index 48c80b18..7d839967 100644 --- a/hosts/apps.py +++ b/hosts/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/hosts/forms.py b/hosts/forms.py index 5276a66d..60a3e0c2 100644 --- a/hosts/forms.py +++ b/hosts/forms.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.forms import ModelForm, TextInput from hosts.models import Host diff --git a/hosts/managers.py b/hosts/managers.py index 469b2a5a..6f2f7f4c 100644 --- a/hosts/managers.py +++ b/hosts/managers.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.db import models diff --git a/hosts/models.py b/hosts/models.py index effa34f5..dc428986 100644 --- a/hosts/models.py +++ b/hosts/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,9 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models, IntegrityError, DatabaseError, transaction from django.db.models import Q from django.urls import reverse @@ -39,13 +36,12 @@ from hosts.utils import update_rdns, remove_reports -@python_2_unicode_compatible class Host(models.Model): hostname = models.CharField(max_length=255, unique=True) ipaddress = models.GenericIPAddressField() reversedns = models.CharField(max_length=255, blank=True, null=True) - check_dns = models.BooleanField(default=True) + check_dns = models.BooleanField(default=False) os = models.ForeignKey(OS, on_delete=models.CASCADE) kernel = models.CharField(max_length=255) arch = models.ForeignKey(MachineArchitecture, on_delete=models.CASCADE) @@ -317,7 +313,6 @@ def find_kernel_updates(self, kernel_packages, repo_packages): return update_ids -@python_2_unicode_compatible class HostRepo(models.Model): host = models.ForeignKey(Host, on_delete=models.CASCADE) repo = models.ForeignKey(Repository, on_delete=models.CASCADE) diff --git a/hosts/serializers.py b/hosts/serializers.py index b503fcd6..034d7840 100644 --- a/hosts/serializers.py +++ b/hosts/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from hosts.models import Host, HostRepo diff --git a/hosts/templatetags/report_alert.py b/hosts/templatetags/report_alert.py index b9106bec..d27b322c 100644 --- a/hosts/templatetags/report_alert.py +++ b/hosts/templatetags/report_alert.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,15 +15,13 @@ # You should have received a copy of the GNU General Public License # along with Patchman If not, see . -from __future__ import unicode_literals - from datetime import timedelta from django.conf import settings from django.template import Library from django.utils.html import format_html -from django.contrib.staticfiles.templatetags.staticfiles import static +from django.templatetags.static import static from django.utils import timezone register = Library() diff --git a/hosts/urls.py b/hosts/urls.py index 7343225a..e3591dbf 100644 --- a/hosts/urls.py +++ b/hosts/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from hosts import views diff --git a/hosts/utils.py b/hosts/utils.py index 4f3dd628..9eb737c6 100644 --- a/hosts/utils.py +++ b/hosts/utils.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from socket import gethostbyaddr, gaierror, herror from django.db import DatabaseError diff --git a/hosts/views.py b/hosts/views.py index 7ef464c3..6ea5640b 100644 --- a/hosts/views.py +++ b/hosts/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.shortcuts import get_object_or_404, render, redirect from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger diff --git a/manage.py b/manage.py index 4e001449..14270356 100755 --- a/manage.py +++ b/manage.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -16,8 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - import os import sys diff --git a/operatingsystems/admin.py b/operatingsystems/admin.py index 557a310f..cf01c118 100644 --- a/operatingsystems/admin.py +++ b/operatingsystems/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from operatingsystems.models import OS, OSGroup diff --git a/operatingsystems/apps.py b/operatingsystems/apps.py index f0270cb2..e151aeb6 100644 --- a/operatingsystems/apps.py +++ b/operatingsystems/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/operatingsystems/forms.py b/operatingsystems/forms.py index 95ea20ca..a0bbab33 100644 --- a/operatingsystems/forms.py +++ b/operatingsystems/forms.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.forms import ModelForm, ModelMultipleChoiceField from django.contrib.admin.widgets import FilteredSelectMultiple diff --git a/operatingsystems/models.py b/operatingsystems/models.py index ecf8f82e..383da471 100644 --- a/operatingsystems/models.py +++ b/operatingsystems/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,16 +15,12 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models from django.urls import reverse from repos.models import Repository -@python_2_unicode_compatible class OSGroup(models.Model): name = models.CharField(max_length=255, unique=True) @@ -42,7 +38,6 @@ def get_absolute_url(self): return reverse('operatingsystems:osgroup_detail', args=[str(self.id)]) -@python_2_unicode_compatible class OS(models.Model): name = models.CharField(max_length=255, unique=True) diff --git a/operatingsystems/serializers.py b/operatingsystems/serializers.py index 8a15b82c..9fae8231 100644 --- a/operatingsystems/serializers.py +++ b/operatingsystems/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from operatingsystems.models import OS, OSGroup diff --git a/operatingsystems/urls.py b/operatingsystems/urls.py index e49edebc..da45299c 100644 --- a/operatingsystems/urls.py +++ b/operatingsystems/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from operatingsystems import views diff --git a/operatingsystems/views.py b/operatingsystems/views.py index 5e234046..a1af28c8 100644 --- a/operatingsystems/views.py +++ b/operatingsystems/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.shortcuts import get_object_or_404, render, redirect from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger diff --git a/packages/admin.py b/packages/admin.py index c7514d01..cd92ef2a 100644 --- a/packages/admin.py +++ b/packages/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from packages.models import Package, PackageName, \ PackageUpdate, Erratum, ErratumReference diff --git a/packages/apps.py b/packages/apps.py index adbc6215..7b9f1292 100644 --- a/packages/apps.py +++ b/packages/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/packages/managers.py b/packages/managers.py index 25f0fd0a..a1a6afa3 100644 --- a/packages/managers.py +++ b/packages/managers.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.db import models diff --git a/packages/models.py b/packages/models.py index 789ec776..bc5c0bc0 100644 --- a/packages/models.py +++ b/packages/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,9 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models from django.urls import reverse @@ -31,7 +28,6 @@ from packages.managers import PackageManager -@python_2_unicode_compatible class PackageName(models.Model): name = models.CharField(unique=True, max_length=255) @@ -48,7 +44,6 @@ def get_absolute_url(self): return reverse('packages:package_detail', args=[self.name]) -@python_2_unicode_compatible class Package(models.Model): RPM = 'R' @@ -149,7 +144,6 @@ def repo_count(self): mirror__packages=self).distinct().count() -@python_2_unicode_compatible class PackageString(models.Model): class Meta(object): @@ -195,7 +189,6 @@ def __hash__(self): return hash(self.__key()) -@python_2_unicode_compatible class PackageUpdate(models.Model): oldpackage = models.ForeignKey(Package, @@ -219,7 +212,6 @@ def __str__(self): update_type) -@python_2_unicode_compatible class ErratumReference(models.Model): url = models.URLField(max_length=255) @@ -228,7 +220,6 @@ def __str__(self): return self.url -@python_2_unicode_compatible class Erratum(models.Model): name = models.CharField(max_length=255) diff --git a/packages/serializers.py b/packages/serializers.py index 06b6eede..767d4f2b 100644 --- a/packages/serializers.py +++ b/packages/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from packages.models import PackageName, Package, PackageUpdate, \ diff --git a/packages/urls.py b/packages/urls.py index 322cb121..affa9033 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from packages import views diff --git a/packages/utils.py b/packages/utils.py index 7f72baf6..d6d68658 100644 --- a/packages/utils.py +++ b/packages/utils.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - import re from defusedxml.lxml import _etree as etree @@ -109,7 +107,7 @@ def download_errata(): def parse_errata_checksum(data): """ Parse the errata checksum and return the bz2 checksum """ - for line in data.splitlines(): + for line in data.decode('utf-8').splitlines(): if line.endswith('errata.latest.xml.bz2'): return line.split()[0] diff --git a/packages/views.py b/packages/views.py index 68fa5e26..73887c97 100644 --- a/packages/views.py +++ b/packages/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.shortcuts import get_object_or_404, render from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger diff --git a/patchman/__init__.py b/patchman/__init__.py index 09360f94..64ec7db1 100644 --- a/patchman/__init__.py +++ b/patchman/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,6 +14,4 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals, absolute_import - from .receivers import * # noqa diff --git a/patchman/celery.py b/patchman/celery.py index 37e46606..0f6ae245 100644 --- a/patchman/celery.py +++ b/patchman/celery.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals, absolute_import - import os from celery import Celery diff --git a/patchman/receivers.py b/patchman/receivers.py index 52548f18..8190f9a2 100644 --- a/patchman/receivers.py +++ b/patchman/receivers.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals, print_function - from colorama import init, Fore, Style from django.dispatch import receiver diff --git a/patchman/settings.py b/patchman/settings.py index 422aa035..879949b6 100644 --- a/patchman/settings.py +++ b/patchman/settings.py @@ -1,8 +1,7 @@ # Django settings for patchman project. -from __future__ import unicode_literals, absolute_import - import os +import site import sys # Build paths inside the project like this: os.path.join(BASE_DIR, ...) @@ -126,18 +125,24 @@ TEST_RUNNER = 'django.test.runner.DiscoverRunner' -try: - from .local_settings import * # noqa -except ImportError: - if sys.prefix == '/usr': - conf_path = '/etc/patchman' - else: - conf_path = os.path.join(sys.prefix, 'etc/patchman') - # if conf_path doesn't exist, try ./etc/patchman - if not os.path.isdir(conf_path): - conf_path = './etc/patchman' - local_settings = os.path.join(conf_path, 'local_settings.py') - exec(compile(open(local_settings).read(), local_settings, 'exec')) +if sys.prefix == '/usr': + conf_path = '/etc/patchman' +else: + conf_path = os.path.join(sys.prefix, 'etc/patchman') + # if sys.prefix + conf_path doesn't exist, try ./etc/patchman (source) + if not os.path.isdir(conf_path): + conf_path = './etc/patchman' + # if ./etc/patchman doesn't exist, try site.getsitepackages() (pip) + if not os.path.isdir(conf_path): + try: + sitepackages = site.getsitepackages() + except AttributeError: + # virtualenv, try site-packages in sys.path + sp = 'site-packages' + sitepackages = [s for s in sys.path if s.endswith(sp)][0] + conf_path = os.path.join(sitepackages, 'etc/patchman') +local_settings = os.path.join(conf_path, 'local_settings.py') +exec(compile(open(local_settings).read(), local_settings, 'exec')) MANAGERS = ADMINS INSTALLED_APPS = DEFAULT_APPS + THIRD_PARTY_APPS + LOCAL_APPS @@ -149,3 +154,14 @@ STATICFILES_DIRS = [os.path.abspath(os.path.join(BASE_DIR, 'patchman/static'))] # noqa STATIC_ROOT = os.path.abspath(os.path.join(BASE_DIR, 'run/static')) STATIC_URL = '/static/' + MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + ] + STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' # noqa diff --git a/patchman/signals.py b/patchman/signals.py index 3d11dd12..3c32b4ff 100644 --- a/patchman/signals.py +++ b/patchman/signals.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.dispatch import Signal progress_info_s = Signal(providing_args=['ptext', 'plength']) diff --git a/patchman/urls.py b/patchman/urls.py index e8a24c01..6cfbbab8 100644 --- a/patchman/urls.py +++ b/patchman/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of patchman # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with If not, see -from __future__ import unicode_literals - from django.conf.urls import include, handler404, handler500 # noqa from django.conf import settings from django.contrib import admin diff --git a/patchman/wsgi.py b/patchman/wsgi.py index df079520..4f52ecce 100644 --- a/patchman/wsgi.py +++ b/patchman/wsgi.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - import os from django.core.wsgi import get_wsgi_application @@ -23,8 +21,5 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') # noqa from django.conf import settings -application = get_wsgi_application() -if hasattr(settings, 'RUN_GUNICORN') and settings.RUN_GUNICORN: - from whitenoise.django import DjangoWhiteNoise - application = DjangoWhiteNoise(application) +application = get_wsgi_application() diff --git a/reports/admin.py b/reports/admin.py index 7b10fea8..a7e2339d 100644 --- a/reports/admin.py +++ b/reports/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from reports.models import Report diff --git a/reports/apps.py b/reports/apps.py index 19f1ef02..ef53b3cd 100644 --- a/reports/apps.py +++ b/reports/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/reports/models.py b/reports/models.py index ade3b118..ee0947b5 100644 --- a/reports/models.py +++ b/reports/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,9 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models, IntegrityError, DatabaseError, transaction from django.urls import reverse @@ -30,7 +27,6 @@ from socket import gethostbyaddr, herror -@python_2_unicode_compatible class Report(models.Model): created = models.DateTimeField(auto_now_add=True) diff --git a/reports/tasks.py b/reports/tasks.py index 81a55001..052cea85 100755 --- a/reports/tasks.py +++ b/reports/tasks.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals, absolute_import - from django.conf import settings from reports.models import Report diff --git a/reports/urls.py b/reports/urls.py index 3968a9a8..c396c16b 100644 --- a/reports/urls.py +++ b/reports/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from reports import views diff --git a/reports/utils.py b/reports/utils.py index c5b8e463..9171efc0 100644 --- a/reports/utils.py +++ b/reports/utils.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - import re from django.db import IntegrityError, DatabaseError, transaction diff --git a/reports/views.py b/reports/views.py index df927e5e..dae04ef6 100644 --- a/reports/views.py +++ b/reports/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.http import HttpResponse, Http404 from django.views.decorators.csrf import csrf_exempt from django.shortcuts import get_object_or_404, render, redirect diff --git a/repos/admin.py b/repos/admin.py index ae193d0f..0bea1e52 100644 --- a/repos/admin.py +++ b/repos/admin.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.contrib import admin from repos.models import Repository, Mirror, MirrorPackage diff --git a/repos/apps.py b/repos/apps.py index ab6a8ba8..31ca077c 100644 --- a/repos/apps.py +++ b/repos/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/repos/forms.py b/repos/forms.py index b5a5ece3..ad000453 100644 --- a/repos/forms.py +++ b/repos/forms.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.forms import ModelForm, ModelMultipleChoiceField, TextInput, \ Form, ModelChoiceField, ValidationError from django.contrib.admin.widgets import FilteredSelectMultiple diff --git a/repos/managers.py b/repos/managers.py index 2cd4994c..f0fe85e6 100644 --- a/repos/managers.py +++ b/repos/managers.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.db import models diff --git a/repos/models.py b/repos/models.py index 11cac4a5..b3c3669b 100644 --- a/repos/models.py +++ b/repos/models.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,9 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - -from django.utils.encoding import python_2_unicode_compatible from django.db import models from django.urls import reverse @@ -29,7 +26,6 @@ from patchman.signals import info_message, warning_message, error_message -@python_2_unicode_compatible class Repository(models.Model): RPM = 'R' @@ -119,7 +115,6 @@ def enable(self): mirror.save() -@python_2_unicode_compatible class Mirror(models.Model): repo = models.ForeignKey(Repository, on_delete=models.CASCADE) diff --git a/repos/serializers.py b/repos/serializers.py index d5b506a0..52bd6e13 100644 --- a/repos/serializers.py +++ b/repos/serializers.py @@ -1,4 +1,4 @@ -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from rest_framework import serializers from repos.models import Repository, Mirror, MirrorPackage diff --git a/repos/templates/repos/repo_edit.html b/repos/templates/repos/repo_edit.html index 2daa57ea..0a160d8e 100644 --- a/repos/templates/repos/repo_edit.html +++ b/repos/templates/repos/repo_edit.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% load common bootstrap3 staticfiles %} +{% load common bootstrap3 static %} {% block extrahead %} diff --git a/repos/templatetags/repo_buttons.py b/repos/templatetags/repo_buttons.py index 9926a3d6..772165f7 100644 --- a/repos/templatetags/repo_buttons.py +++ b/repos/templatetags/repo_buttons.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,10 +15,8 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.template import Library -from django.contrib.staticfiles.templatetags.staticfiles import static +from django.templatetags.static import static from django.utils.html import format_html register = Library() diff --git a/repos/urls.py b/repos/urls.py index aa52a25a..b8806aa8 100644 --- a/repos/urls.py +++ b/repos/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from repos import views diff --git a/repos/utils.py b/repos/utils.py index 1b9921d4..2ca47484 100644 --- a/repos/utils.py +++ b/repos/utils.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - import re try: import lzma @@ -34,7 +32,6 @@ from django.conf import settings from django.db import transaction from django.db.models import Q -from django.utils.six import text_type from packages.models import Package, PackageName, PackageString from arch.models import PackageArchitecture @@ -134,7 +131,7 @@ def update_mirror_packages(mirror, packages): def get_primary_url(mirror_url, data): - if isinstance(data, text_type): + if isinstance(data, str): if data.startswith('Bad repo - not in list') or \ data.startswith('Invalid repo'): return None, None, None diff --git a/repos/views.py b/repos/views.py index 1fddbb88..f4ef89a4 100644 --- a/repos/views.py +++ b/repos/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.shortcuts import get_object_or_404, render, redirect from django.http import HttpResponse from django.contrib.auth.decorators import login_required diff --git a/requirements.txt b/requirements.txt index 8e788c8c..6084633f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,16 +1,16 @@ -Django==1.11.29 -django-tagging==0.4.6 -django-extensions==2.2.8 -django-bootstrap3==11.1.0 +Django==2.2.14 +django-tagging==0.5.0 +django-extensions==3.0.2 +django-bootstrap3==14.1.0 progressbar==2.5 -python-debian==0.1.36 -lxml==4.5.0 +python-debian==0.1.37 +lxml==4.5.1 defusedxml==0.6.0 chardet==3.0.4 -requests==2.22.0 +requests==2.24.0 colorama==0.4.3 -djangorestframework==3.9.3 -humanize==1.0.0 +djangorestframework==3.11.0 +humanize==2.5.0 version-utils==0.3.0 -python-magic==0.4.15 +python-magic==0.4.18 python-memcached==1.59 diff --git a/sbin/patchman b/sbin/patchman index 41cc56e1..550508e8 100755 --- a/sbin/patchman +++ b/sbin/patchman @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # diff --git a/sbin/patchman-manage b/sbin/patchman-manage index d7f077a9..5eca8f95 100755 --- a/sbin/patchman-manage +++ b/sbin/patchman-manage @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # diff --git a/sbin/patchman-set-secret-key b/sbin/patchman-set-secret-key index fe2b3260..95d91b9e 100755 --- a/sbin/patchman-set-secret-key +++ b/sbin/patchman-set-secret-key @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -# Copyright 2016 Marcus Furlong +# Copyright 2016-2020 Marcus Furlong # # This file is part of Patchman. # @@ -16,35 +16,36 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see +import fileinput import os -import re +import site import sys -import codecs from random import choice -from tempfile import NamedTemporaryFile -from shutil import copy +from string import ascii_letters, digits if sys.prefix == '/usr': conf_path = '/etc/patchman' else: conf_path = os.path.join(sys.prefix, 'etc/patchman') - # if conf_path doesn't exist, try ./etc/patchman + # if sys.prefix + conf_path doesn't exist, try ./etc/patchman (source) if not os.path.isdir(conf_path): conf_path = './etc/patchman' + # if ./etc/patchman doesn't exist, try site.getsitepackages() (pip) + if not os.path.isdir(conf_path): + try: + sitepackages = site.getsitepackages() + except AttributeError: + # virtualenv, try site-packages in sys.path + sp = 'site-packages' + sitepackages = [s for s in sys.path if s.endswith(sp)][0] + conf_path = os.path.join(sitepackages, 'etc/patchman') local_settings = os.path.join(conf_path, 'local_settings.py') -chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)' -settings_contents = codecs.open(local_settings, 'r', encoding='utf-8').read() +chars = ascii_letters + digits + '!@#$%^&*(-_=+)' secret_key = ''.join([choice(chars) for i in range(50)]) -settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents) - -f = NamedTemporaryFile(delete=False) -temp = f.name -f.close() - -fh = codecs.open(temp, 'w+b', encoding='utf-8') -fh.write(settings_contents) -fh.close() -copy(temp, local_settings) -os.remove(temp) +for line in fileinput.input(local_settings, inplace=True): + if line.startswith('SECRET_KEY'): + print('SECRET_KEY = \'' + secret_key + '\'') + else: + print(line.rstrip()) diff --git a/scripts/rpm-install.sh b/scripts/rpm-install.sh index 733a9376..73b62783 100644 --- a/scripts/rpm-install.sh +++ b/scripts/rpm-install.sh @@ -4,7 +4,7 @@ # # This is what dist.py normally does. -python setup.py install --root=${RPM_BUILD_ROOT} --record="INSTALLED_FILES" +python3 setup.py install --single-version-externally-managed --root=${RPM_BUILD_ROOT} --record="INSTALLED_FILES" # Sort the filelist so that directories appear before files. This avoids # duplicate filename problems on some systems. @@ -19,5 +19,4 @@ for i in `cat INSTALLED_FILES`; do done cat DIRS > INSTALLED_FILES -# Make sure we match foo.pyo and foo.pyc along with foo.py (but only once each) -sed -e "/\.py[co]$/d" -e "s/\.py$/.py*/" -e '/\/etc\//s|^|%config(noreplace) |' FILES >>INSTALLED_FILES +sed -e '/\/etc\//s|^|%config(noreplace) |' FILES >>INSTALLED_FILES diff --git a/scripts/rpm-post-install.sh b/scripts/rpm-post-install.sh index 4fc23608..787baaac 100644 --- a/scripts/rpm-post-install.sh +++ b/scripts/rpm-post-install.sh @@ -4,8 +4,8 @@ if [ ! -e /etc/httpd/conf.d/patchman.conf ] ; then cp /etc/patchman/apache.conf.example /etc/httpd/conf.d/patchman.conf fi -if ! grep /usr/lib/python2.7/site-packages /etc/httpd/conf.d/patchman.conf >/dev/null 2>&1 ; then - sed -i -e "s/^\(Define patchman_pythonpath\).*/\1 \/usr\/lib\/python2.7\/site-packages/" \ +if ! grep /usr/lib64/python3.6/site-packages /etc/httpd/conf.d/patchman.conf >/dev/null 2>&1 ; then + sed -i -e "s/^\(Define patchman_pythonpath\).*/\1 \/usr\/lib64\/python3.6\/site-packages/" \ /etc/httpd/conf.d/patchman.conf fi diff --git a/setup.cfg b/setup.cfg index 408f38f2..c8114cef 100644 --- a/setup.cfg +++ b/setup.cfg @@ -2,20 +2,20 @@ doc_files = README.md AUTHORS COPYING INSTALL.md install-script = scripts/rpm-install.sh post-install = scripts/rpm-post-install.sh -requires = python >= 2.7 - python-django >= 1.11.21 - python-django-extensions - python-django-tagging - python-django-bootstrap3 - python-django-rest-framework - python-requests - python-colorama - python-magic - python-progressbar - /usr/lib64/python2.7/site-packages/rpm - python-debian - python-lxml - python-defusedxml - python-humanize +requires = python36 >= 3.6 + python3-django >= 2.2.9 + python3-django-tagging + python3-django-extensions + python3-django-bootstrap3 + python3-django-rest-framework + python3-debian + python3-rpm + python3-progressbar + python3-lxml + python3-defusedxml + python3-requests + python3-colorama + python3-magic + python3-humanize httpd mod_wsgi diff --git a/setup.py b/setup.py index 19c50f75..d983db0f 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # diff --git a/tox.ini b/tox.ini index d1ee88a0..db38b677 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,12 @@ [tox] skipsdist = True envlist = - py27 - py27-flake8 py36 py36-flake8 + py37 + py37-flake8 + py38 + py38-flake8 [testenv] deps = @@ -19,20 +21,17 @@ deps = commands = flake8 exclude = .venv,.git,.tox,dist,doc,*lib/python*,*egg,build,*migrations* -[testenv:py27] -basepython = python2.7 -deps = {[testenv]deps} - -[testenv:py36] -basepython = python2.7 -deps = {[testenv]deps} +[testenv:py36-flake8] +basepython = python3.6 +deps = {[flake8]deps} +commands = {[flake8]commands} -[testenv:py27-flake8] -basepython = python2.7 +[testenv:py37-flake8] +basepython = python3.7 deps = {[flake8]deps} commands = {[flake8]commands} -[testenv:py36-flake8] -basepython = python3.6 +[testenv:py38-flake8] +basepython = python3.8 deps = {[flake8]deps} commands = {[flake8]commands} diff --git a/util/__init__.py b/util/__init__.py index c6119226..af630331 100644 --- a/util/__init__.py +++ b/util/__init__.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals, print_function - import sys import requests import bz2 diff --git a/util/apps.py b/util/apps.py index 6fd865ca..2c1f7bab 100644 --- a/util/apps.py +++ b/util/apps.py @@ -1,4 +1,4 @@ -# Copyright 2019 Marcus Furlong +# Copyright 2019-2020 Marcus Furlong # # This file is part of Patchman. # @@ -14,8 +14,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/util/filterspecs.py b/util/filterspecs.py index 05a3292e..ec6e849e 100644 --- a/util/filterspecs.py +++ b/util/filterspecs.py @@ -1,5 +1,5 @@ # Copyright 2010 VPAC -# Copyright 2016 Marcus Furlong +# Copyright 2020 Marcus Furlong # # This file is part of Patchman. # @@ -16,9 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman If not, see . -from __future__ import unicode_literals - -from django.utils.six import text_type from django.utils.safestring import mark_safe from django.db.models.query import QuerySet from operator import itemgetter @@ -43,7 +40,7 @@ def __init__(self, request, name, filters, header=''): if isinstance(filters, QuerySet): f = {} for i in filters: - if isinstance(i, text_type): + if isinstance(i, str): f[str(i)] = str(i) else: f[i.pk] = str(i) diff --git a/util/templates/base.html b/util/templates/base.html index 2b16364f..25dc0578 100644 --- a/util/templates/base.html +++ b/util/templates/base.html @@ -5,7 +5,7 @@ {% load bootstrap3 %} {% bootstrap_css %} {% bootstrap_javascript jquery=1 %} - {% load staticfiles %} + {% load static %} {% block page_title %}{% endblock %} diff --git a/util/templatetags/common.py b/util/templatetags/common.py index 528546ba..b1d8eb41 100644 --- a/util/templatetags/common.py +++ b/util/templatetags/common.py @@ -1,5 +1,5 @@ # Copyright 2010 VPAC -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -16,8 +16,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman If not, see . -from __future__ import unicode_literals - from humanize import naturaltime from datetime import datetime, timedelta @@ -25,8 +23,8 @@ from django.template import Library from django.template.loader import get_template from django.utils.html import format_html -from django.contrib.staticfiles.templatetags.staticfiles import static -from django.core.paginator import QuerySetPaginator, Paginator +from django.templatetags.static import static +from django.core.paginator import Paginator try: from urllib.parse import urlencode @@ -83,7 +81,7 @@ def gen_table(object_list, template_name=None): @register.simple_tag def object_count(page): - if isinstance(page.paginator, (QuerySetPaginator, Paginator)): + if isinstance(page.paginator, Paginator): if page.paginator.count == 1: name = page.paginator.object_list.model._meta.verbose_name else: diff --git a/util/urls.py b/util/urls.py index 36661015..3fa9fe55 100644 --- a/util/urls.py +++ b/util/urls.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from django.urls import path from django.views.generic import RedirectView diff --git a/util/views.py b/util/views.py index 361378ea..dc842f68 100644 --- a/util/views.py +++ b/util/views.py @@ -1,5 +1,5 @@ # Copyright 2012 VPAC, http://www.vpac.org -# Copyright 2013-2016 Marcus Furlong +# Copyright 2013-2020 Marcus Furlong # # This file is part of Patchman. # @@ -15,8 +15,6 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -from __future__ import unicode_literals - from datetime import datetime, timedelta from django.conf import settings From 020a42edee4db4e347445cacbc39baef8718b246 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 24 Jul 2020 19:44:40 -0400 Subject: [PATCH 03/13] switch to dnf from yum --- INSTALL.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 7d58767f..f3ae2de3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -43,9 +43,9 @@ baseurl=https://repo.openbytes.ie/yum enabled=1 gpgcheck=0 EOF -yum install -y epel-release -yum makecache -yum install -y patchman patchman-client +dnf install -y epel-release +dnf makecache +dnf install -y patchman patchman-client systemctl restart httpd patchman-manage createsuperuser ``` @@ -56,7 +56,7 @@ TBD - not working yet ```shell apt -y install gcc libxml2-dev libxslt1-dev virtualenv python3-dev zlib1g-dev # (debian/ubuntu) -yum -y install gcc libxml2-devel libxslt-devel python3-virtualenv # (centos/rhel) +dnf -y install gcc libxml2-devel libxslt-devel python3-virtualenv # (centos/rhel) mkdir /srv/patchman cd /srv/patchman virtualenv . @@ -336,7 +336,7 @@ Memcached can optionally be run to reduce the load on the server. ```shell apt -y install memcached python3-memcache # (debian/ubuntu) -yum -y install memcached python3-memcached # (centos/rhel) +dnf -y install memcached python3-memcached # (centos/rhel) systemctl restart memcached ``` From cb5f613fbef3fc18978a320290b3948c20ab2146 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 24 Jul 2020 19:45:58 -0400 Subject: [PATCH 04/13] switch from rabbit to redis for celery --- INSTALL.md | 8 ++++---- patchman/settings.py | 6 +----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index f3ae2de3..e3784e6d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -313,16 +313,16 @@ Install Celery for realtime processing of reports from clients: #### Ubuntu / Debian ```shell -apt -y install python3-celery rabbitmq-server +apt -y install python3-celery redis python3-redis C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman ``` #### CentOS / RHEL ```shell -yum -y install python3-celery rabbitmq-server -systemctl restart rabbitmq-server -semanage port -a -t http_port_t -p tcp 5672 +dnf -y install python3-celery redis python3-redis +systemctl restart redis-server +semanage port -a -t http_port_t -p tcp 6379 C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman ``` diff --git a/patchman/settings.py b/patchman/settings.py index 879949b6..dc2a2ccd 100644 --- a/patchman/settings.py +++ b/patchman/settings.py @@ -104,11 +104,7 @@ THIRD_PARTY_APPS += ['celery'] CELERY_IMPORTS = ['reports.tasks'] USE_ASYNC_PROCESSING = True - BROKER_HOST = 'localhost' - BROKER_PORT = 5672 - BROKER_USER = 'guest' - BROKER_PASSWORD = 'guest' - BROKER_VHOST = '/' + BROKER_URL = 'redis://localhost:6379/0' LOGIN_REDIRECT_URL = '/patchman/' LOGOUT_REDIRECT_URL = '/patchman/login/' From b4f67a4add30283010e40b769a98d4e941d2d6d7 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 24 Jul 2020 19:46:16 -0400 Subject: [PATCH 05/13] add celery context for task --- reports/tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reports/tasks.py b/reports/tasks.py index 052cea85..788c9750 100755 --- a/reports/tasks.py +++ b/reports/tasks.py @@ -21,8 +21,9 @@ if settings.USE_ASYNC_PROCESSING: from celery.task import task + from patchman.celery import app - @task() + @app.task() def process_report(report_id): report = Report.objects.get(id=report_id) report.process(verbose=True) From 73aabd06000c19c4b152540cca49980691a5d871 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 24 Jul 2020 19:48:04 -0400 Subject: [PATCH 06/13] consistent argument ordering --- INSTALL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index e3784e6d..f3b78ec8 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -43,9 +43,9 @@ baseurl=https://repo.openbytes.ie/yum enabled=1 gpgcheck=0 EOF -dnf install -y epel-release +dnf -y install epel-release dnf makecache -dnf install -y patchman patchman-client +dnf -y install patchman patchman-client systemctl restart httpd patchman-manage createsuperuser ``` From d8a802d9db4111bd5948736e0fcc18851e26ed66 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Thu, 30 Jul 2020 00:20:03 -0400 Subject: [PATCH 07/13] update installation instructions --- INSTALL.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index f3b78ec8..1234f0da 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -70,17 +70,15 @@ gunicorn patchman.wsgi -b 0.0.0.0:80 ### Source -#### Ubuntu 18.04 (bionic) +#### Ubuntu 20.04 (focal) 1. Install dependencies ```shell -apt -y install -t buster-backports python3-django -apt -y install python3-django-tagging python3-django-extensions -python3-djangorestframework python3-defusedxml python3-lxml \ -python3-requests python3-rpm python3-debian \ -python3-colorama python3-humanize python3-magic \ -apache2 libapache2-mod-wsgi +apt -y install python3-django python3-django-tagging python3-django-extensions \ +python3-djangorestframework python3-defusedxml python3-lxml python3-requests \ +python3-rpm python3-debian python3-colorama python3-humanize python3-magic \ +apache2 libapache2-mod-wsgi-py3 python3-pip python3-progressbar ``` 2. Install django-bootstrap3 @@ -313,8 +311,8 @@ Install Celery for realtime processing of reports from clients: #### Ubuntu / Debian ```shell -apt -y install python3-celery redis python3-redis -C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman +apt -y install python3-celery redis python3-redis python-celery-common +C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://localhost:6379/0 -E -A patchman ``` #### CentOS / RHEL @@ -323,7 +321,7 @@ C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman dnf -y install python3-celery redis python3-redis systemctl restart redis-server semanage port -a -t http_port_t -p tcp 6379 -C_FORCE_ROOT=1 celery worker --loglevel=info -E -A patchman +C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://localhost:6379/0 -E -A patchman ``` From afc350137a0fbaa26d22eb81ae0957fd342a6d94 Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Thu, 30 Jul 2020 00:49:23 -0400 Subject: [PATCH 08/13] prefer 127.0.0.1 over localhost --- INSTALL.md | 4 ++-- patchman/settings.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 1234f0da..e0e5d5cb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -312,7 +312,7 @@ Install Celery for realtime processing of reports from clients: ```shell apt -y install python3-celery redis python3-redis python-celery-common -C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://localhost:6379/0 -E -A patchman +C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://127.0.0.1:6379/0 -E -A patchman ``` #### CentOS / RHEL @@ -321,7 +321,7 @@ C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://localhost:6379/0 -E -A p dnf -y install python3-celery redis python3-redis systemctl restart redis-server semanage port -a -t http_port_t -p tcp 6379 -C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://localhost:6379/0 -E -A patchman +C_FORCE_ROOT=1 celery worker --loglevel=info -b redis://127.0.0.1:6379/0 -E -A patchman ``` diff --git a/patchman/settings.py b/patchman/settings.py index dc2a2ccd..e67ccd2a 100644 --- a/patchman/settings.py +++ b/patchman/settings.py @@ -104,7 +104,7 @@ THIRD_PARTY_APPS += ['celery'] CELERY_IMPORTS = ['reports.tasks'] USE_ASYNC_PROCESSING = True - BROKER_URL = 'redis://localhost:6379/0' + CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0' LOGIN_REDIRECT_URL = '/patchman/' LOGOUT_REDIRECT_URL = '/patchman/login/' From 931c9dbf51b79f5893304d72f15c9b45f2ba9afe Mon Sep 17 00:00:00 2001 From: Marcus Furlong Date: Fri, 7 Feb 2020 01:14:51 -0500 Subject: [PATCH 09/13] update whitenoise config --- patchman/wsgi.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/patchman/wsgi.py b/patchman/wsgi.py index 4f52ecce..fe412e50 100644 --- a/patchman/wsgi.py +++ b/patchman/wsgi.py @@ -14,12 +14,7 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see -import os - from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') # noqa -from django.conf import settings - application = get_wsgi_application() From a33502e22079d38f7130b0620592247fda42c849 Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Fri, 10 Apr 2020 13:26:46 +0300 Subject: [PATCH 10/13] Add management commands --- patchman/apps.py | 7 +++ patchman/management/__init__.py | 0 patchman/management/commands/__init__.py | 0 .../commands/createsuperuser_with_password.py | 33 ++++++++++++ .../management/commands/set_rdns_check.py | 17 ++++++ .../management/commands/set_secret_key.py | 52 +++++++++++++++++++ patchman/settings.py | 1 + 7 files changed, 110 insertions(+) create mode 100644 patchman/apps.py create mode 100644 patchman/management/__init__.py create mode 100644 patchman/management/commands/__init__.py create mode 100644 patchman/management/commands/createsuperuser_with_password.py create mode 100644 patchman/management/commands/set_rdns_check.py create mode 100644 patchman/management/commands/set_secret_key.py diff --git a/patchman/apps.py b/patchman/apps.py new file mode 100644 index 00000000..4a9c3f7b --- /dev/null +++ b/patchman/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class PatchmanConfig(AppConfig): + name = 'patchman' diff --git a/patchman/management/__init__.py b/patchman/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/patchman/management/commands/__init__.py b/patchman/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/patchman/management/commands/createsuperuser_with_password.py b/patchman/management/commands/createsuperuser_with_password.py new file mode 100644 index 00000000..63d3c721 --- /dev/null +++ b/patchman/management/commands/createsuperuser_with_password.py @@ -0,0 +1,33 @@ +from django.contrib.auth.management.commands import createsuperuser +from django.core.management import CommandError + + +class Command(createsuperuser.Command): + help = 'Crate a superuser, and allow password to be provided' + + def add_arguments(self, parser): + super(Command, self).add_arguments(parser) + parser.add_argument( + '--password', dest='password', default=None, + help='Specifies the password for the superuser.', + ) + + def handle(self, *args, **options): + password = options.get('password') + username = options.get('username') + database = options.get('database') + + if options['interactive']: + raise CommandError( + 'Command is required to run with --no-input option') + if password and not username: + raise CommandError( + '--username is required if specifying --password') + + super(Command, self).handle(*args, **options) + + if password: + user = self.UserModel._default_manager.db_manager( + database).get(username=username) + user.set_password(password) + user.save() diff --git a/patchman/management/commands/set_rdns_check.py b/patchman/management/commands/set_rdns_check.py new file mode 100644 index 00000000..0e5250a7 --- /dev/null +++ b/patchman/management/commands/set_rdns_check.py @@ -0,0 +1,17 @@ +from django.core.management.base import BaseCommand, CommandError +from hosts.models import Host + + +class Command(BaseCommand): + help = 'Enable/Disable rDNS check for hosts' + + def add_arguments(self, parser): + parser.add_argument( + '--disable', action='store_false', default=True, dest='rdns_check', + help='If set, disables rDNS check') + + def handle(self, *args, **options): + try: + Host.objects.all().update(check_dns=options['rdns_check']) + except Exception as e: + raise CommandError('Failed to update rDNS check', str(e)) diff --git a/patchman/management/commands/set_secret_key.py b/patchman/management/commands/set_secret_key.py new file mode 100644 index 00000000..870d1475 --- /dev/null +++ b/patchman/management/commands/set_secret_key.py @@ -0,0 +1,52 @@ +import os +import re +import sys +import codecs +from random import choice +from tempfile import NamedTemporaryFile +from shutil import copy + +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'Set SECRET_KEY of Patchman Application.' + + def add_arguments(self, parser): + parser.add_argument( + '--key', help=( + 'The SECRET_KEY to be used by Patchman. If not set, a random ' + 'key of length 50 will be created.')) + + @staticmethod + def get_random_key(): + chars = 'abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)' + return ''.join([choice(chars) for i in range(50)]) + + def handle(self, *args, **options): + secret_key = options.get('key', self.get_random_key()) + + if sys.prefix == '/usr': + conf_path = '/etc/patchman' + else: + conf_path = os.path.join(sys.prefix, 'etc/patchman') + # if conf_path doesn't exist, try ./etc/patchman + if not os.path.isdir(conf_path): + conf_path = './etc/patchman' + local_settings = os.path.join(conf_path, 'local_settings.py') + + settings_contents = codecs.open( + local_settings, 'r', encoding='utf-8').read() + settings_contents = re.sub( + r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents) + + f = NamedTemporaryFile(delete=False) + temp = f.name + f.close() + + fh = codecs.open(temp, 'w+b', encoding='utf-8') + fh.write(settings_contents) + fh.close() + + copy(temp, local_settings) + os.remove(temp) diff --git a/patchman/settings.py b/patchman/settings.py index e67ccd2a..cb11ac07 100644 --- a/patchman/settings.py +++ b/patchman/settings.py @@ -88,6 +88,7 @@ 'repos.apps.ReposConfig', 'reports.apps.ReportsConfig', 'util.apps.UtilConfig', + 'patchman.apps.PatchmanConfig', ] REST_FRAMEWORK = { From 13da103c31157969e1587d8c1587a819d34e6f82 Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Tue, 12 May 2020 13:24:44 +0300 Subject: [PATCH 11/13] Add set_site command --- patchman/management/commands/set_site.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 patchman/management/commands/set_site.py diff --git a/patchman/management/commands/set_site.py b/patchman/management/commands/set_site.py new file mode 100644 index 00000000..659bb281 --- /dev/null +++ b/patchman/management/commands/set_site.py @@ -0,0 +1,23 @@ +from django.core.management.base import BaseCommand, CommandError +from django.contrib.sites.models import Site +from django.conf import settings + + +class Command(BaseCommand): + help = 'Set Patchman Site Name' + + def add_arguments(self, parser): + parser.add_argument( + '-n', '--name', dest='site_name', help='Site name') + parser.add_argument( + '--clear-cache', action='store_true', default=False, + dest='clear_cache', help='Clear Site cache') + + def handle(self, *args, **options): + try: + Site.objects.filter(pk=settings.SITE_ID).update( + name=options['site_name'], domain=options['site_name']) + if options['claer_cache']: + Site.objects.clear_cache() + except Exception as e: + raise CommandError('Failed to update Site name', str(e)) From 0fffaee2d152f584696318a4b0777e36ea655fbb Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Mon, 18 May 2020 08:54:57 +0300 Subject: [PATCH 12/13] Fix tox --- patchman/celery.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patchman/celery.py b/patchman/celery.py index 0f6ae245..54561298 100644 --- a/patchman/celery.py +++ b/patchman/celery.py @@ -17,8 +17,8 @@ import os from celery import Celery -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') # noqa -from django.conf import settings +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') +from django.conf import settings # noqa app = Celery('patchman') From 5bff7948b30f59c67a7540783de0142aaf524c11 Mon Sep 17 00:00:00 2001 From: Stamatis Katsaounis Date: Thu, 21 May 2020 10:29:25 +0300 Subject: [PATCH 13/13] Fix option --- patchman/celery.py | 4 ++-- patchman/management/commands/set_site.py | 2 +- patchman/wsgi.py | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/patchman/celery.py b/patchman/celery.py index 54561298..0f6ae245 100644 --- a/patchman/celery.py +++ b/patchman/celery.py @@ -17,8 +17,8 @@ import os from celery import Celery -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') -from django.conf import settings # noqa +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') # noqa +from django.conf import settings app = Celery('patchman') diff --git a/patchman/management/commands/set_site.py b/patchman/management/commands/set_site.py index 659bb281..3ad97a1b 100644 --- a/patchman/management/commands/set_site.py +++ b/patchman/management/commands/set_site.py @@ -17,7 +17,7 @@ def handle(self, *args, **options): try: Site.objects.filter(pk=settings.SITE_ID).update( name=options['site_name'], domain=options['site_name']) - if options['claer_cache']: + if options['clear_cache']: Site.objects.clear_cache() except Exception as e: raise CommandError('Failed to update Site name', str(e)) diff --git a/patchman/wsgi.py b/patchman/wsgi.py index fe412e50..4f52ecce 100644 --- a/patchman/wsgi.py +++ b/patchman/wsgi.py @@ -14,7 +14,12 @@ # You should have received a copy of the GNU General Public License # along with Patchman. If not, see +import os + from django.core.wsgi import get_wsgi_application +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'patchman.settings') # noqa +from django.conf import settings + application = get_wsgi_application()