diff --git a/data/migrations/versions/4b7ef0c7bdb2_add_the_maintenance_notification_type.py b/data/migrations/versions/4b7ef0c7bdb2_add_the_maintenance_notification_type.py
new file mode 100644
index 000000000..9e5fff425
--- /dev/null
+++ b/data/migrations/versions/4b7ef0c7bdb2_add_the_maintenance_notification_type.py
@@ -0,0 +1,33 @@
+"""Add the maintenance notification type.
+
+Revision ID: 4b7ef0c7bdb2
+Revises: bcdde200a1b
+Create Date: 2014-06-27 19:09:56.387534
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '4b7ef0c7bdb2'
+down_revision = 'bcdde200a1b'
+
+from alembic import op
+from data.model.sqlalchemybridge import gen_sqlalchemy_metadata
+from data.database import all_models
+import sqlalchemy as sa
+
+
+def upgrade():
+ schema = gen_sqlalchemy_metadata(all_models)
+ op.bulk_insert(schema.tables['notificationkind'],
+ [
+ {'id':4, 'name':'maintenance'},
+ ])
+
+
+def downgrade():
+ notificationkind = schema.tables['notificationkind']
+ op.execute(
+ (notificationkind.delete()
+ .where(notificationkind.c.name == op.inline_literal('maintenance')))
+
+ )
diff --git a/initdb.py b/initdb.py
index cc1471e73..456587220 100644
--- a/initdb.py
+++ b/initdb.py
@@ -2,8 +2,10 @@ import logging
import json
import hashlib
import random
+import calendar
from datetime import datetime, timedelta
+from email.utils import formatdate
from peewee import (SqliteDatabase, create_model_tables, drop_model_tables,
savepoint_sqlite)
@@ -232,6 +234,7 @@ def initialize_database():
NotificationKind.create(name='password_required')
NotificationKind.create(name='over_private_usage')
NotificationKind.create(name='expiring_license')
+ NotificationKind.create(name='maintenance')
NotificationKind.create(name='test_notification')
@@ -289,6 +292,16 @@ def populate_database():
model.create_notification('test_notification', new_user_1, metadata={'some': 'value'})
+ from_date = datetime.utcnow()
+ to_date = from_date + timedelta(hours=1)
+ notification_metadata = {
+ 'from_date': formatdate(calendar.timegm(from_date.utctimetuple())),
+ 'to_date': formatdate(calendar.timegm(to_date.utctimetuple())),
+ 'reason': 'database migration'
+ }
+ model.create_notification('maintenance', new_user_1, metadata=notification_metadata)
+
+
__generate_repository(new_user_4, 'randomrepo', 'Random repo repository.', False,
[], (4, [], ['latest', 'prod']))
diff --git a/static/css/quay.css b/static/css/quay.css
index 68e317c70..8586ec9c7 100644
--- a/static/css/quay.css
+++ b/static/css/quay.css
@@ -582,7 +582,7 @@ i.toggle-icon:hover {
.notification-warning {
color: #8a6d3b;
- background: #fcf8e3;
+ background: #ffde2f;
}
.notification-error {
diff --git a/static/js/app.js b/static/js/app.js
index 397729c3b..242cb9d95 100644
--- a/static/js/app.js
+++ b/static/js/app.js
@@ -919,6 +919,12 @@ quayApp = angular.module('quay', quayDependencies, function($provide, cfpLoading
'message': 'Your license will expire at: {expires_at} ' +
'
Please contact Quay.io support to purchase a new license.',
'page': '/contact/'
+ },
+ 'maintenance': {
+ 'level': 'warning',
+ 'message': 'We will be down for schedule maintenance from {from_date} to {to_date} ' +
+ 'for {reason}. We are sorry about any inconvenience.',
+ 'page': 'http://status.quay.io/'
}
};
@@ -4335,7 +4341,11 @@ quayApp.directive('notificationView', function () {
'notification': '=notification',
'parent': '=parent'
},
- controller: function($scope, $element, $location, UserService, NotificationService) {
+ controller: function($scope, $element, $window, $location, UserService, NotificationService) {
+ var stringStartsWith = function (str, prefix) {
+ return str.slice(0, prefix.length) == prefix;
+ };
+
$scope.getMessage = function(notification) {
return NotificationService.getMessage(notification);
};
@@ -4352,14 +4362,18 @@ quayApp.directive('notificationView', function () {
$scope.showNotification = function() {
var url = NotificationService.getPage($scope.notification);
if (url) {
- var parts = url.split('?')
- $location.path(parts[0]);
-
- if (parts.length > 1) {
- $location.search(parts[1]);
- }
+ if (stringStartsWith(url, 'http://') || stringStartsWith(url, 'https://')) {
+ $window.location.href = url;
+ } else {
+ var parts = url.split('?')
+ $location.path(parts[0]);
+
+ if (parts.length > 1) {
+ $location.search(parts[1]);
+ }
- $scope.parent.$hide();
+ $scope.parent.$hide();
+ }
}
};
diff --git a/test/data/test.db b/test/data/test.db
index 09fbf419a..e5a283ef8 100644
Binary files a/test/data/test.db and b/test/data/test.db differ