mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 01:57:35 -03:30
Integrate a migration-detector middleware
This attempts to detect if there are migrations in-progress and will force display an interstitial page in the process that attempts to load the index page every 10s until it succeeds. This is only attached in production settings so the development environment can proceed even if the migrations haven't been applied yet
This commit is contained in:
parent
0e04b8e4d4
commit
b39db745d4
1
.gitignore
vendored
1
.gitignore
vendored
@ -21,6 +21,7 @@ awx/ui/static
|
||||
awx/ui/build_test
|
||||
awx/ui/client/languages
|
||||
awx/ui/templates/ui/index.html
|
||||
awx/ui/templates/ui/installing.html
|
||||
|
||||
# Tower setup playbook testing
|
||||
setup/test/roles/postgresql
|
||||
|
||||
@ -9,11 +9,13 @@ import six
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models.signals import post_save
|
||||
from django.db import IntegrityError
|
||||
from django.db.migrations.executor import MigrationExecutor
|
||||
from django.db import IntegrityError, connection
|
||||
from django.utils.functional import curry
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.apps import apps
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from awx.main.models import ActivityStream
|
||||
from awx.api.authentication import TokenAuthentication
|
||||
@ -162,3 +164,12 @@ class URLModificationMiddleware(object):
|
||||
if request.path_info != new_path:
|
||||
request.path = request.path.replace(request.path_info, new_path)
|
||||
request.path_info = new_path
|
||||
|
||||
|
||||
class MigrationRanCheckMiddleware(object):
|
||||
|
||||
def process_request(self, request):
|
||||
executor = MigrationExecutor(connection)
|
||||
plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
|
||||
if bool(plan) and 'migrations_notran' not in request.path:
|
||||
return redirect(reverse("ui:migrations_notran"))
|
||||
|
||||
@ -87,6 +87,8 @@ settings_files = os.path.join(settings_dir, '*.py')
|
||||
settings_file = os.environ.get('AWX_SETTINGS_FILE',
|
||||
'/etc/tower/settings.py')
|
||||
|
||||
MIDDLEWARE_CLASSES = ('awx.main.middleware.MigrationRanCheckMiddleware',) + MIDDLEWARE_CLASSES
|
||||
|
||||
# Attempt to load settings from /etc/tower/settings.py first, followed by
|
||||
# /etc/tower/conf.d/*.py.
|
||||
try:
|
||||
|
||||
@ -34,7 +34,7 @@ class SocialAuthMiddleware(SocialAuthExceptionMiddleware):
|
||||
if not hasattr(request, 'successful_authenticator'):
|
||||
request.successful_authenticator = None
|
||||
|
||||
if not request.path.startswith('/sso/'):
|
||||
if not request.path.startswith('/sso/') and 'migrations_notran' not in request.path:
|
||||
|
||||
# If token isn't present but we still have a user logged in via Django
|
||||
# sessions, log them out.
|
||||
|
||||
@ -25,6 +25,8 @@ const APP_ENTRY = path.join(SOURCE_PATH, 'app.js');
|
||||
const VENDOR_ENTRY = path.join(SOURCE_PATH, 'vendor.js');
|
||||
const INDEX_ENTRY = path.join(CLIENT_PATH, 'index.template.ejs');
|
||||
const INDEX_OUTPUT = path.join(UI_PATH, 'templates/ui/index.html');
|
||||
const INSTALL_RUNNING_ENTRY = path.join(CLIENT_PATH, 'installing.template.ejs')
|
||||
const INSTALL_RUNNING_OUTPUT = path.join(UI_PATH, 'templates/ui/installing.html');
|
||||
const THEME_ENTRY = path.join(LIB_PATH, 'theme', 'index.less');
|
||||
const OUTPUT = 'js/[name].[hash].js';
|
||||
const CHUNKS = ['vendor', 'app'];
|
||||
@ -168,6 +170,19 @@ let base = {
|
||||
moduleA.files.sort((fileA, fileB) => fileA.includes('js') ? -1 : 1)
|
||||
moduleB.files.sort((fileA, fileB) => fileA.includes('js') ? -1 : 1)
|
||||
|
||||
return moduleA.names[0] === 'vendor' ? -1 : 1
|
||||
}
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
alwaysWriteToDisk: true,
|
||||
template: INSTALL_RUNNING_ENTRY,
|
||||
filename: INSTALL_RUNNING_OUTPUT,
|
||||
inject: false,
|
||||
chunks: CHUNKS,
|
||||
chunksSortMode: (moduleA, moduleB) => {
|
||||
moduleA.files.sort((fileA, fileB) => fileA.includes('js') ? -1 : 1)
|
||||
moduleB.files.sort((fileA, fileB) => fileA.includes('js') ? -1 : 1)
|
||||
|
||||
return moduleA.names[0] === 'vendor' ? -1 : 1
|
||||
}
|
||||
})
|
||||
|
||||
35
awx/ui/client/installing.template.ejs
Normal file
35
awx/ui/client/installing.template.ejs
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="awApp">
|
||||
<head>
|
||||
{% load staticfiles %}
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="shortcut icon" href="{{ STATIC_URL }}assets/favicon.ico?v={{version}}" />
|
||||
<title ng-bind="tabTitle"></title>
|
||||
<% htmlWebpackPlugin.files.css.forEach(file => {%>
|
||||
<link href="{{ STATIC_URL }}<%= file %>" rel="stylesheet" />
|
||||
<% }) %>
|
||||
<% htmlWebpackPlugin.files.js.forEach(file => {%>
|
||||
<script src="{{ STATIC_URL }}<%= file %>"></script>
|
||||
<% }) %>
|
||||
<script>
|
||||
setInterval(function() {
|
||||
window.location = '/#/index.html';
|
||||
}, 10000);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="jumbotron">
|
||||
<div class="container-fluid" id="content-container">
|
||||
<div class="span4">
|
||||
<img style="float:left" src="{% static 'assets/logo-header.svg' %}" width="200"/>
|
||||
<div class="content-heading"><h1>AWX is Upgrading</h1></div>
|
||||
<p>
|
||||
AWX is currently upgrading or installing, this page will refresh when done.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@ -6,5 +6,6 @@ from django.conf.urls import *
|
||||
|
||||
urlpatterns = patterns('awx.ui.views',
|
||||
url(r'^$', 'index', name='index'),
|
||||
url(r'^migrations_notran/$', 'migrations_notran', name='migrations_notran'),
|
||||
url(r'^portal/$', 'portal_redirect', name='portal_redirect'),
|
||||
)
|
||||
|
||||
@ -20,3 +20,9 @@ class PortalRedirectView(RedirectView):
|
||||
url = '/#/portal'
|
||||
|
||||
portal_redirect = PortalRedirectView.as_view()
|
||||
|
||||
class MigrationsNotran(TemplateView):
|
||||
|
||||
template_name = 'ui/installing.html'
|
||||
|
||||
migrations_notran = MigrationsNotran.as_view()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user