Commit d6ea079f by Bach Dániel

Merge branch 'feature-django18' into 'master'

Django18 

See merge request !331
parents e5b9cb0f 576d93a0
...@@ -43,6 +43,7 @@ class Level(Model): ...@@ -43,6 +43,7 @@ class Level(Model):
return "<%s/%s>" % (unicode(self.content_type), self.name) return "<%s/%s>" % (unicode(self.content_type), self.name)
class Meta: class Meta:
app_label = 'acl'
unique_together = (('content_type', 'codename'), unique_together = (('content_type', 'codename'),
# ('content_type', 'weight'), # ('content_type', 'weight'),
# TODO find a way of temp. disabling this constr. # TODO find a way of temp. disabling this constr.
...@@ -63,6 +64,7 @@ class ObjectLevel(Model): ...@@ -63,6 +64,7 @@ class ObjectLevel(Model):
return "<%s: %s>" % (unicode(self.content_object), unicode(self.level)) return "<%s: %s>" % (unicode(self.content_object), unicode(self.level))
class Meta: class Meta:
app_label = 'acl'
unique_together = (('content_type', 'object_id', 'level'),) unique_together = (('content_type', 'object_id', 'level'),)
...@@ -182,7 +184,7 @@ class AclBase(Model): ...@@ -182,7 +184,7 @@ class AclBase(Model):
def get_users_with_level(self, **kwargs): def get_users_with_level(self, **kwargs):
logger.debug('%s.get_users_with_level() called', unicode(self)) logger.debug('%s.get_users_with_level() called', unicode(self))
object_levels = (self.object_level_set.filter(**kwargs).select_related( object_levels = (self.object_level_set.filter(**kwargs).select_related(
'users', 'level').all()) 'level').prefetch_related('users').all())
users = [] users = []
for object_level in object_levels: for object_level in object_levels:
name = object_level.level.codename name = object_level.level.codename
...@@ -194,7 +196,7 @@ class AclBase(Model): ...@@ -194,7 +196,7 @@ class AclBase(Model):
def get_groups_with_level(self): def get_groups_with_level(self):
logger.debug('%s.get_groups_with_level() called', unicode(self)) logger.debug('%s.get_groups_with_level() called', unicode(self))
object_levels = (self.object_level_set.select_related( object_levels = (self.object_level_set.select_related(
'groups', 'level').all()) 'level').prefetch_related('groups').all())
groups = [] groups = []
for object_level in object_levels: for object_level in object_levels:
name = object_level.level.codename name = object_level.level.codename
......
...@@ -337,7 +337,6 @@ DJANGO_APPS = ( ...@@ -337,7 +337,6 @@ DJANGO_APPS = (
THIRD_PARTY_APPS = ( THIRD_PARTY_APPS = (
'django_tables2', 'django_tables2',
'crispy_forms', 'crispy_forms',
'djcelery',
'sizefield', 'sizefield',
'taggit', 'taggit',
'statici18n', 'statici18n',
...@@ -564,3 +563,5 @@ ADMIN_ENABLED = False ...@@ -564,3 +563,5 @@ ADMIN_ENABLED = False
BLACKLIST_PASSWORD = get_env_variable("BLACKLIST_PASSWORD", "") BLACKLIST_PASSWORD = get_env_variable("BLACKLIST_PASSWORD", "")
BLACKLIST_HOOK_URL = get_env_variable("BLACKLIST_HOOK_URL", "") BLACKLIST_HOOK_URL = get_env_variable("BLACKLIST_HOOK_URL", "")
REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "") REQUEST_HOOK_URL = get_env_variable("REQUEST_HOOK_URL", "")
SSHKEY_EMAIL_ADD_KEY = False
...@@ -14,9 +14,31 @@ ...@@ -14,9 +14,31 @@
# #
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>. # with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
import os# noqa import os
from .base import * # noqa from .base import * # noqa
# flake8: noqa
# fix https://github.com/django-nose/django-nose/issues/197
# AttributeError: 'module' object has no attribute 'commit_unless_managed'
# TypeError: _skip_create_test_db() got an unexpected keyword argument 'keepdb'
from django.db import transaction
from django_nose import runner
def _skip_create_test_db(self, verbosity=1, autoclobber=False, serialize=True,
keepdb=True):
return old_skip_create_test_db(
self, verbosity=verbosity, autoclobber=autoclobber,
serialize=serialize)
setattr(transaction, "commit_unless_managed", lambda using: using)
old_skip_create_test_db = runner._skip_create_test_db
setattr(runner, "_skip_create_test_db", _skip_create_test_db)
os.environ['REUSE_DB'] = "1" os.environ['REUSE_DB'] = "1"
os.environ['DJANGO_TEST_DB_NAME'] = "circle" os.environ['DJANGO_TEST_DB_NAME'] = "circle"
DATABASES = { DATABASES = {
...@@ -42,7 +64,8 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' ...@@ -42,7 +64,8 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
path_to_selenium_test = os.path.join(SITE_ROOT, "dashboard/tests/selenium") path_to_selenium_test = os.path.join(SITE_ROOT, "dashboard/tests/selenium")
NOSE_ARGS = ['--stop', '--with-doctest', '--with-selenium-driver', '--selenium-driver=firefox', '-w%s' % path_to_selenium_test] NOSE_ARGS = ['--stop', '--with-doctest', '--with-selenium-driver',
'--selenium-driver=firefox', '-w%s' % path_to_selenium_test]
PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher'] PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher']
......
...@@ -356,8 +356,6 @@ class HumanSortField(CharField): ...@@ -356,8 +356,6 @@ class HumanSortField(CharField):
Code is based on carljm's django-model-utils. Code is based on carljm's django-model-utils.
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
logger.debug('Initing HumanSortField(%s %s)',
unicode(args), unicode(kwargs))
kwargs.setdefault('default', "") kwargs.setdefault('default', "")
self.maximum_number_length = kwargs.pop('maximum_number_length', 4) self.maximum_number_length = kwargs.pop('maximum_number_length', 4)
monitor = kwargs.pop('monitor', None) monitor = kwargs.pop('monitor', None)
......
...@@ -44,1221 +44,6 @@ ...@@ -44,1221 +44,6 @@
}, },
{ {
"pk": 1, "pk": 1,
"model": "auth.permission",
"fields": {
"codename": "add_permission",
"name": "Can add permission",
"content_type": 1
}
},
{
"pk": 2,
"model": "auth.permission",
"fields": {
"codename": "change_permission",
"name": "Can change permission",
"content_type": 1
}
},
{
"pk": 3,
"model": "auth.permission",
"fields": {
"codename": "delete_permission",
"name": "Can delete permission",
"content_type": 1
}
},
{
"pk": 4,
"model": "auth.permission",
"fields": {
"codename": "add_group",
"name": "Can add group",
"content_type": 2
}
},
{
"pk": 5,
"model": "auth.permission",
"fields": {
"codename": "change_group",
"name": "Can change group",
"content_type": 2
}
},
{
"pk": 6,
"model": "auth.permission",
"fields": {
"codename": "delete_group",
"name": "Can delete group",
"content_type": 2
}
},
{
"pk": 7,
"model": "auth.permission",
"fields": {
"codename": "add_user",
"name": "Can add user",
"content_type": 3
}
},
{
"pk": 8,
"model": "auth.permission",
"fields": {
"codename": "change_user",
"name": "Can change user",
"content_type": 3
}
},
{
"pk": 9,
"model": "auth.permission",
"fields": {
"codename": "delete_user",
"name": "Can delete user",
"content_type": 3
}
},
{
"pk": 10,
"model": "auth.permission",
"fields": {
"codename": "add_contenttype",
"name": "Can add content type",
"content_type": 4
}
},
{
"pk": 11,
"model": "auth.permission",
"fields": {
"codename": "change_contenttype",
"name": "Can change content type",
"content_type": 4
}
},
{
"pk": 12,
"model": "auth.permission",
"fields": {
"codename": "delete_contenttype",
"name": "Can delete content type",
"content_type": 4
}
},
{
"pk": 13,
"model": "auth.permission",
"fields": {
"codename": "add_session",
"name": "Can add session",
"content_type": 5
}
},
{
"pk": 14,
"model": "auth.permission",
"fields": {
"codename": "change_session",
"name": "Can change session",
"content_type": 5
}
},
{
"pk": 15,
"model": "auth.permission",
"fields": {
"codename": "delete_session",
"name": "Can delete session",
"content_type": 5
}
},
{
"pk": 16,
"model": "auth.permission",
"fields": {
"codename": "add_site",
"name": "Can add site",
"content_type": 6
}
},
{
"pk": 17,
"model": "auth.permission",
"fields": {
"codename": "change_site",
"name": "Can change site",
"content_type": 6
}
},
{
"pk": 18,
"model": "auth.permission",
"fields": {
"codename": "delete_site",
"name": "Can delete site",
"content_type": 6
}
},
{
"pk": 19,
"model": "auth.permission",
"fields": {
"codename": "add_logentry",
"name": "Can add log entry",
"content_type": 7
}
},
{
"pk": 20,
"model": "auth.permission",
"fields": {
"codename": "change_logentry",
"name": "Can change log entry",
"content_type": 7
}
},
{
"pk": 21,
"model": "auth.permission",
"fields": {
"codename": "delete_logentry",
"name": "Can delete log entry",
"content_type": 7
}
},
{
"pk": 22,
"model": "auth.permission",
"fields": {
"codename": "add_migrationhistory",
"name": "Can add migration history",
"content_type": 8
}
},
{
"pk": 23,
"model": "auth.permission",
"fields": {
"codename": "change_migrationhistory",
"name": "Can change migration history",
"content_type": 8
}
},
{
"pk": 24,
"model": "auth.permission",
"fields": {
"codename": "delete_migrationhistory",
"name": "Can delete migration history",
"content_type": 8
}
},
{
"pk": 25,
"model": "auth.permission",
"fields": {
"codename": "add_namedbaseresourceconfig",
"name": "Can add named base resource config",
"content_type": 9
}
},
{
"pk": 26,
"model": "auth.permission",
"fields": {
"codename": "change_namedbaseresourceconfig",
"name": "Can change named base resource config",
"content_type": 9
}
},
{
"pk": 27,
"model": "auth.permission",
"fields": {
"codename": "delete_namedbaseresourceconfig",
"name": "Can delete named base resource config",
"content_type": 9
}
},
{
"pk": 28,
"model": "auth.permission",
"fields": {
"codename": "add_node",
"name": "Can add node",
"content_type": 10
}
},
{
"pk": 29,
"model": "auth.permission",
"fields": {
"codename": "change_node",
"name": "Can change node",
"content_type": 10
}
},
{
"pk": 30,
"model": "auth.permission",
"fields": {
"codename": "delete_node",
"name": "Can delete node",
"content_type": 10
}
},
{
"pk": 31,
"model": "auth.permission",
"fields": {
"codename": "add_nodeactivity",
"name": "Can add node activity",
"content_type": 11
}
},
{
"pk": 32,
"model": "auth.permission",
"fields": {
"codename": "change_nodeactivity",
"name": "Can change node activity",
"content_type": 11
}
},
{
"pk": 33,
"model": "auth.permission",
"fields": {
"codename": "delete_nodeactivity",
"name": "Can delete node activity",
"content_type": 11
}
},
{
"pk": 34,
"model": "auth.permission",
"fields": {
"codename": "add_lease",
"name": "Can add lease",
"content_type": 12
}
},
{
"pk": 35,
"model": "auth.permission",
"fields": {
"codename": "change_lease",
"name": "Can change lease",
"content_type": 12
}
},
{
"pk": 36,
"model": "auth.permission",
"fields": {
"codename": "delete_lease",
"name": "Can delete lease",
"content_type": 12
}
},
{
"pk": 37,
"model": "auth.permission",
"fields": {
"codename": "add_instancetemplate",
"name": "Can add template",
"content_type": 13
}
},
{
"pk": 38,
"model": "auth.permission",
"fields": {
"codename": "change_instancetemplate",
"name": "Can change template",
"content_type": 13
}
},
{
"pk": 39,
"model": "auth.permission",
"fields": {
"codename": "delete_instancetemplate",
"name": "Can delete template",
"content_type": 13
}
},
{
"pk": 40,
"model": "auth.permission",
"fields": {
"codename": "add_interfacetemplate",
"name": "Can add interface template",
"content_type": 14
}
},
{
"pk": 41,
"model": "auth.permission",
"fields": {
"codename": "change_interfacetemplate",
"name": "Can change interface template",
"content_type": 14
}
},
{
"pk": 42,
"model": "auth.permission",
"fields": {
"codename": "delete_interfacetemplate",
"name": "Can delete interface template",
"content_type": 14
}
},
{
"pk": 43,
"model": "auth.permission",
"fields": {
"codename": "add_instance",
"name": "Can add instance",
"content_type": 15
}
},
{
"pk": 44,
"model": "auth.permission",
"fields": {
"codename": "change_instance",
"name": "Can change instance",
"content_type": 15
}
},
{
"pk": 45,
"model": "auth.permission",
"fields": {
"codename": "delete_instance",
"name": "Can delete instance",
"content_type": 15
}
},
{
"pk": 46,
"model": "auth.permission",
"fields": {
"codename": "add_instanceactivity",
"name": "Can add instance activity",
"content_type": 16
}
},
{
"pk": 47,
"model": "auth.permission",
"fields": {
"codename": "change_instanceactivity",
"name": "Can change instance activity",
"content_type": 16
}
},
{
"pk": 48,
"model": "auth.permission",
"fields": {
"codename": "delete_instanceactivity",
"name": "Can delete instance activity",
"content_type": 16
}
},
{
"pk": 49,
"model": "auth.permission",
"fields": {
"codename": "add_interface",
"name": "Can add interface",
"content_type": 17
}
},
{
"pk": 50,
"model": "auth.permission",
"fields": {
"codename": "change_interface",
"name": "Can change interface",
"content_type": 17
}
},
{
"pk": 51,
"model": "auth.permission",
"fields": {
"codename": "delete_interface",
"name": "Can delete interface",
"content_type": 17
}
},
{
"pk": 52,
"model": "auth.permission",
"fields": {
"codename": "add_datastore",
"name": "Can add datastore",
"content_type": 18
}
},
{
"pk": 53,
"model": "auth.permission",
"fields": {
"codename": "change_datastore",
"name": "Can change datastore",
"content_type": 18
}
},
{
"pk": 54,
"model": "auth.permission",
"fields": {
"codename": "delete_datastore",
"name": "Can delete datastore",
"content_type": 18
}
},
{
"pk": 55,
"model": "auth.permission",
"fields": {
"codename": "add_disk",
"name": "Can add disk",
"content_type": 19
}
},
{
"pk": 56,
"model": "auth.permission",
"fields": {
"codename": "change_disk",
"name": "Can change disk",
"content_type": 19
}
},
{
"pk": 57,
"model": "auth.permission",
"fields": {
"codename": "delete_disk",
"name": "Can delete disk",
"content_type": 19
}
},
{
"pk": 58,
"model": "auth.permission",
"fields": {
"codename": "add_rule",
"name": "Can add rule",
"content_type": 20
}
},
{
"pk": 59,
"model": "auth.permission",
"fields": {
"codename": "change_rule",
"name": "Can change rule",
"content_type": 20
}
},
{
"pk": 60,
"model": "auth.permission",
"fields": {
"codename": "delete_rule",
"name": "Can delete rule",
"content_type": 20
}
},
{
"pk": 61,
"model": "auth.permission",
"fields": {
"codename": "add_vlan",
"name": "Can add vlan",
"content_type": 21
}
},
{
"pk": 62,
"model": "auth.permission",
"fields": {
"codename": "change_vlan",
"name": "Can change vlan",
"content_type": 21
}
},
{
"pk": 63,
"model": "auth.permission",
"fields": {
"codename": "delete_vlan",
"name": "Can delete vlan",
"content_type": 21
}
},
{
"pk": 64,
"model": "auth.permission",
"fields": {
"codename": "add_vlangroup",
"name": "Can add vlan group",
"content_type": 22
}
},
{
"pk": 65,
"model": "auth.permission",
"fields": {
"codename": "change_vlangroup",
"name": "Can change vlan group",
"content_type": 22
}
},
{
"pk": 66,
"model": "auth.permission",
"fields": {
"codename": "delete_vlangroup",
"name": "Can delete vlan group",
"content_type": 22
}
},
{
"pk": 67,
"model": "auth.permission",
"fields": {
"codename": "add_group",
"name": "Can add group",
"content_type": 23
}
},
{
"pk": 68,
"model": "auth.permission",
"fields": {
"codename": "change_group",
"name": "Can change group",
"content_type": 23
}
},
{
"pk": 69,
"model": "auth.permission",
"fields": {
"codename": "delete_group",
"name": "Can delete group",
"content_type": 23
}
},
{
"pk": 70,
"model": "auth.permission",
"fields": {
"codename": "add_host",
"name": "Can add host",
"content_type": 24
}
},
{
"pk": 71,
"model": "auth.permission",
"fields": {
"codename": "change_host",
"name": "Can change host",
"content_type": 24
}
},
{
"pk": 72,
"model": "auth.permission",
"fields": {
"codename": "delete_host",
"name": "Can delete host",
"content_type": 24
}
},
{
"pk": 73,
"model": "auth.permission",
"fields": {
"codename": "add_firewall",
"name": "Can add firewall",
"content_type": 25
}
},
{
"pk": 74,
"model": "auth.permission",
"fields": {
"codename": "change_firewall",
"name": "Can change firewall",
"content_type": 25
}
},
{
"pk": 75,
"model": "auth.permission",
"fields": {
"codename": "delete_firewall",
"name": "Can delete firewall",
"content_type": 25
}
},
{
"pk": 76,
"model": "auth.permission",
"fields": {
"codename": "add_domain",
"name": "Can add domain",
"content_type": 26
}
},
{
"pk": 77,
"model": "auth.permission",
"fields": {
"codename": "change_domain",
"name": "Can change domain",
"content_type": 26
}
},
{
"pk": 78,
"model": "auth.permission",
"fields": {
"codename": "delete_domain",
"name": "Can delete domain",
"content_type": 26
}
},
{
"pk": 79,
"model": "auth.permission",
"fields": {
"codename": "add_record",
"name": "Can add record",
"content_type": 27
}
},
{
"pk": 80,
"model": "auth.permission",
"fields": {
"codename": "change_record",
"name": "Can change record",
"content_type": 27
}
},
{
"pk": 81,
"model": "auth.permission",
"fields": {
"codename": "delete_record",
"name": "Can delete record",
"content_type": 27
}
},
{
"pk": 82,
"model": "auth.permission",
"fields": {
"codename": "add_blacklist",
"name": "Can add blacklist",
"content_type": 28
}
},
{
"pk": 83,
"model": "auth.permission",
"fields": {
"codename": "change_blacklist",
"name": "Can change blacklist",
"content_type": 28
}
},
{
"pk": 84,
"model": "auth.permission",
"fields": {
"codename": "delete_blacklist",
"name": "Can delete blacklist",
"content_type": 28
}
},
{
"pk": 85,
"model": "auth.permission",
"fields": {
"codename": "add_taskmeta",
"name": "Can add task state",
"content_type": 29
}
},
{
"pk": 86,
"model": "auth.permission",
"fields": {
"codename": "change_taskmeta",
"name": "Can change task state",
"content_type": 29
}
},
{
"pk": 87,
"model": "auth.permission",
"fields": {
"codename": "delete_taskmeta",
"name": "Can delete task state",
"content_type": 29
}
},
{
"pk": 88,
"model": "auth.permission",
"fields": {
"codename": "add_tasksetmeta",
"name": "Can add saved group result",
"content_type": 30
}
},
{
"pk": 89,
"model": "auth.permission",
"fields": {
"codename": "change_tasksetmeta",
"name": "Can change saved group result",
"content_type": 30
}
},
{
"pk": 90,
"model": "auth.permission",
"fields": {
"codename": "delete_tasksetmeta",
"name": "Can delete saved group result",
"content_type": 30
}
},
{
"pk": 91,
"model": "auth.permission",
"fields": {
"codename": "add_intervalschedule",
"name": "Can add interval",
"content_type": 31
}
},
{
"pk": 92,
"model": "auth.permission",
"fields": {
"codename": "change_intervalschedule",
"name": "Can change interval",
"content_type": 31
}
},
{
"pk": 93,
"model": "auth.permission",
"fields": {
"codename": "delete_intervalschedule",
"name": "Can delete interval",
"content_type": 31
}
},
{
"pk": 94,
"model": "auth.permission",
"fields": {
"codename": "add_crontabschedule",
"name": "Can add crontab",
"content_type": 32
}
},
{
"pk": 95,
"model": "auth.permission",
"fields": {
"codename": "change_crontabschedule",
"name": "Can change crontab",
"content_type": 32
}
},
{
"pk": 96,
"model": "auth.permission",
"fields": {
"codename": "delete_crontabschedule",
"name": "Can delete crontab",
"content_type": 32
}
},
{
"pk": 97,
"model": "auth.permission",
"fields": {
"codename": "add_periodictasks",
"name": "Can add periodic tasks",
"content_type": 33
}
},
{
"pk": 98,
"model": "auth.permission",
"fields": {
"codename": "change_periodictasks",
"name": "Can change periodic tasks",
"content_type": 33
}
},
{
"pk": 99,
"model": "auth.permission",
"fields": {
"codename": "delete_periodictasks",
"name": "Can delete periodic tasks",
"content_type": 33
}
},
{
"pk": 100,
"model": "auth.permission",
"fields": {
"codename": "add_periodictask",
"name": "Can add periodic task",
"content_type": 34
}
},
{
"pk": 101,
"model": "auth.permission",
"fields": {
"codename": "change_periodictask",
"name": "Can change periodic task",
"content_type": 34
}
},
{
"pk": 102,
"model": "auth.permission",
"fields": {
"codename": "delete_periodictask",
"name": "Can delete periodic task",
"content_type": 34
}
},
{
"pk": 103,
"model": "auth.permission",
"fields": {
"codename": "add_workerstate",
"name": "Can add worker",
"content_type": 35
}
},
{
"pk": 104,
"model": "auth.permission",
"fields": {
"codename": "change_workerstate",
"name": "Can change worker",
"content_type": 35
}
},
{
"pk": 105,
"model": "auth.permission",
"fields": {
"codename": "delete_workerstate",
"name": "Can delete worker",
"content_type": 35
}
},
{
"pk": 106,
"model": "auth.permission",
"fields": {
"codename": "add_taskstate",
"name": "Can add task",
"content_type": 36
}
},
{
"pk": 107,
"model": "auth.permission",
"fields": {
"codename": "change_taskstate",
"name": "Can change task",
"content_type": 36
}
},
{
"pk": 108,
"model": "auth.permission",
"fields": {
"codename": "delete_taskstate",
"name": "Can delete task",
"content_type": 36
}
},
{
"pk": 109,
"model": "auth.permission",
"fields": {
"codename": "add_userobjectpermission",
"name": "Can add user object permission",
"content_type": 37
}
},
{
"pk": 110,
"model": "auth.permission",
"fields": {
"codename": "change_userobjectpermission",
"name": "Can change user object permission",
"content_type": 37
}
},
{
"pk": 111,
"model": "auth.permission",
"fields": {
"codename": "delete_userobjectpermission",
"name": "Can delete user object permission",
"content_type": 37
}
},
{
"pk": 112,
"model": "auth.permission",
"fields": {
"codename": "add_groupobjectpermission",
"name": "Can add group object permission",
"content_type": 38
}
},
{
"pk": 113,
"model": "auth.permission",
"fields": {
"codename": "change_groupobjectpermission",
"name": "Can change group object permission",
"content_type": 38
}
},
{
"pk": 114,
"model": "auth.permission",
"fields": {
"codename": "delete_groupobjectpermission",
"name": "Can delete group object permission",
"content_type": 38
}
},
{
"pk": 115,
"model": "auth.permission",
"fields": {
"codename": "own_instance",
"name": "owner",
"content_type": 15
}
},
{
"pk": 116,
"model": "auth.permission",
"fields": {
"codename": "operate_instance",
"name": "operator",
"content_type": 15
}
},
{
"pk": 117,
"model": "auth.permission",
"fields": {
"codename": "use_instance",
"name": "user",
"content_type": 15
}
},
{
"pk": 118,
"model": "auth.permission",
"fields": {
"codename": "add_diskactivity",
"name": "Can add disk activity",
"content_type": 39
}
},
{
"pk": 119,
"model": "auth.permission",
"fields": {
"codename": "change_diskactivity",
"name": "Can change disk activity",
"content_type": 39
}
},
{
"pk": 120,
"model": "auth.permission",
"fields": {
"codename": "delete_diskactivity",
"name": "Can delete disk activity",
"content_type": 39
}
},
{
"pk": 121,
"model": "auth.permission",
"fields": {
"codename": "add_level",
"name": "Can add level",
"content_type": 40
}
},
{
"pk": 122,
"model": "auth.permission",
"fields": {
"codename": "change_level",
"name": "Can change level",
"content_type": 40
}
},
{
"pk": 123,
"model": "auth.permission",
"fields": {
"codename": "delete_level",
"name": "Can delete level",
"content_type": 40
}
},
{
"pk": 127,
"model": "auth.permission",
"fields": {
"codename": "add_objectlevel",
"name": "Can add object level",
"content_type": 42
}
},
{
"pk": 128,
"model": "auth.permission",
"fields": {
"codename": "change_objectlevel",
"name": "Can change object level",
"content_type": 42
}
},
{
"pk": 129,
"model": "auth.permission",
"fields": {
"codename": "delete_objectlevel",
"name": "Can delete object level",
"content_type": 42
}
},
{
"pk": 130,
"model": "auth.permission",
"fields": {
"codename": "add_switchport",
"name": "Can add switch port",
"content_type": 43
}
},
{
"pk": 131,
"model": "auth.permission",
"fields": {
"codename": "change_switchport",
"name": "Can change switch port",
"content_type": 43
}
},
{
"pk": 132,
"model": "auth.permission",
"fields": {
"codename": "delete_switchport",
"name": "Can delete switch port",
"content_type": 43
}
},
{
"pk": 133,
"model": "auth.permission",
"fields": {
"codename": "add_ethernetdevice",
"name": "Can add ethernet device",
"content_type": 44
}
},
{
"pk": 134,
"model": "auth.permission",
"fields": {
"codename": "change_ethernetdevice",
"name": "Can change ethernet device",
"content_type": 44
}
},
{
"pk": 135,
"model": "auth.permission",
"fields": {
"codename": "delete_ethernetdevice",
"name": "Can delete ethernet device",
"content_type": 44
}
},
{
"pk": 1366,
"model": "auth.permission",
"fields": {
"codename": "config_ports",
"name": "Can configure port forwards.",
"content_type": 28
}
},
{
"pk": 1367,
"model": "auth.permission",
"fields": {
"codename": "create_vm",
"name": "Can create a new VM.",
"content_type": 28
}
},
{
"pk": 1368,
"model": "auth.permission",
"fields": {
"codename": "access_console",
"name": "Can access the graphical console of a VM.",
"content_type": 28
}
},
{
"pk": 1,
"model": "auth.group", "model": "auth.group",
"fields": { "fields": {
"name": "csopi", "name": "csopi",
......
...@@ -1326,16 +1326,16 @@ class UserEditForm(forms.ModelForm): ...@@ -1326,16 +1326,16 @@ class UserEditForm(forms.ModelForm):
class AclUserOrGroupAddForm(forms.Form): class AclUserOrGroupAddForm(forms.Form):
name = forms.CharField(widget=autocomplete_light.TextWidget( name = forms.CharField(widget=autocomplete_light.TextWidget(
'AclUserGroupAutocomplete', 'AclUserGroupAutocomplete',
autocomplete_js_attributes={'placeholder': _("Name of group or user")}, attrs={'class': 'form-control',
attrs={'class': 'form-control'})) 'placeholder': _("Name of group or user")}))
class TransferOwnershipForm(forms.Form): class TransferOwnershipForm(forms.Form):
name = forms.CharField( name = forms.CharField(
widget=autocomplete_light.TextWidget( widget=autocomplete_light.TextWidget(
'AclUserAutocomplete', 'AclUserAutocomplete',
autocomplete_js_attributes={"placeholder": _("Name of user")}, attrs={'class': 'form-control',
attrs={'class': 'form-control'}), 'placeholder': _("Name of user")}),
label=_("E-mail address or identifier of user")) label=_("E-mail address or identifier of user"))
...@@ -1343,8 +1343,8 @@ class AddGroupMemberForm(forms.Form): ...@@ -1343,8 +1343,8 @@ class AddGroupMemberForm(forms.Form):
new_member = forms.CharField( new_member = forms.CharField(
widget=autocomplete_light.TextWidget( widget=autocomplete_light.TextWidget(
'AclUserAutocomplete', 'AclUserAutocomplete',
autocomplete_js_attributes={"placeholder": _("Name of user")}, attrs={'class': 'form-control',
attrs={'class': 'form-control'}), 'placeholder': _("Name of user")}),
label=_("E-mail address or identifier of user")) label=_("E-mail address or identifier of user"))
......
...@@ -19,9 +19,8 @@ from os import listdir ...@@ -19,9 +19,8 @@ from os import listdir
from os.path import isfile, isdir, join from os.path import isfile, isdir, join
import unittest import unittest
from django.conf import settings
from django.template import Template, Context, VariableDoesNotExist from django.template import Template, Context, VariableDoesNotExist
from django.template.loader import find_template_loader from django.template.engine import Engine
from django.core.urlresolvers import NoReverseMatch from django.core.urlresolvers import NoReverseMatch
...@@ -29,9 +28,8 @@ class TemplateSyntaxTestCase(unittest.TestCase): ...@@ -29,9 +28,8 @@ class TemplateSyntaxTestCase(unittest.TestCase):
def test_templates(self): def test_templates(self):
"""Test all templates for syntax errors.""" """Test all templates for syntax errors."""
for loader_name in settings.TEMPLATE_LOADERS: for loader in Engine.get_default().template_loaders:
print loader_name print loader
loader = find_template_loader(loader_name)
self._test_dir(loader.get_template_sources('')) self._test_dir(loader.get_template_sources(''))
def _test_dir(self, dir, path="/"): def _test_dir(self, dir, path="/"):
......
...@@ -1706,7 +1706,11 @@ class SshKeyTest(LoginMixin, TestCase): ...@@ -1706,7 +1706,11 @@ class SshKeyTest(LoginMixin, TestCase):
self.u2.set_password('password') self.u2.set_password('password')
self.u2.profile = Profile() self.u2.profile = Profile()
self.u2.save() self.u2.save()
self.k1 = UserKey(key='ssh-rsa AAAAB3NzaC1yc2EC asd', user=self.u1) self.valid_key = (
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQDGqQy86fpVL3fAPE9ExTSvg4"
"Me7bpzH4azerTwWl8u9KKbhYe8XnC+cpvzbRxinFE9SqgQtKJzuxE0f/hHsNCQ"
"t3zDLHsqfFUdFQzkImXJ+duUKGyHKIsx6Os0j6nl+3c= asd")
self.k1 = UserKey(key=self.valid_key, user=self.u1)
self.k1.save() self.k1.save()
def tearDown(self): def tearDown(self):
...@@ -1719,7 +1723,7 @@ class SshKeyTest(LoginMixin, TestCase): ...@@ -1719,7 +1723,7 @@ class SshKeyTest(LoginMixin, TestCase):
self.login(c, self.u1) self.login(c, self.u1)
resp = c.post("/dashboard/sshkey/1/", resp = c.post("/dashboard/sshkey/1/",
{'key': 'ssh-rsa AAAAB3NzaC1yc2EC'}) {'key': self.valid_key})
self.assertEqual(UserKey.objects.get(id=1).user, self.u1) self.assertEqual(UserKey.objects.get(id=1).user, self.u1)
self.assertEqual(200, resp.status_code) self.assertEqual(200, resp.status_code)
...@@ -1728,7 +1732,7 @@ class SshKeyTest(LoginMixin, TestCase): ...@@ -1728,7 +1732,7 @@ class SshKeyTest(LoginMixin, TestCase):
self.login(c, self.u2) self.login(c, self.u2)
resp = c.post("/dashboard/sshkey/1/", resp = c.post("/dashboard/sshkey/1/",
{'key': 'ssh-rsa AAAAB3NzaC1yc2EC'}) {'key': self.valid_key})
self.assertEqual(UserKey.objects.get(id=1).user, self.u1) self.assertEqual(UserKey.objects.get(id=1).user, self.u1)
self.assertEqual(403, resp.status_code) self.assertEqual(403, resp.status_code)
...@@ -1737,7 +1741,7 @@ class SshKeyTest(LoginMixin, TestCase): ...@@ -1737,7 +1741,7 @@ class SshKeyTest(LoginMixin, TestCase):
self.login(c, self.u1) self.login(c, self.u1)
resp = c.post("/dashboard/sshkey/create/", resp = c.post("/dashboard/sshkey/create/",
{'name': 'asd', 'key': 'ssh-rsa AAAAB3NzaC1yc2EC'}) {'name': 'asd', 'key': self.valid_key})
self.assertEqual(UserKey.objects.get(id=2).user, self.u1) self.assertEqual(UserKey.objects.get(id=2).user, self.u1)
self.assertEqual(302, resp.status_code) self.assertEqual(302, resp.status_code)
......
...@@ -1109,8 +1109,10 @@ class VmCreate(LoginRequiredMixin, TemplateView): ...@@ -1109,8 +1109,10 @@ class VmCreate(LoginRequiredMixin, TemplateView):
return self.__deploy(request, instances) return self.__deploy(request, instances)
def __deploy(self, request, instances, *args, **kwargs): def __deploy(self, request, instances, *args, **kwargs):
# workaround EncodeError: dictionary changed size during iteration
user = User.objects.get(pk=request.user.pk)
for i in instances: for i in instances:
i.deploy.async(user=request.user) i.deploy.async(user=user)
if len(instances) > 1: if len(instances) > 1:
messages.success(request, ungettext_lazy( messages.success(request, ungettext_lazy(
......
...@@ -75,7 +75,7 @@ def flake8(): ...@@ -75,7 +75,7 @@ def flake8():
def migrate(): def migrate():
"Run db migrations" "Run db migrations"
with _workon("circle"), cd("~/circle/circle"): with _workon("circle"), cd("~/circle/circle"):
run("./manage.py migrate") run("./manage.py migrate --fake-initial")
@roles('portal') @roles('portal')
...@@ -166,6 +166,7 @@ def update_portal(test=False, git=True): ...@@ -166,6 +166,7 @@ def update_portal(test=False, git=True):
pull() pull()
cleanup() cleanup()
pip("circle", "~/circle/requirements.txt") pip("circle", "~/circle/requirements.txt")
sudo("cp ~/circle/miscellaneous/*celery.conf /etc/init/")
bower() bower()
migrate() migrate()
compile_things() compile_things()
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('firewall', '0004_auto_20150318_1317'),
]
operations = [
migrations.AlterField(
model_name='host',
name='groups',
field=models.ManyToManyField(help_text='Host groups the machine is part of.', to='firewall.Group', verbose_name='groups', blank=True),
),
migrations.AlterField(
model_name='vlan',
name='snat_to',
field=models.ManyToManyField(help_text='Connections to these networks should be network address translated, i.e. their source address is rewritten to the value of NAT IP address.', to='firewall.Vlan', verbose_name='NAT to', blank=True),
),
migrations.AlterField(
model_name='vlangroup',
name='vlans',
field=models.ManyToManyField(help_text='The vlans which are members of the group.', to='firewall.Vlan', verbose_name='vlans', blank=True),
),
]
...@@ -255,6 +255,7 @@ class Rule(models.Model): ...@@ -255,6 +255,7 @@ class Rule(models.Model):
return qs return qs
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("rule") verbose_name = _("rule")
verbose_name_plural = _("rules") verbose_name_plural = _("rules")
ordering = ( ordering = (
...@@ -330,7 +331,7 @@ class Vlan(AclBase, models.Model): ...@@ -330,7 +331,7 @@ class Vlan(AclBase, models.Model):
'selected below ' 'selected below '
'(typically to the internet).')) '(typically to the internet).'))
snat_to = models.ManyToManyField('self', symmetrical=False, blank=True, snat_to = models.ManyToManyField('self', symmetrical=False, blank=True,
null=True, verbose_name=_('NAT to'), verbose_name=_('NAT to'),
help_text=_( help_text=_(
'Connections to these networks ' 'Connections to these networks '
'should be network address ' 'should be network address '
...@@ -392,6 +393,7 @@ class Vlan(AclBase, models.Model): ...@@ -392,6 +393,7 @@ class Vlan(AclBase, models.Model):
verbose_name=_('modified at')) verbose_name=_('modified at'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("vlan") verbose_name = _("vlan")
verbose_name_plural = _("vlans") verbose_name_plural = _("vlans")
ordering = ('vid', ) ordering = ('vid', )
...@@ -533,7 +535,7 @@ class VlanGroup(models.Model): ...@@ -533,7 +535,7 @@ class VlanGroup(models.Model):
name = models.CharField(max_length=20, unique=True, verbose_name=_('name'), name = models.CharField(max_length=20, unique=True, verbose_name=_('name'),
help_text=_('The name of the group.')) help_text=_('The name of the group.'))
vlans = models.ManyToManyField('Vlan', symmetrical=False, blank=True, vlans = models.ManyToManyField('Vlan', symmetrical=False, blank=True,
null=True, verbose_name=_('vlans'), verbose_name=_('vlans'),
help_text=_('The vlans which are members ' help_text=_('The vlans which are members '
'of the group.')) 'of the group.'))
description = models.TextField(blank=True, verbose_name=_('description'), description = models.TextField(blank=True, verbose_name=_('description'),
...@@ -546,6 +548,7 @@ class VlanGroup(models.Model): ...@@ -546,6 +548,7 @@ class VlanGroup(models.Model):
verbose_name=_('modified at')) verbose_name=_('modified at'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("vlan group") verbose_name = _("vlan group")
verbose_name_plural = _("vlan groups") verbose_name_plural = _("vlan groups")
ordering = ('id', ) ordering = ('id', )
...@@ -573,6 +576,7 @@ class Group(models.Model): ...@@ -573,6 +576,7 @@ class Group(models.Model):
verbose_name=_('modified at')) verbose_name=_('modified at'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("host group") verbose_name = _("host group")
verbose_name_plural = _("host groups") verbose_name_plural = _("host groups")
ordering = ('id', ) ordering = ('id', )
...@@ -639,7 +643,7 @@ class Host(models.Model): ...@@ -639,7 +643,7 @@ class Host(models.Model):
help_text=_( help_text=_(
'The person responsible for this host.')) 'The person responsible for this host.'))
groups = models.ManyToManyField('Group', symmetrical=False, blank=True, groups = models.ManyToManyField('Group', symmetrical=False, blank=True,
null=True, verbose_name=_('groups'), verbose_name=_('groups'),
help_text=_( help_text=_(
'Host groups the machine is part of.')) 'Host groups the machine is part of.'))
created_at = models.DateTimeField(auto_now_add=True, created_at = models.DateTimeField(auto_now_add=True,
...@@ -648,6 +652,7 @@ class Host(models.Model): ...@@ -648,6 +652,7 @@ class Host(models.Model):
verbose_name=_('modified at')) verbose_name=_('modified at'))
class Meta(object): class Meta(object):
app_label = 'firewall'
unique_together = ('hostname', 'vlan') unique_together = ('hostname', 'vlan')
ordering = ('normalized_hostname', 'vlan') ordering = ('normalized_hostname', 'vlan')
...@@ -951,6 +956,7 @@ class Firewall(models.Model): ...@@ -951,6 +956,7 @@ class Firewall(models.Model):
verbose_name=_('name')) verbose_name=_('name'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("firewall") verbose_name = _("firewall")
verbose_name_plural = _("firewalls") verbose_name_plural = _("firewalls")
ordering = ('id', ) ordering = ('id', )
...@@ -1002,6 +1008,7 @@ class Domain(models.Model): ...@@ -1002,6 +1008,7 @@ class Domain(models.Model):
description = models.TextField(blank=True, verbose_name=_('description')) description = models.TextField(blank=True, verbose_name=_('description'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("domain") verbose_name = _("domain")
verbose_name_plural = _("domains") verbose_name_plural = _("domains")
ordering = ('id', ) ordering = ('id', )
...@@ -1083,6 +1090,7 @@ class Record(models.Model): ...@@ -1083,6 +1090,7 @@ class Record(models.Model):
return reverse('network.record', kwargs={'pk': self.pk}) return reverse('network.record', kwargs={'pk': self.pk})
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("record") verbose_name = _("record")
verbose_name_plural = _("records") verbose_name_plural = _("records")
ordering = ( ordering = (
...@@ -1105,6 +1113,7 @@ class SwitchPort(models.Model): ...@@ -1105,6 +1113,7 @@ class SwitchPort(models.Model):
verbose_name=_('modified_at')) verbose_name=_('modified_at'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("switch port") verbose_name = _("switch port")
verbose_name_plural = _("switch ports") verbose_name_plural = _("switch ports")
ordering = ('id', ) ordering = ('id', )
...@@ -1137,6 +1146,7 @@ class EthernetDevice(models.Model): ...@@ -1137,6 +1146,7 @@ class EthernetDevice(models.Model):
verbose_name=_('modified_at')) verbose_name=_('modified_at'))
class Meta: class Meta:
app_label = 'firewall'
verbose_name = _("ethernet device") verbose_name = _("ethernet device")
verbose_name_plural = _("ethernet devices") verbose_name_plural = _("ethernet devices")
ordering = ('id', ) ordering = ('id', )
...@@ -1172,6 +1182,7 @@ class BlacklistItem(models.Model): ...@@ -1172,6 +1182,7 @@ class BlacklistItem(models.Model):
return self.ipv4 return self.ipv4
class Meta(object): class Meta(object):
app_label = 'firewall'
verbose_name = _('blacklist item') verbose_name = _('blacklist item')
verbose_name_plural = _('blacklist items') verbose_name_plural = _('blacklist items')
ordering = ('id', ) ordering = ('id', )
......
...@@ -11,5 +11,5 @@ TimeoutStopSec=600 ...@@ -11,5 +11,5 @@ TimeoutStopSec=600
Restart=always Restart=always
WorkingDirectory=/home/cloud/circle/circle WorkingDirectory=/home/cloud/circle/circle
ExecStartPre=/bin/bash -c "source /etc/profile; workon circle; ./manage.py celery -f --app=manager.%I purge" ExecStartPre=/bin/bash -c "source /etc/profile; workon circle; celery -f --app=manager.%I purge"
ExecStart=/bin/bash -c "source /etc/profile; workon circle; exec ./manage.py celery --app=manager.%I worker --autoreload --loglevel=info --hostname=%I -B -c 3" ExecStart=/bin/bash -c "source /etc/profile; workon circle; exec celery --app=manager.%I worker --loglevel=info --hostname=%I -B -c 3"
...@@ -9,11 +9,12 @@ setuid cloud ...@@ -9,11 +9,12 @@ setuid cloud
kill timeout 360 kill timeout 360
kill signal SIGTERM kill signal SIGTERM
script script
cd /home/cloud/circle/circle cd /home/cloud/circle/circle
. /home/cloud/.virtualenvs/circle/bin/activate . /home/cloud/.virtualenvs/circle/bin/activate
. /home/cloud/.virtualenvs/circle/bin/postactivate . /home/cloud/.virtualenvs/circle/bin/postactivate
./manage.py celery -f --app=manager.mancelery purge celery -f --app=manager.mancelery purge
exec ./manage.py celery --app=manager.mancelery worker --autoreload --loglevel=info --hostname=mancelery -B -c 3 exec celery --app=manager.mancelery worker --autoreload --loglevel=info --hostname=mancelery -B -c 3
end script end script
...@@ -3,15 +3,18 @@ description "CIRCLE moncelery for monitoring jobs" ...@@ -3,15 +3,18 @@ description "CIRCLE moncelery for monitoring jobs"
respawn respawn
respawn limit 30 30 respawn limit 30 30
setgid cloud setgid cloud
setuid cloud setuid cloud
kill timeout 360
kill signal SIGTERM
script script
cd /home/cloud/circle/circle cd /home/cloud/circle/circle
. /home/cloud/.virtualenvs/circle/bin/activate . /home/cloud/.virtualenvs/circle/bin/activate
. /home/cloud/.virtualenvs/circle/bin/postactivate . /home/cloud/.virtualenvs/circle/bin/postactivate
./manage.py celery -f --app=manager.moncelery purge celery -f --app=manager.moncelery purge
exec ./manage.py celery --app=manager.moncelery worker --autoreload --loglevel=info --hostname=moncelery -B -c 2 exec celery --app=manager.moncelery worker --autoreload --loglevel=info --hostname=moncelery -B -c 2
end script end script
...@@ -14,7 +14,7 @@ script ...@@ -14,7 +14,7 @@ script
cd /home/cloud/circle/circle cd /home/cloud/circle/circle
. /home/cloud/.virtualenvs/circle/bin/activate . /home/cloud/.virtualenvs/circle/bin/activate
. /home/cloud/.virtualenvs/circle/bin/postactivate . /home/cloud/.virtualenvs/circle/bin/postactivate
./manage.py celery -f --app=manager.slowcelery purge celery -f --app=manager.slowcelery purge
exec ./manage.py celery --app=manager.slowcelery worker --autoreload --loglevel=info --hostname=slowcelery -B -c 1 exec celery --app=manager.slowcelery worker --autoreload --loglevel=info --hostname=slowcelery -B -c 1
end script end script
amqp==1.4.6 amqp==1.4.6
anyjson==0.3.3 anyjson==0.3.3
arrow==0.5.4 arrow==0.5.4
billiard==3.3.0.18 billiard==3.3.0.20
bpython==0.13.1 bpython==0.14.1
celery==3.1.17 celery==3.1.18
Django==1.7.5 Django==1.8.2
django-appconf==0.6 django-appconf==1.0.1
django-autocomplete-light==1.4.14 django-autocomplete-light==2.1.1
django-braces==1.4.0 django-braces==1.8.0
django-celery==3.1.16
django-crispy-forms==1.4.0 django-crispy-forms==1.4.0
django-model-utils==2.2 django-model-utils==2.2
djangosaml2==0.13.0 djangosaml2==0.13.0
django-sizefield==0.6 django-sizefield==0.7
django-sshkey==2.2.0 git+https://git.ik.bme.hu/circle/django-sshkey.git
django-statici18n==1.1 django-statici18n==1.1.3
django-tables2==0.15.0 django-tables2==0.16.0
django-taggit==0.13.0 django-taggit==0.14.0
docutils==0.12 docutils==0.12
Jinja2==2.7.3 Jinja2==2.7.3
jsonfield==1.0.0 jsonfield==1.0.3
kombu==3.0.23 kombu==3.0.26
logutils==0.3.3 logutils==0.3.3
MarkupSafe==0.23 MarkupSafe==0.23
netaddr==0.7.12 netaddr==0.7.14
pip-tools==0.3.5 pip-tools==0.3.6
psycopg2==2.5.4 psycopg2==2.6
Pygments==1.6 Pygments==2.0.2
pylibmc==1.3.0 pylibmc==1.4.3
python-dateutil==2.2 python-dateutil==2.4.2
pyinotify==0.9.4 pyinotify==0.9.5
pytz==2014.7 pytz==2015.4
requests==2.5.3 requests==2.7.0
salt==2014.1.0 salt==2015.5.1
shutilwhich==1.0.1 shutilwhich==1.1.0
simplejson==3.6.5 simplejson==3.7.2
six==1.8.0 six==1.9.0
slimit==0.8.1 slimit==0.8.1
South==0.8.4 sqlparse==0.1.15
sqlparse==0.1.13
pika==0.9.14 pika==0.9.14
Fabric==1.10.0
lxml==3.4.0
django-pipeline==1.4.7 django-pipeline==1.4.7
# Local development dependencies go here # Local development dependencies go here
-r base.txt -r base.txt
coverage==3.7.1 coverage==3.7.1
django-debug-toolbar==1.2.1 django-debug-toolbar==1.3.0
django-rosetta==0.7.4 django-rosetta==0.7.6
Sphinx==1.2.2 Sphinx==1.3.1
# Pro-tip: Try not to put anything here. There should be no dependency in # Pro-tip: Try not to put anything here. There should be no dependency in
# production that isn't in development. # production that isn't in development.
-r base.txt -r base.txt
uWSGI==2.0.8 uWSGI==2.0.10
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
coverage==3.7.1 coverage==3.7.1
factory-boy==2.4.1 factory-boy==2.4.1
mock==1.0.1 mock==1.0.1
django-nose==1.3 django-nose==1.4
nose==1.3.4 nose==1.3.6
nose-exclude==0.2.0 nose-exclude==0.2.0
selenium==2.45.0 selenium==2.45.0
selenose==1.3 selenose==1.3
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment