Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
5e496201
authored
Jul 22, 2014
by
Guba Sándor
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into nostate-operation
Conflicts: circle/vm/models/instance.py
parents
38e373e3
6170f914
Hide whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
2097 additions
and
194 deletions
+2097
-194
circle/circle/settings/base.py
+4
-0
circle/circle/urls.py
+5
-2
circle/common/models.py
+131
-6
circle/common/operations.py
+15
-2
circle/common/views.py
+33
-0
circle/dashboard/fixtures/test-vm-fixture.json
+1
-0
circle/dashboard/migrations/0011_auto__add_field_notification_subject_data__add_field_notification_mess.py
+274
-0
circle/dashboard/migrations/0012_migrate_messages.py
+269
-0
circle/dashboard/migrations/0013_auto__del_field_notification_message__del_field_notification_subject.py
+272
-0
circle/dashboard/models.py
+33
-16
circle/dashboard/static/dashboard/dashboard.js
+0
-2
circle/dashboard/static/dashboard/vm-common.js
+2
-2
circle/dashboard/templates/dashboard/_notifications-timeline.html
+4
-4
circle/dashboard/templates/dashboard/_template-choose.html
+5
-1
circle/dashboard/templates/dashboard/instanceactivity_detail.html
+7
-2
circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
+10
-3
circle/dashboard/templates/dashboard/notifications/ownership-accepted.html
+0
-4
circle/dashboard/templates/dashboard/notifications/ownership-offer.html
+0
-5
circle/dashboard/templates/dashboard/notifications/vm-destroyed.html
+0
-4
circle/dashboard/templates/dashboard/notifications/vm-expiring.html
+0
-10
circle/dashboard/templates/dashboard/notifications/vm-suspended.html
+0
-4
circle/dashboard/templates/dashboard/template-list.html
+2
-2
circle/dashboard/templates/dashboard/vm-detail/_activity-timeline.html
+6
-6
circle/dashboard/templates/dashboard/vm-detail/_disk-operations.html
+1
-1
circle/dashboard/templates/dashboard/vm-detail/home.html
+3
-1
circle/dashboard/tests/test_mockedviews.py
+5
-3
circle/dashboard/tests/test_models.py
+3
-3
circle/dashboard/tests/test_views.py
+9
-2
circle/dashboard/views.py
+22
-14
circle/storage/models.py
+14
-1
circle/templates/500.html
+7
-1
circle/vm/migrations/0023_auto__del_unique_instancetemplate_n.py
+5
-3
circle/vm/migrations/0024_auto__del_field_instanceactivity_result__add_field_instanceactivity_re.py
+340
-0
circle/vm/migrations/0025_auto__add_field_instanceactivity_readable_name_data__add_field_nodeact.py
+295
-0
circle/vm/models/activity.py
+60
-27
circle/vm/models/instance.py
+66
-2
circle/vm/models/network.py
+16
-8
circle/vm/models/node.py
+6
-3
circle/vm/operations.py
+122
-36
circle/vm/tasks/local_periodic_tasks.py
+12
-7
circle/vm/tasks/vm_tasks.py
+20
-0
circle/vm/tests/test_models.py
+17
-7
requirements/base.txt
+1
-0
No files found.
circle/circle/settings/base.py
View file @
5e496201
...
@@ -22,6 +22,7 @@ from os.path import (abspath, basename, dirname, join, normpath, isfile,
...
@@ -22,6 +22,7 @@ from os.path import (abspath, basename, dirname, join, normpath, isfile,
expanduser
)
expanduser
)
from
sys
import
path
from
sys
import
path
from
subprocess
import
check_output
from
subprocess
import
check_output
from
uuid
import
getnode
from
django.core.exceptions
import
ImproperlyConfigured
from
django.core.exceptions
import
ImproperlyConfigured
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
...
@@ -444,3 +445,6 @@ if graphite_host and graphite_port:
...
@@ -444,3 +445,6 @@ if graphite_host and graphite_port:
GRAPHITE_URL
=
'http://
%
s:
%
s/render/'
%
(
graphite_host
,
graphite_port
)
GRAPHITE_URL
=
'http://
%
s:
%
s/render/'
%
(
graphite_host
,
graphite_port
)
else
:
else
:
GRAPHITE_URL
=
None
GRAPHITE_URL
=
None
SESSION_COOKIE_NAME
=
"csessid
%
x"
%
(((
getnode
()
//
139
)
^
(
getnode
()
%
983
))
&
0xffff
)
circle/circle/urls.py
View file @
5e496201
...
@@ -43,8 +43,9 @@ urlpatterns = patterns(
...
@@ -43,8 +43,9 @@ urlpatterns = patterns(
url
(
r'^network/'
,
include
(
'network.urls'
)),
url
(
r'^network/'
,
include
(
'network.urls'
)),
url
(
r'^dashboard/'
,
include
(
'dashboard.urls'
)),
url
(
r'^dashboard/'
,
include
(
'dashboard.urls'
)),
url
((
r'^accounts/reset/(?P<uidb36>[0-9A-Za-z]{1,13})-'
# django/contrib/auth/urls.py (care when new version)
'(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$'
),
url
((
r'^accounts/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/'
r'(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$'
),
'django.contrib.auth.views.password_reset_confirm'
,
'django.contrib.auth.views.password_reset_confirm'
,
{
'set_password_form'
:
CircleSetPasswordForm
},
{
'set_password_form'
:
CircleSetPasswordForm
},
name
=
'accounts.password_reset_confirm'
name
=
'accounts.password_reset_confirm'
...
@@ -64,3 +65,5 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
...
@@ -64,3 +65,5 @@ if get_env_variable('DJANGO_SAML', 'FALSE') == 'TRUE':
''
,
''
,
(
r'^saml2/'
,
include
(
'djangosaml2.urls'
)),
(
r'^saml2/'
,
include
(
'djangosaml2.urls'
)),
)
)
handler500
=
'common.views.handler500'
circle/common/models.py
View file @
5e496201
...
@@ -21,13 +21,19 @@ from hashlib import sha224
...
@@ -21,13 +21,19 @@ from hashlib import sha224
from
itertools
import
chain
,
imap
from
itertools
import
chain
,
imap
from
logging
import
getLogger
from
logging
import
getLogger
from
time
import
time
from
time
import
time
from
warnings
import
warn
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.core.cache
import
cache
from
django.core.cache
import
cache
from
django.db.models
import
(
CharField
,
DateTimeField
,
ForeignKey
,
from
django.core.serializers.json
import
DjangoJSONEncoder
NullBooleanField
,
TextField
)
from
django.db.models
import
(
CharField
,
DateTimeField
,
ForeignKey
,
NullBooleanField
)
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.encoding
import
force_text
from
django.utils.functional
import
Promise
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
jsonfield
import
JSONField
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
...
@@ -45,7 +51,11 @@ def activitycontextimpl(act, on_abort=None, on_commit=None):
...
@@ -45,7 +51,11 @@ def activitycontextimpl(act, on_abort=None, on_commit=None):
# BaseException is the common parent of Exception and
# BaseException is the common parent of Exception and
# system-exiting exceptions, e.g. KeyboardInterrupt
# system-exiting exceptions, e.g. KeyboardInterrupt
handler
=
None
if
on_abort
is
None
else
lambda
a
:
on_abort
(
a
,
e
)
handler
=
None
if
on_abort
is
None
else
lambda
a
:
on_abort
(
a
,
e
)
act
.
finish
(
succeeded
=
False
,
result
=
str
(
e
),
event_handler
=
handler
)
result
=
create_readable
(
ugettext_noop
(
"Failure."
),
ugettext_noop
(
"Unhandled exception: "
"
%(error)
s"
),
error
=
unicode
(
e
))
act
.
finish
(
succeeded
=
False
,
result
=
result
,
event_handler
=
handler
)
raise
e
raise
e
else
:
else
:
act
.
finish
(
succeeded
=
True
,
event_handler
=
on_commit
)
act
.
finish
(
succeeded
=
True
,
event_handler
=
on_commit
)
...
@@ -103,8 +113,23 @@ def split_activity_code(activity_code):
...
@@ -103,8 +113,23 @@ def split_activity_code(activity_code):
return
activity_code
.
split
(
activity_code_separator
)
return
activity_code
.
split
(
activity_code_separator
)
class
Encoder
(
DjangoJSONEncoder
):
def
default
(
self
,
obj
):
if
isinstance
(
obj
,
Promise
):
obj
=
force_text
(
obj
)
try
:
return
super
(
Encoder
,
self
)
.
default
(
obj
)
except
TypeError
:
return
unicode
(
obj
)
class
ActivityModel
(
TimeStampedModel
):
class
ActivityModel
(
TimeStampedModel
):
activity_code
=
CharField
(
max_length
=
100
,
verbose_name
=
_
(
'activity code'
))
activity_code
=
CharField
(
max_length
=
100
,
verbose_name
=
_
(
'activity code'
))
readable_name_data
=
JSONField
(
blank
=
True
,
null
=
True
,
dump_kwargs
=
{
"cls"
:
Encoder
},
verbose_name
=
_
(
'human readable name'
),
help_text
=
_
(
'Human readable name of '
'activity.'
))
parent
=
ForeignKey
(
'self'
,
blank
=
True
,
null
=
True
,
related_name
=
'children'
)
parent
=
ForeignKey
(
'self'
,
blank
=
True
,
null
=
True
,
related_name
=
'children'
)
task_uuid
=
CharField
(
blank
=
True
,
max_length
=
50
,
null
=
True
,
unique
=
True
,
task_uuid
=
CharField
(
blank
=
True
,
max_length
=
50
,
null
=
True
,
unique
=
True
,
help_text
=
_
(
'Celery task unique identifier.'
),
help_text
=
_
(
'Celery task unique identifier.'
),
...
@@ -120,8 +145,9 @@ class ActivityModel(TimeStampedModel):
...
@@ -120,8 +145,9 @@ class ActivityModel(TimeStampedModel):
succeeded
=
NullBooleanField
(
blank
=
True
,
null
=
True
,
succeeded
=
NullBooleanField
(
blank
=
True
,
null
=
True
,
help_text
=
_
(
'True, if the activity has '
help_text
=
_
(
'True, if the activity has '
'finished successfully.'
))
'finished successfully.'
))
result
=
TextField
(
verbose_name
=
_
(
'result'
),
blank
=
True
,
null
=
True
,
result_data
=
JSONField
(
verbose_name
=
_
(
'result'
),
blank
=
True
,
null
=
True
,
help_text
=
_
(
'Human readable result of activity.'
))
dump_kwargs
=
{
"cls"
:
Encoder
},
help_text
=
_
(
'Human readable result of activity.'
))
def
__unicode__
(
self
):
def
__unicode__
(
self
):
if
self
.
parent
:
if
self
.
parent
:
...
@@ -150,6 +176,29 @@ class ActivityModel(TimeStampedModel):
...
@@ -150,6 +176,29 @@ class ActivityModel(TimeStampedModel):
def
has_failed
(
self
):
def
has_failed
(
self
):
return
self
.
finished
and
not
self
.
succeeded
return
self
.
finished
and
not
self
.
succeeded
@property
def
readable_name
(
self
):
return
HumanReadableObject
.
from_dict
(
self
.
readable_name_data
)
@readable_name.setter
def
readable_name
(
self
,
value
):
self
.
readable_name_data
=
None
if
value
is
None
else
value
.
to_dict
()
@property
def
result
(
self
):
return
HumanReadableObject
.
from_dict
(
self
.
result_data
)
@result.setter
def
result
(
self
,
value
):
if
isinstance
(
value
,
basestring
):
warn
(
"Using string as result value is deprecated. Use "
"HumanReadableObject instead."
,
DeprecationWarning
,
stacklevel
=
2
)
value
=
create_readable
(
user_text_template
=
""
,
admin_text_template
=
value
)
self
.
result_data
=
None
if
value
is
None
else
value
.
to_dict
()
def
method_cache
(
memcached_seconds
=
60
,
instance_seconds
=
5
):
# noqa
def
method_cache
(
memcached_seconds
=
60
,
instance_seconds
=
5
):
# noqa
"""Cache return value of decorated method to memcached and memory.
"""Cache return value of decorated method to memcached and memory.
...
@@ -299,3 +348,79 @@ try:
...
@@ -299,3 +348,79 @@ try:
],
patterns
=
[
'common
\
.models
\
.'
])
],
patterns
=
[
'common
\
.models
\
.'
])
except
ImportError
:
except
ImportError
:
pass
pass
class
HumanReadableObject
(
object
):
def
__init__
(
self
,
user_text_template
,
admin_text_template
,
params
):
self
.
_set_values
(
user_text_template
,
admin_text_template
,
params
)
def
_set_values
(
self
,
user_text_template
,
admin_text_template
,
params
):
self
.
user_text_template
=
user_text_template
self
.
admin_text_template
=
admin_text_template
self
.
params
=
params
@classmethod
def
create
(
cls
,
user_text_template
,
admin_text_template
=
None
,
**
params
):
return
cls
(
user_text_template
,
admin_text_template
or
user_text_template
,
params
)
def
set
(
self
,
user_text_template
,
admin_text_template
=
None
,
**
params
):
self
.
_set_values
(
user_text_template
,
admin_text_template
or
user_text_template
,
params
)
@classmethod
def
from_dict
(
cls
,
d
):
return
None
if
d
is
None
else
cls
(
**
d
)
def
get_admin_text
(
self
):
if
self
.
admin_text_template
==
""
:
return
""
try
:
return
_
(
self
.
admin_text_template
)
%
self
.
params
except
KeyError
:
logger
.
exception
(
"Can't render admin_text_template '
%
s'
%% %
s"
,
self
.
admin_text_template
,
unicode
(
self
.
params
))
return
self
.
get_user_text
()
def
get_user_text
(
self
):
if
self
.
user_text_template
==
""
:
return
""
try
:
return
_
(
self
.
user_text_template
)
%
self
.
params
except
KeyError
:
logger
.
exception
(
"Can't render user_text_template '
%
s'
%% %
s"
,
self
.
user_text_template
,
unicode
(
self
.
params
))
return
self
.
user_text_template
def
to_dict
(
self
):
return
{
"user_text_template"
:
self
.
user_text_template
,
"admin_text_template"
:
self
.
admin_text_template
,
"params"
:
self
.
params
}
def
__unicode__
(
self
):
return
self
.
get_user_text
()
create_readable
=
HumanReadableObject
.
create
class
HumanReadableException
(
HumanReadableObject
,
Exception
):
"""HumanReadableObject that is an Exception so can used in except clause.
"""
pass
def
humanize_exception
(
message
,
exception
=
None
,
**
params
):
"""Return new dynamic-class exception which is based on
HumanReadableException and the original class with the dict of exception.
>>> try: raise humanize_exception("Welcome!", TypeError("hello"))
... except HumanReadableException as e: print e.get_admin_text()
...
Welcome!
"""
Ex
=
type
(
"HumanReadable"
+
type
(
exception
)
.
__name__
,
(
HumanReadableException
,
type
(
exception
)),
exception
.
__dict__
)
return
Ex
.
create
(
message
,
**
params
)
circle/common/operations.py
View file @
5e496201
...
@@ -74,7 +74,8 @@ class Operation(object):
...
@@ -74,7 +74,8 @@ class Operation(object):
self
.
check_auth
(
user
)
self
.
check_auth
(
user
)
self
.
check_precond
()
self
.
check_precond
()
activity
=
self
.
create_activity
(
parent
=
parent_activity
,
user
=
user
)
activity
=
self
.
create_activity
(
parent
=
parent_activity
,
user
=
user
,
kwargs
=
kwargs
)
return
activity
,
allargs
,
auxargs
return
activity
,
allargs
,
auxargs
...
@@ -150,7 +151,7 @@ class Operation(object):
...
@@ -150,7 +151,7 @@ class Operation(object):
raise
PermissionDenied
(
"
%
s doesn't have the required permissions."
raise
PermissionDenied
(
"
%
s doesn't have the required permissions."
%
user
)
%
user
)
def
create_activity
(
self
,
parent
,
user
):
def
create_activity
(
self
,
parent
,
user
,
kwargs
):
raise
NotImplementedError
raise
NotImplementedError
def
on_abort
(
self
,
activity
,
error
):
def
on_abort
(
self
,
activity
,
error
):
...
@@ -159,6 +160,18 @@ class Operation(object):
...
@@ -159,6 +160,18 @@ class Operation(object):
"""
"""
pass
pass
def
get_activity_name
(
self
,
kwargs
):
try
:
return
self
.
activity_name
except
AttributeError
:
try
:
return
self
.
name
.
_proxy____args
[
0
]
# ewww!
except
AttributeError
:
raise
ImproperlyConfigured
(
"Set Operation.activity_name to an ugettext_nooped "
"string or a create_readable call, or override "
"get_activity_name to create a name dynamically"
)
def
on_commit
(
self
,
activity
):
def
on_commit
(
self
,
activity
):
"""This method is called when the operation executes successfully.
"""This method is called when the operation executes successfully.
"""
"""
...
...
circle/common/views.py
0 → 100644
View file @
5e496201
from
sys
import
exc_info
import
logging
from
django.template
import
RequestContext
from
django.shortcuts
import
render_to_response
from
.models
import
HumanReadableException
logger
=
logging
.
getLogger
(
__name__
)
def
handler500
(
request
):
cls
,
exception
,
traceback
=
exc_info
()
logger
.
exception
(
"unhandled exception"
)
ctx
=
{}
if
isinstance
(
exception
,
HumanReadableException
):
try
:
ctx
[
'error'
]
=
exception
.
get_user_text
()
except
:
pass
else
:
try
:
if
request
.
user
.
is_superuser
():
ctx
[
'error'
]
=
exception
.
get_admin_text
()
except
:
pass
try
:
resp
=
render_to_response
(
"500.html"
,
ctx
,
RequestContext
(
request
))
except
:
resp
=
render_to_response
(
"500.html"
,
ctx
)
resp
.
status_code
=
500
return
resp
circle/dashboard/fixtures/test-vm-fixture.json
View file @
5e496201
...
@@ -1395,6 +1395,7 @@
...
@@ -1395,6 +1395,7 @@
"raw_data"
:
""
,
"raw_data"
:
""
,
"vnc_port"
:
1234
,
"vnc_port"
:
1234
,
"num_cores"
:
2
,
"num_cores"
:
2
,
"status"
:
"RUNNING"
,
"modified"
:
"2013-10-14T07:27:38.192Z"
"modified"
:
"2013-10-14T07:27:38.192Z"
}
}
},
},
...
...
circle/dashboard/migrations/0011_auto__add_field_notification_subject_data__add_field_notification_mess.py
0 → 100644
View file @
5e496201
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding field 'Notification.subject_data'
db
.
add_column
(
u'dashboard_notification'
,
'subject_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
),
keep_default
=
False
)
# Adding field 'Notification.message_data'
db
.
add_column
(
u'dashboard_notification'
,
'message_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
),
keep_default
=
False
)
def
backwards
(
self
,
orm
):
# Deleting field 'Notification.subject_data'
db
.
delete_column
(
u'dashboard_notification'
,
'subject_data'
)
# Deleting field 'Notification.message_data'
db
.
delete_column
(
u'dashboard_notification'
,
'message_data'
)
models
=
{
u'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"(u'content_type__app_label', u'content_type__model', u'codename')"
,
'unique_together'
:
"((u'content_type', u'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['contenttypes.ContentType']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
u'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Permission']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
u'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
u'dashboard.favourite'
:
{
'Meta'
:
{
'object_name'
:
'Favourite'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Instance']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
})
},
u'dashboard.futuremember'
:
{
'Meta'
:
{
'unique_together'
:
"(('org_id', 'group'),)"
,
'object_name'
:
'FutureMember'
},
'group'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
})
},
u'dashboard.groupprofile'
:
{
'Meta'
:
{
'object_name'
:
'GroupProfile'
},
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'group'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.Group']"
,
'unique'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'dashboard.notification'
:
{
'Meta'
:
{
'ordering'
:
"['-created']"
,
'object_name'
:
'Notification'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'message'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'message_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"'new'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'subject'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'subject_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'to'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'valid_until'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
})
},
u'dashboard.profile'
:
{
'Meta'
:
{
'object_name'
:
'Profile'
},
'email_notifications'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_limit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'5'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'preferred_language'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'en'"
,
'max_length'
:
'32'
}),
'use_gravatar'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'unique'
:
'True'
})
},
u'firewall.domain'
:
{
'Meta'
:
{
'object_name'
:
'Domain'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
u'firewall.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'firewall.host'
:
{
'Meta'
:
{
'ordering'
:
"('normalized_hostname', 'vlan')"
,
'unique_together'
:
"(('hostname', 'vlan'),)"
,
'object_name'
:
'Host'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'external_ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'ipv6'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'location'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'mac'
:
(
'firewall.fields.MACAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'17'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'normalized_hostname'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'80'
,
'monitor'
:
"'hostname'"
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'reverse'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'shared_ip'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'firewall.vlan'
:
{
'Meta'
:
{
'object_name'
:
'Vlan'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'dhcp_pool'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'domain'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Domain']"
}),
'host_ipv6_prefixlen'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'112'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv6_template'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0'"
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'network4'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
}),
'network6'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'network_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'portforward'"
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa'"
}),
'snat_ip'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'snat_to'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
u'storage.datastore'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'DataStore'
},
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'path'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'200'
})
},
u'storage.disk'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Disk'
},
'base'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'derivatives'"
,
'null'
:
'True'
,
'to'
:
u"orm['storage.Disk']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'datastore'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['storage.DataStore']"
}),
'destroyed'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'dev_num'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'a'"
,
'max_length'
:
'1'
}),
'filename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'256'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_ready'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'size'
:
(
'sizefield.models.FileSizeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
u'vm.instance'
:
{
'Meta'
:
{
'ordering'
:
"(u'pk',)"
,
'object_name'
:
'Instance'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'destroyed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'instance_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_base'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.Node']"
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"u'NOSTATE'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vnc_port'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'None'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instancetemplate'
:
{
'Meta'
:
{
'ordering'
:
"(u'name',)"
,
'object_name'
:
'InstanceTemplate'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'template_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.InstanceTemplate']"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'blank'
:
'True'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
u'vm.lease'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Lease'
},
'delete_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'suspend_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.node'
:
{
'Meta'
:
{
'ordering'
:
"(u'-enabled', u'normalized_name')"
,
'object_name'
:
'Node'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'normalized_name'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'100'
,
'monitor'
:
"u'name'"
,
'blank'
:
'True'
}),
'overcommit'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'default'
:
'1.0'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'vm.trait'
:
{
'Meta'
:
{
'object_name'
:
'Trait'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'dashboard'
]
\ No newline at end of file
circle/dashboard/migrations/0012_migrate_messages.py
0 → 100644
View file @
5e496201
# -*- coding: utf-8 -*-
from
south.v2
import
DataMigration
class
Migration
(
DataMigration
):
def
forwards
(
self
,
orm
):
for
n
in
orm
.
Notification
.
objects
.
all
():
n
.
subject_data
=
{
"user_text_template"
:
n
.
subject
.
replace
(
"
%
"
,
"
%%
"
),
"admin_text_template"
:
""
,
"params"
:
{}}
n
.
message_data
=
{
"user_text_template"
:
n
.
message
.
replace
(
"
%
"
,
"
%%
"
),
"admin_text_template"
:
""
,
"params"
:
{}}
n
.
save
()
def
backwards
(
self
,
orm
):
for
n
in
orm
.
Notification
.
objects
.
all
():
if
n
.
subject_data
:
n
.
subject
=
(
n
.
subject_data
[
"user_text_template"
]
%
n
.
subject_data
[
"params"
])
if
n
.
message_data
:
n
.
message
=
(
n
.
message_data
[
"user_text_template"
]
%
n
.
message_data
[
"params"
])
n
.
save
()
models
=
{
u'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"(u'content_type__app_label', u'content_type__model', u'codename')"
,
'unique_together'
:
"((u'content_type', u'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['contenttypes.ContentType']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
u'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Permission']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
u'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
u'dashboard.favourite'
:
{
'Meta'
:
{
'object_name'
:
'Favourite'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Instance']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
})
},
u'dashboard.futuremember'
:
{
'Meta'
:
{
'unique_together'
:
"(('org_id', 'group'),)"
,
'object_name'
:
'FutureMember'
},
'group'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
})
},
u'dashboard.groupprofile'
:
{
'Meta'
:
{
'object_name'
:
'GroupProfile'
},
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'group'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.Group']"
,
'unique'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'dashboard.notification'
:
{
'Meta'
:
{
'ordering'
:
"['-created']"
,
'object_name'
:
'Notification'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'message'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'message_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"'new'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'subject'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'subject_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'to'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'valid_until'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
})
},
u'dashboard.profile'
:
{
'Meta'
:
{
'object_name'
:
'Profile'
},
'email_notifications'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_limit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'5'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'preferred_language'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'en'"
,
'max_length'
:
'32'
}),
'use_gravatar'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'unique'
:
'True'
})
},
u'firewall.domain'
:
{
'Meta'
:
{
'object_name'
:
'Domain'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
u'firewall.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'firewall.host'
:
{
'Meta'
:
{
'ordering'
:
"('normalized_hostname', 'vlan')"
,
'unique_together'
:
"(('hostname', 'vlan'),)"
,
'object_name'
:
'Host'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'external_ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'ipv6'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'location'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'mac'
:
(
'firewall.fields.MACAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'17'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'normalized_hostname'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'80'
,
'monitor'
:
"'hostname'"
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'reverse'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'shared_ip'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'firewall.vlan'
:
{
'Meta'
:
{
'object_name'
:
'Vlan'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'dhcp_pool'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'domain'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Domain']"
}),
'host_ipv6_prefixlen'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'112'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv6_template'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0'"
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'network4'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
}),
'network6'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'network_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'portforward'"
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa'"
}),
'snat_ip'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'snat_to'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
u'storage.datastore'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'DataStore'
},
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'path'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'200'
})
},
u'storage.disk'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Disk'
},
'base'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'derivatives'"
,
'null'
:
'True'
,
'to'
:
u"orm['storage.Disk']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'datastore'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['storage.DataStore']"
}),
'destroyed'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'dev_num'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'a'"
,
'max_length'
:
'1'
}),
'filename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'256'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_ready'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'size'
:
(
'sizefield.models.FileSizeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
u'vm.instance'
:
{
'Meta'
:
{
'ordering'
:
"(u'pk',)"
,
'object_name'
:
'Instance'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'destroyed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'instance_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_base'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.Node']"
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"u'NOSTATE'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vnc_port'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'None'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instancetemplate'
:
{
'Meta'
:
{
'ordering'
:
"(u'name',)"
,
'object_name'
:
'InstanceTemplate'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'template_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.InstanceTemplate']"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'blank'
:
'True'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
u'vm.lease'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Lease'
},
'delete_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'suspend_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.node'
:
{
'Meta'
:
{
'ordering'
:
"(u'-enabled', u'normalized_name')"
,
'object_name'
:
'Node'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'normalized_name'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'100'
,
'monitor'
:
"u'name'"
,
'blank'
:
'True'
}),
'overcommit'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'default'
:
'1.0'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'vm.trait'
:
{
'Meta'
:
{
'object_name'
:
'Trait'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'dashboard'
]
symmetrical
=
True
circle/dashboard/migrations/0013_auto__del_field_notification_message__del_field_notification_subject.py
0 → 100644
View file @
5e496201
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Deleting field 'Notification.message'
db
.
delete_column
(
u'dashboard_notification'
,
'message'
)
# Deleting field 'Notification.subject'
db
.
delete_column
(
u'dashboard_notification'
,
'subject'
)
def
backwards
(
self
,
orm
):
# Adding field 'Notification.message'
db
.
add_column
(
u'dashboard_notification'
,
'message'
,
self
.
gf
(
'django.db.models.fields.TextField'
)(
default
=
''
),
keep_default
=
False
)
# Adding field 'Notification.subject'
db
.
add_column
(
u'dashboard_notification'
,
'subject'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
''
,
max_length
=
128
),
keep_default
=
False
)
models
=
{
u'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"(u'content_type__app_label', u'content_type__model', u'codename')"
,
'unique_together'
:
"((u'content_type', u'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['contenttypes.ContentType']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
u'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Permission']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
u'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
u'dashboard.favourite'
:
{
'Meta'
:
{
'object_name'
:
'Favourite'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Instance']"
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
})
},
u'dashboard.futuremember'
:
{
'Meta'
:
{
'unique_together'
:
"(('org_id', 'group'),)"
,
'object_name'
:
'FutureMember'
},
'group'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
})
},
u'dashboard.groupprofile'
:
{
'Meta'
:
{
'object_name'
:
'GroupProfile'
},
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'group'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.Group']"
,
'unique'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'dashboard.notification'
:
{
'Meta'
:
{
'ordering'
:
"['-created']"
,
'object_name'
:
'Notification'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'message_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"'new'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'subject_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
}),
'to'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'valid_until'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
})
},
u'dashboard.profile'
:
{
'Meta'
:
{
'object_name'
:
'Profile'
},
'email_notifications'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_limit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'5'
}),
'org_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'64'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'preferred_language'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'en'"
,
'max_length'
:
'32'
}),
'use_gravatar'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.OneToOneField'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'unique'
:
'True'
})
},
u'firewall.domain'
:
{
'Meta'
:
{
'object_name'
:
'Domain'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
u'firewall.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'firewall.host'
:
{
'Meta'
:
{
'ordering'
:
"('normalized_hostname', 'vlan')"
,
'unique_together'
:
"(('hostname', 'vlan'),)"
,
'object_name'
:
'Host'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'external_ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'ipv6'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'location'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'mac'
:
(
'firewall.fields.MACAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'17'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'normalized_hostname'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'80'
,
'monitor'
:
"'hostname'"
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'reverse'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'shared_ip'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'firewall.vlan'
:
{
'Meta'
:
{
'object_name'
:
'Vlan'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'dhcp_pool'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'domain'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Domain']"
}),
'host_ipv6_prefixlen'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'112'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv6_template'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0'"
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'network4'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
}),
'network6'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'network_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'portforward'"
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa'"
}),
'snat_ip'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'snat_to'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
u'storage.datastore'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'DataStore'
},
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'path'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'200'
})
},
u'storage.disk'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Disk'
},
'base'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'derivatives'"
,
'null'
:
'True'
,
'to'
:
u"orm['storage.Disk']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'datastore'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['storage.DataStore']"
}),
'destroyed'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'dev_num'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'a'"
,
'max_length'
:
'1'
}),
'filename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'256'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_ready'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'size'
:
(
'sizefield.models.FileSizeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
u'vm.instance'
:
{
'Meta'
:
{
'ordering'
:
"(u'pk',)"
,
'object_name'
:
'Instance'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'destroyed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'instance_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_base'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.Node']"
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"u'NOSTATE'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vnc_port'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'None'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instancetemplate'
:
{
'Meta'
:
{
'ordering'
:
"(u'name',)"
,
'object_name'
:
'InstanceTemplate'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'template_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.InstanceTemplate']"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'blank'
:
'True'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
u'vm.lease'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Lease'
},
'delete_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'suspend_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.node'
:
{
'Meta'
:
{
'ordering'
:
"(u'-enabled', u'normalized_name')"
,
'object_name'
:
'Node'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'normalized_name'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'100'
,
'monitor'
:
"u'name'"
,
'blank'
:
'True'
}),
'overcommit'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'default'
:
'1.0'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'vm.trait'
:
{
'Meta'
:
{
'object_name'
:
'Trait'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'dashboard'
]
\ No newline at end of file
circle/dashboard/models.py
View file @
5e496201
...
@@ -30,16 +30,17 @@ from django.db.models import (
...
@@ -30,16 +30,17 @@ from django.db.models import (
DateTimeField
,
permalink
,
BooleanField
DateTimeField
,
permalink
,
BooleanField
)
)
from
django.db.models.signals
import
post_save
,
pre_delete
from
django.db.models.signals
import
post_save
,
pre_delete
from
django.template.loader
import
render_to_string
from
django.templatetags.static
import
static
from
django.templatetags.static
import
static
from
django.utils.translation
import
ugettext_lazy
as
_
,
override
,
ugettext
from
django.utils.translation
import
ugettext_lazy
as
_
from
django_sshkey.models
import
UserKey
from
django_sshkey.models
import
UserKey
from
jsonfield
import
JSONField
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
from
model_utils.fields
import
StatusField
from
model_utils.fields
import
StatusField
from
model_utils
import
Choices
from
model_utils
import
Choices
from
acl.models
import
AclBase
from
acl.models
import
AclBase
from
common.models
import
HumanReadableObject
,
create_readable
,
Encoder
from
vm.tasks.agent_tasks
import
add_keys
,
del_keys
from
vm.tasks.agent_tasks
import
add_keys
,
del_keys
...
@@ -58,26 +59,39 @@ class Notification(TimeStampedModel):
...
@@ -58,26 +59,39 @@ class Notification(TimeStampedModel):
status
=
StatusField
()
status
=
StatusField
()
to
=
ForeignKey
(
User
)
to
=
ForeignKey
(
User
)
subject
=
CharField
(
max_length
=
128
)
subject
_data
=
JSONField
(
null
=
True
,
dump_kwargs
=
{
"cls"
:
Encoder
}
)
message
=
TextField
(
)
message
_data
=
JSONField
(
null
=
True
,
dump_kwargs
=
{
"cls"
:
Encoder
}
)
valid_until
=
DateTimeField
(
null
=
True
,
default
=
None
)
valid_until
=
DateTimeField
(
null
=
True
,
default
=
None
)
class
Meta
:
class
Meta
:
ordering
=
[
'-created'
]
ordering
=
[
'-created'
]
@classmethod
@classmethod
def
send
(
cls
,
user
,
subject
,
template
,
context
=
{},
valid_until
=
None
):
def
send
(
cls
,
user
,
subject
,
template
,
context
,
try
:
valid_until
=
None
,
subject_context
=
None
):
language
=
user
.
profile
.
preferred_language
hro
=
create_readable
(
template
,
user
=
user
,
**
context
)
except
:
subject
=
create_readable
(
subject
,
subject_context
or
context
)
language
=
None
return
cls
.
objects
.
create
(
to
=
user
,
with
override
(
language
):
subject_data
=
subject
.
to_dict
(),
context
[
'user'
]
=
user
message_data
=
hro
.
to_dict
(),
rendered
=
render_to_string
(
template
,
context
)
subject
=
ugettext
(
unicode
(
subject
))
return
cls
.
objects
.
create
(
to
=
user
,
subject
=
subject
,
message
=
rendered
,
valid_until
=
valid_until
)
valid_until
=
valid_until
)
@property
def
subject
(
self
):
return
HumanReadableObject
.
from_dict
(
self
.
subject_data
)
@subject.setter
def
subject
(
self
,
value
):
self
.
subject_data
=
None
if
value
is
None
else
value
.
to_dict
()
@property
def
message
(
self
):
return
HumanReadableObject
.
from_dict
(
self
.
message_data
)
@message.setter
def
message
(
self
,
value
):
self
.
message_data
=
None
if
value
is
None
else
value
.
to_dict
()
class
Profile
(
Model
):
class
Profile
(
Model
):
user
=
OneToOneField
(
User
)
user
=
OneToOneField
(
User
)
...
@@ -96,8 +110,11 @@ class Profile(Model):
...
@@ -96,8 +110,11 @@ class Profile(Model):
verbose_name
=
_
(
"Email notifications"
),
default
=
True
,
verbose_name
=
_
(
"Email notifications"
),
default
=
True
,
help_text
=
_
(
'Whether user wants to get digested email notifications.'
))
help_text
=
_
(
'Whether user wants to get digested email notifications.'
))
def
notify
(
self
,
subject
,
template
,
context
=
{},
valid_until
=
None
):
def
notify
(
self
,
subject
,
template
,
context
=
None
,
valid_until
=
None
,
return
Notification
.
send
(
self
.
user
,
subject
,
template
,
context
,
**
kwargs
):
if
context
is
not
None
:
kwargs
.
update
(
context
)
return
Notification
.
send
(
self
.
user
,
subject
,
template
,
kwargs
,
valid_until
)
valid_until
)
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
...
...
circle/dashboard/static/dashboard/dashboard.js
View file @
5e496201
...
@@ -56,8 +56,6 @@ $(function () {
...
@@ -56,8 +56,6 @@ $(function () {
url
:
'/dashboard/template/choose/'
,
url
:
'/dashboard/template/choose/'
,
success
:
function
(
data
)
{
success
:
function
(
data
)
{
$
(
'body'
).
append
(
data
);
$
(
'body'
).
append
(
data
);
vmCreateLoaded
();
addSliderMiscs
();
$
(
'#create-modal'
).
modal
(
'show'
);
$
(
'#create-modal'
).
modal
(
'show'
);
$
(
'#create-modal'
).
on
(
'hidden.bs.modal'
,
function
()
{
$
(
'#create-modal'
).
on
(
'hidden.bs.modal'
,
function
()
{
$
(
'#create-modal'
).
remove
();
$
(
'#create-modal'
).
remove
();
...
...
circle/dashboard/static/dashboard/vm-common.js
View file @
5e496201
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
$
(
function
()
{
$
(
function
()
{
/* vm operations */
/* vm operations */
$
(
'#ops, #vm-details-resources-disk'
).
on
(
'click'
,
'.operation.btn'
,
function
(
e
)
{
$
(
'#ops, #vm-details-resources-disk
, #vm-details-renew-op
'
).
on
(
'click'
,
'.operation.btn'
,
function
(
e
)
{
var
icon
=
$
(
this
).
children
(
"i"
).
addClass
(
'fa-spinner fa-spin'
);
var
icon
=
$
(
this
).
children
(
"i"
).
addClass
(
'fa-spinner fa-spin'
);
$
.
ajax
({
$
.
ajax
({
...
@@ -53,7 +53,7 @@ $(function() {
...
@@ -53,7 +53,7 @@ $(function() {
/* if there are messages display them */
/* if there are messages display them */
if
(
data
.
messages
&&
data
.
messages
.
length
>
0
)
{
if
(
data
.
messages
&&
data
.
messages
.
length
>
0
)
{
addMessage
(
data
.
messages
.
join
(
"<br />"
),
"danger"
);
addMessage
(
data
.
messages
.
join
(
"<br />"
),
data
.
success
?
"success"
:
"danger"
);
}
}
}
}
else
{
else
{
...
...
circle/dashboard/templates/dashboard/_notifications-timeline.html
View file @
5e496201
{% load i18n %}
{% load i18n %}
{% for n in notifications %}
{% for n in notifications %}
<li
class=
"notification-message"
>
<li
class=
"notification-message"
id=
"msg-{{n.id}}"
>
<span
class=
"notification-message-subject"
>
<span
class=
"notification-message-subject"
>
{% if n.status == "new" %}
<i
class=
"fa fa-envelope-alt"
></i>
{% endif %}
{% if n.status == "new" %}
<i
class=
"fa fa-envelope-alt"
></i>
{% endif %}
{{ n.subject }}
{{ n.subject
.get_user_text
}}
</span>
</span>
<span
class=
"notification-message-date pull-right"
>
<span
class=
"notification-message-date pull-right"
title=
"{{n.created}}"
>
{{ n.created|timesince }}
{{ n.created|timesince }}
</span>
</span>
<div
style=
"clear: both;"
></div>
<div
style=
"clear: both;"
></div>
<div
class=
"notification-message-text"
>
<div
class=
"notification-message-text"
>
{{ n.message|safe }}
{{ n.message
.get_user_text
|safe }}
</div>
</div>
</li>
</li>
{% empty %}
{% empty %}
...
...
circle/dashboard/templates/dashboard/_template-choose.html
View file @
5e496201
{% load i18n %}
{% load i18n %}
<div
class=
"alert alert-info"
id=
"template-choose-alert"
>
<div
class=
"alert alert-info"
id=
"template-choose-alert"
>
{% trans "Customize an existing template or create a brand new one from scratch!" %}
{% if perms.vm.create_base_template %}
{% trans "Customize an existing template or create a brand new one from scratch." %}
{% else %}
{% trans "Customize an existing template." %}
{% endif %}
</div>
</div>
<form
action=
"{% url "
dashboard
.
views
.
template-choose
"
%}"
method=
"POST"
<form
action=
"{% url "
dashboard
.
views
.
template-choose
"
%}"
method=
"POST"
...
...
circle/dashboard/templates/dashboard/instanceactivity_detail.html
View file @
5e496201
...
@@ -5,7 +5,12 @@
...
@@ -5,7 +5,12 @@
<div
class=
"body-content"
>
<div
class=
"body-content"
>
<div
class=
"page-header"
>
<div
class=
"page-header"
>
<h1>
<h1>
{{ object.instance.name }}: {{ object.get_readable_name }}
{{ object.instance.name }}:
{% if user.is_superuser %}
{{object.readable_name.get_admin_text}}
{% else %}
{{object.readable_name.get_user_text}}
{% endif %}
</h1>
</h1>
</div>
</div>
<div
class=
"row"
>
<div
class=
"row"
>
...
@@ -53,7 +58,7 @@
...
@@ -53,7 +58,7 @@
<dt>
{% trans "result" %}
</dt>
<dt>
{% trans "result" %}
</dt>
<dd><textarea
class=
"form-control"
>
{
{object.result}
}
</textarea></dd>
<dd><textarea
class=
"form-control"
>
{
% if user.is_superuser %}{{object.result.get_admin_text}}{% else %}{{object.result.get_admin_text}}{% endif %
}
</textarea></dd>
<dt>
{% trans "resultant state" %}
</dt>
<dt>
{% trans "resultant state" %}
</dt>
<dd>
{{object.resultant_state|default:'n/a'}}
</dd>
<dd>
{{object.resultant_state|default:'n/a'}}
</dd>
...
...
circle/dashboard/templates/dashboard/node-detail/_activity-timeline.html
View file @
5e496201
...
@@ -3,15 +3,22 @@
...
@@ -3,15 +3,22 @@
{% for a in activities %}
{% for a in activities %}
<div
class=
"activity"
data-activity-id=
"{{ a.pk }}"
>
<div
class=
"activity"
data-activity-id=
"{{ a.pk }}"
>
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<i
class=
"fa
{% if not a.finished %}fa-refresh fa-spin {% else %}fa
fa-plus{% endif %}"
></i>
<i
class=
"fa
{% if not a.finished %}fa-refresh fa-spin {% else %}
fa-plus{% endif %}"
></i>
</span>
</span>
<strong>
{{ a.get_readable_name }}
</strong>
<strong>
{% if user.is_superuser %}
{{ a.readable_name.get_admin_text }}
{% else %}
{{ a.readable_name.get_user_text }}{% endif %}
</strong>
{{ a.started|date:"Y-m-d H:i" }}, {{ a.user }}
{{ a.started|date:"Y-m-d H:i" }}, {{ a.user }}
{% if a.children.count > 0 %}
{% if a.children.count > 0 %}
<div
class=
"sub-timeline"
>
<div
class=
"sub-timeline"
>
{% for s in a.children.all %}
{% for s in a.children.all %}
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}"
>
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}"
>
{{ s.get_readable_name }} -
{% if user.is_superuser %}
{{ s.readable_name.get_admin_text }}
{% else %}
{{ s.readable_name.get_user_text }}{% endif %}
–
{% if s.finished %}
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
{{ s.finished|time:"H:i:s" }}
{% else %}
{% else %}
...
...
circle/dashboard/templates/dashboard/notifications/ownership-accepted.html
deleted
100644 → 0
View file @
38e373e3
{%load i18n%}
{%blocktrans with instance=instance.name user=user.name%}
Your ownership offer of {{instance}} has been accepted by {{user}}.
{%endblocktrans%}
circle/dashboard/templates/dashboard/notifications/ownership-offer.html
deleted
100644 → 0
View file @
38e373e3
{%load i18n%}
{%blocktrans with instance=instance.name user=user.name%}
{{user}} offered you to take the ownership of his/her virtual machine
called {{instance}}.{%endblocktrans%}
<a
href=
"{{token}}"
class=
"btn btn-success btn-small"
>
{%trans "Accept"%}
</a>
circle/dashboard/templates/dashboard/notifications/vm-destroyed.html
deleted
100644 → 0
View file @
38e373e3
{%load i18n%}
{%blocktrans with instance=instance.name url=instance.get_absolute_url %}
Your instance
<a
href=
"{{url}}"
>
{{instance}}
</a>
has been destroyed due to expiration.
{%endblocktrans%}
circle/dashboard/templates/dashboard/notifications/vm-expiring.html
deleted
100644 → 0
View file @
38e373e3
{%load i18n%}
{%blocktrans with instance=instance.name url=instance.get_absolute_url suspend=instance.time_of_suspend delete=instance.time_of_delete %}
Your instance
<a
href=
"{{url}}"
>
{{instance}}
</a>
is going to expire.
It will be suspended at {{suspend}} and destroyed at {{delete}}.
{%endblocktrans%}
{%blocktrans with token=token url=instance.get_absolute_url %}
Please, either
<a
href=
"{{token}}"
>
renew
</a>
or
<a
href=
"{{url}}"
>
destroy
</a>
it now.
{%endblocktrans%}
circle/dashboard/templates/dashboard/notifications/vm-suspended.html
deleted
100644 → 0
View file @
38e373e3
{%load i18n%}
{%blocktrans with instance=instance.name url=instance.get_absolute_url %}
Your instance
<a
href=
"{{url}}"
>
{{instance}}
</a>
has been suspended due to expiration.
{%endblocktrans%}
circle/dashboard/templates/dashboard/template-list.html
View file @
5e496201
...
@@ -10,8 +10,8 @@
...
@@ -10,8 +10,8 @@
<div
class=
"col-md-12"
>
<div
class=
"col-md-12"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
>
<div
class=
"panel-heading"
>
<a
href=
"{% url "
dashboard
.
views
.
template-c
reate
"
%}"
class=
"pull-right btn btn-success btn-xs
"
>
<a
href=
"{% url "
dashboard
.
views
.
template-c
hoose
"
%}"
class=
"pull-right btn btn-success btn-xs template-choose
"
>
<i
class=
"fa fa-plus"
></i>
{% trans "new
base vm
" %}
<i
class=
"fa fa-plus"
></i>
{% trans "new
template
" %}
</a>
</a>
<h3
class=
"no-margin"
><i
class=
"fa fa-puzzle-piece"
></i>
{% trans "Templates" %}
</h3>
<h3
class=
"no-margin"
><i
class=
"fa fa-puzzle-piece"
></i>
{% trans "Templates" %}
</h3>
</div>
</div>
...
...
circle/dashboard/templates/dashboard/vm-detail/_activity-timeline.html
View file @
5e496201
...
@@ -4,10 +4,10 @@
...
@@ -4,10 +4,10 @@
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<span
class=
"timeline-icon{% if a.has_failed %} timeline-icon-failed{% endif %}"
>
<i
class=
"fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-plus{% endif %}"
></i>
<i
class=
"fa {% if not a.finished %}fa-refresh fa-spin {% else %}fa-plus{% endif %}"
></i>
</span>
</span>
<strong
{%
if
user
.
is_superuser
and
a
.
result
%}
title=
"{{ a.resul
t }}"
{%
endif
%}
>
<strong
{%
if
a
.
result
%}
title=
"{{ a.result.get_user_tex
t }}"
{%
endif
%}
>
{% if user.is_superuser %}
<a
href=
"{{ a.get_absolute_url }}"
>
{% endif %}
<a
href=
"{{ a.get_absolute_url }}"
>
{% if a.times > 1 %}({{ a.times }}x){% endif %}
{% if a.times > 1 %}({{ a.times }}x){% endif %}
{{ a.
get_readable_name }}{% if user.is_superuser %}
</a>
{% endif %}
{{ a.
readable_name.get_user_text }}
</a>
{% if a.has_percent %}
{% if a.has_percent %}
- {{ a.percentage }}%
- {{ a.percentage }}%
...
@@ -30,9 +30,9 @@
...
@@ -30,9 +30,9 @@
<div
class=
"sub-timeline"
>
<div
class=
"sub-timeline"
>
{% for s in a.children.all %}
{% for s in a.children.all %}
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}{% if s.pk == active.pk %} sub-activity-active{% endif %}"
>
<div
data-activity-id=
"{{ s.pk }}"
class=
"sub-activity{% if s.has_failed %} sub-activity-failed{% endif %}{% if s.pk == active.pk %} sub-activity-active{% endif %}"
>
<span
{%
if
user
.
is_superuser
and
s
.
result
%}
title=
"{{ s.resul
t }}"
{%
endif
%}
>
<span
{%
if
s
.
result
%}
title=
"{{ s.result.get_user_tex
t }}"
{%
endif
%}
>
{% if user.is_superuser %}
<a
href=
"{{ s.get_absolute_url }}"
>
{% endif %}
<a
href=
"{{ s.get_absolute_url }}"
>
{{ s.
get_readable_name }}{% if user.is_superuser %}
</a>
{% endif %}
</span>
–
{{ s.
readable_name.get_user_text }}
</a>
</span>
–
{% if s.finished %}
{% if s.finished %}
{{ s.finished|time:"H:i:s" }}
{{ s.finished|time:"H:i:s" }}
{% else %}
{% else %}
...
...
circle/dashboard/templates/dashboard/vm-detail/_disk-operations.html
View file @
5e496201
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
{% for op in ops %}
{% for op in ops %}
{% if op.is_disk_operation %}
{% if op.is_disk_operation %}
<a
href=
"{{op.get_url}}"
class=
"btn btn-success btn-xs
<a
href=
"{{op.get_url}}"
class=
"btn btn-success btn-xs
operation operation-{{op.op}}
btn btn-default
"
>
operation operation-{{op.op}}"
>
<i
class=
"fa fa-{{op.icon}}"
></i>
<i
class=
"fa fa-{{op.icon}}"
></i>
{{op.name}}
</a>
{{op.name}}
</a>
{% endif %}
{% endif %}
...
...
circle/dashboard/templates/dashboard/vm-detail/home.html
View file @
5e496201
...
@@ -47,12 +47,14 @@
...
@@ -47,12 +47,14 @@
</dl>
</dl>
<h4>
{% trans "Expiration" %} {% if instance.is_expiring %}
<i
class=
"fa fa-warning-sign text-danger"
></i>
{% endif %}
<h4>
{% trans "Expiration" %} {% if instance.is_expiring %}
<i
class=
"fa fa-warning-sign text-danger"
></i>
{% endif %}
<span
id=
"vm-details-renew-op"
>
{% with op=op.renew %}
{% with op=op.renew %}
<a
href=
"{{op.get_url}}"
class=
"btn btn-success btn-xs
<a
href=
"{{op.get_url}}"
class=
"btn btn-success btn-xs
operation operation-{{op.op}}
btn btn-default
"
>
operation operation-{{op.op}}"
>
<i
class=
"fa fa-{{op.icon}}"
></i>
<i
class=
"fa fa-{{op.icon}}"
></i>
{{op.name}}
</a>
{{op.name}}
</a>
{% endwith %}
{% endwith %}
</span>
</h4>
</h4>
<dl>
<dl>
<dt>
{% trans "Suspended at:" %}
</dt>
<dt>
{% trans "Suspended at:" %}
</dt>
...
...
circle/dashboard/tests/test_mockedviews.py
View file @
5e496201
...
@@ -47,7 +47,7 @@ class ViewUserTestCase(unittest.TestCase):
...
@@ -47,7 +47,7 @@ class ViewUserTestCase(unittest.TestCase):
go
.
return_value
=
MagicMock
(
spec
=
InstanceActivity
)
go
.
return_value
=
MagicMock
(
spec
=
InstanceActivity
)
go
.
return_value
.
_meta
.
object_name
=
"InstanceActivity"
go
.
return_value
.
_meta
.
object_name
=
"InstanceActivity"
view
=
InstanceActivityDetail
.
as_view
()
view
=
InstanceActivityDetail
.
as_view
()
self
.
assertEquals
(
view
(
request
,
pk
=
1234
)
.
status_code
,
302
)
self
.
assertEquals
(
view
(
request
,
pk
=
1234
)
.
status_code
,
200
)
def
test_found
(
self
):
def
test_found
(
self
):
request
=
FakeRequestFactory
(
superuser
=
True
)
request
=
FakeRequestFactory
(
superuser
=
True
)
...
@@ -436,7 +436,8 @@ def FakeRequestFactory(user=None, **kwargs):
...
@@ -436,7 +436,8 @@ def FakeRequestFactory(user=None, **kwargs):
if
user
is
None
:
if
user
is
None
:
user
=
UserFactory
()
user
=
UserFactory
()
user
.
is_authenticated
=
lambda
:
kwargs
.
pop
(
'authenticated'
,
True
)
auth
=
kwargs
.
pop
(
'authenticated'
,
True
)
user
.
is_authenticated
=
lambda
:
auth
user
.
is_superuser
=
kwargs
.
pop
(
'superuser'
,
False
)
user
.
is_superuser
=
kwargs
.
pop
(
'superuser'
,
False
)
if
kwargs
.
pop
(
'has_perms_mock'
,
False
):
if
kwargs
.
pop
(
'has_perms_mock'
,
False
):
user
.
has_perms
=
MagicMock
(
return_value
=
True
)
user
.
has_perms
=
MagicMock
(
return_value
=
True
)
...
@@ -455,7 +456,8 @@ def FakeRequestFactory(user=None, **kwargs):
...
@@ -455,7 +456,8 @@ def FakeRequestFactory(user=None, **kwargs):
request
.
GET
.
update
(
kwargs
.
pop
(
'GET'
,
{}))
request
.
GET
.
update
(
kwargs
.
pop
(
'GET'
,
{}))
if
len
(
kwargs
):
if
len
(
kwargs
):
warnings
.
warn
(
"FakeRequestFactory kwargs unused: "
+
unicode
(
kwargs
))
warnings
.
warn
(
"FakeRequestFactory kwargs unused: "
+
unicode
(
kwargs
),
stacklevel
=
2
)
return
request
return
request
...
...
circle/dashboard/tests/test_models.py
View file @
5e496201
...
@@ -36,12 +36,12 @@ class NotificationTestCase(TestCase):
...
@@ -36,12 +36,12 @@ class NotificationTestCase(TestCase):
c2
=
self
.
u2
.
notification_set
.
count
()
c2
=
self
.
u2
.
notification_set
.
count
()
profile
=
self
.
u1
.
profile
profile
=
self
.
u1
.
profile
msg
=
profile
.
notify
(
'subj'
,
msg
=
profile
.
notify
(
'subj'
,
'
dashboard/test_message.txt
'
,
'
%(var)
s
%(user)
s
'
,
{
'var'
:
'testme'
})
{
'var'
:
'testme'
})
assert
self
.
u1
.
notification_set
.
count
()
==
c1
+
1
assert
self
.
u1
.
notification_set
.
count
()
==
c1
+
1
assert
self
.
u2
.
notification_set
.
count
()
==
c2
assert
self
.
u2
.
notification_set
.
count
()
==
c2
assert
'user1'
in
msg
.
message
assert
'user1'
in
unicode
(
msg
.
message
)
assert
'testme'
in
msg
.
message
assert
'testme'
in
unicode
(
msg
.
message
)
assert
msg
in
self
.
u1
.
notification_set
.
all
()
assert
msg
in
self
.
u1
.
notification_set
.
all
()
...
...
circle/dashboard/tests/test_views.py
View file @
5e496201
...
@@ -199,6 +199,8 @@ class VmDetailTest(LoginMixin, TestCase):
...
@@ -199,6 +199,8 @@ class VmDetailTest(LoginMixin, TestCase):
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
=
Instance
.
objects
.
get
(
pk
=
1
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
inst
.
add_interface
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
1
),
user
=
self
.
us
)
inst
.
add_interface
(
vlan
=
Vlan
.
objects
.
get
(
pk
=
1
),
user
=
self
.
us
)
inst
.
status
=
'RUNNING'
inst
.
save
()
iface_count
=
inst
.
interface_set
.
count
()
iface_count
=
inst
.
interface_set
.
count
()
c
.
post
(
"/dashboard/interface/1/delete/"
)
c
.
post
(
"/dashboard/interface/1/delete/"
)
...
@@ -211,6 +213,8 @@ class VmDetailTest(LoginMixin, TestCase):
...
@@ -211,6 +213,8 @@ class VmDetailTest(LoginMixin, TestCase):
inst
.
set_level
(
self
.
u1
,
'owner'
)
inst
.
set_level
(
self
.
u1
,
'owner'
)
vlan
=
Vlan
.
objects
.
get
(
pk
=
1
)
vlan
=
Vlan
.
objects
.
get
(
pk
=
1
)
inst
.
add_interface
(
vlan
=
vlan
,
user
=
self
.
us
)
inst
.
add_interface
(
vlan
=
vlan
,
user
=
self
.
us
)
inst
.
status
=
'RUNNING'
inst
.
save
()
iface_count
=
inst
.
interface_set
.
count
()
iface_count
=
inst
.
interface_set
.
count
()
response
=
c
.
post
(
"/dashboard/interface/1/delete/"
,
response
=
c
.
post
(
"/dashboard/interface/1/delete/"
,
...
@@ -337,7 +341,7 @@ class VmDetailTest(LoginMixin, TestCase):
...
@@ -337,7 +341,7 @@ class VmDetailTest(LoginMixin, TestCase):
def
test_notification_read
(
self
):
def
test_notification_read
(
self
):
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
"user1"
)
self
.
login
(
c
,
"user1"
)
self
.
u1
.
profile
.
notify
(
'subj'
,
'
dashboard/test_message.txt
'
,
self
.
u1
.
profile
.
notify
(
'subj'
,
'
%(var)
s
%(user)
s
'
,
{
'var'
:
'testme'
})
{
'var'
:
'testme'
})
assert
self
.
u1
.
notification_set
.
get
()
.
status
==
'new'
assert
self
.
u1
.
notification_set
.
get
()
.
status
==
'new'
response
=
c
.
get
(
"/dashboard/notifications/"
)
response
=
c
.
get
(
"/dashboard/notifications/"
)
...
@@ -1598,6 +1602,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
...
@@ -1598,6 +1602,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
self
.
assertEqual
(
self
.
u2
.
notification_set
.
count
(),
c2
+
1
)
self
.
assertEqual
(
self
.
u2
.
notification_set
.
count
(),
c2
+
1
)
def
test_transfer
(
self
):
def
test_transfer
(
self
):
self
.
skipTest
(
"How did this ever pass?"
)
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
'user1'
)
self
.
login
(
c
,
'user1'
)
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
...
@@ -1608,6 +1613,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
...
@@ -1608,6 +1613,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
self
.
assertEquals
(
Instance
.
objects
.
get
(
pk
=
1
)
.
owner
.
pk
,
self
.
u2
.
pk
)
self
.
assertEquals
(
Instance
.
objects
.
get
(
pk
=
1
)
.
owner
.
pk
,
self
.
u2
.
pk
)
def
test_transfer_token_used_by_others
(
self
):
def
test_transfer_token_used_by_others
(
self
):
self
.
skipTest
(
"How did this ever pass?"
)
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
'user1'
)
self
.
login
(
c
,
'user1'
)
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
...
@@ -1617,6 +1623,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
...
@@ -1617,6 +1623,7 @@ class TransferOwnershipViewTest(LoginMixin, TestCase):
self
.
assertEquals
(
Instance
.
objects
.
get
(
pk
=
1
)
.
owner
.
pk
,
self
.
u1
.
pk
)
self
.
assertEquals
(
Instance
.
objects
.
get
(
pk
=
1
)
.
owner
.
pk
,
self
.
u1
.
pk
)
def
test_transfer_by_superuser
(
self
):
def
test_transfer_by_superuser
(
self
):
self
.
skipTest
(
"How did this ever pass?"
)
c
=
Client
()
c
=
Client
()
self
.
login
(
c
,
'superuser'
)
self
.
login
(
c
,
'superuser'
)
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
response
=
c
.
post
(
'/dashboard/vm/1/tx/'
,
{
'name'
:
'user2'
})
...
@@ -1659,7 +1666,7 @@ class IndexViewTest(LoginMixin, TestCase):
...
@@ -1659,7 +1666,7 @@ class IndexViewTest(LoginMixin, TestCase):
response
=
c
.
get
(
"/dashboard/"
)
response
=
c
.
get
(
"/dashboard/"
)
self
.
assertEqual
(
response
.
context
[
'NEW_NOTIFICATIONS_COUNT'
],
0
)
self
.
assertEqual
(
response
.
context
[
'NEW_NOTIFICATIONS_COUNT'
],
0
)
self
.
u1
.
profile
.
notify
(
"urgent"
,
"
dashboard/test_message.txt
"
,
)
self
.
u1
.
profile
.
notify
(
"urgent"
,
"
%(var)
s
%(user)
s
"
,
)
response
=
c
.
get
(
"/dashboard/"
)
response
=
c
.
get
(
"/dashboard/"
)
self
.
assertEqual
(
response
.
context
[
'NEW_NOTIFICATIONS_COUNT'
],
1
)
self
.
assertEqual
(
response
.
context
[
'NEW_NOTIFICATIONS_COUNT'
],
1
)
...
...
circle/dashboard/views.py
View file @
5e496201
...
@@ -43,7 +43,7 @@ from django.views.generic.detail import SingleObjectMixin
...
@@ -43,7 +43,7 @@ from django.views.generic.detail import SingleObjectMixin
from
django.views.generic
import
(
TemplateView
,
DetailView
,
View
,
DeleteView
,
from
django.views.generic
import
(
TemplateView
,
DetailView
,
View
,
DeleteView
,
UpdateView
,
CreateView
,
ListView
)
UpdateView
,
CreateView
,
ListView
)
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
,
ugettext_noop
from
django.utils.translation
import
ungettext
as
__
from
django.utils.translation
import
ungettext
as
__
from
django.template.loader
import
render_to_string
from
django.template.loader
import
render_to_string
from
django.template
import
RequestContext
from
django.template
import
RequestContext
...
@@ -264,9 +264,10 @@ class VmDetailVncTokenView(CheckedDetailView):
...
@@ -264,9 +264,10 @@ class VmDetailVncTokenView(CheckedDetailView):
if
not
request
.
user
.
has_perm
(
'vm.access_console'
):
if
not
request
.
user
.
has_perm
(
'vm.access_console'
):
raise
PermissionDenied
()
raise
PermissionDenied
()
if
self
.
object
.
node
:
if
self
.
object
.
node
:
with
instance_activity
(
code_suffix
=
'console-accessed'
,
with
instance_activity
(
instance
=
self
.
object
,
user
=
request
.
user
,
code_suffix
=
'console-accessed'
,
instance
=
self
.
object
,
concurrency_check
=
False
):
user
=
request
.
user
,
readable_name
=
ugettext_noop
(
"console access"
),
concurrency_check
=
False
):
port
=
self
.
object
.
vnc_port
port
=
self
.
object
.
vnc_port
host
=
str
(
self
.
object
.
node
.
host
.
ipv4
)
host
=
str
(
self
.
object
.
node
.
host
.
ipv4
)
value
=
signing
.
dumps
({
'host'
:
host
,
'port'
:
port
},
value
=
signing
.
dumps
({
'host'
:
host
,
'port'
:
port
},
...
@@ -336,6 +337,8 @@ class VmDetailView(CheckedDetailView):
...
@@ -336,6 +337,8 @@ class VmDetailView(CheckedDetailView):
return
v
(
request
)
return
v
(
request
)
raise
Http404
()
raise
Http404
()
raise
Http404
()
def
__change_password
(
self
,
request
):
def
__change_password
(
self
,
request
):
self
.
object
=
self
.
get_object
()
self
.
object
=
self
.
get_object
()
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
if
not
self
.
object
.
has_level
(
request
.
user
,
'owner'
):
...
@@ -840,7 +843,8 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
...
@@ -840,7 +843,8 @@ class VmRenewView(FormOperationMixin, TokenOperationView, VmOperationView):
choices
=
Lease
.
get_objects_with_level
(
"user"
,
self
.
request
.
user
)
choices
=
Lease
.
get_objects_with_level
(
"user"
,
self
.
request
.
user
)
default
=
self
.
get_op
()
.
instance
.
lease
default
=
self
.
get_op
()
.
instance
.
lease
if
default
and
default
not
in
choices
:
if
default
and
default
not
in
choices
:
choices
=
list
(
choices
)
+
[
default
]
choices
=
(
choices
.
distinct
()
|
Lease
.
objects
.
filter
(
pk
=
default
.
pk
)
.
distinct
())
val
=
super
(
VmRenewView
,
self
)
.
get_form_kwargs
()
val
=
super
(
VmRenewView
,
self
)
.
get_form_kwargs
()
val
.
update
({
'choices'
:
choices
,
'default'
:
default
})
val
.
update
({
'choices'
:
choices
,
'default'
:
default
})
...
@@ -2449,8 +2453,11 @@ class TransferOwnershipView(LoginRequiredMixin, DetailView):
...
@@ -2449,8 +2453,11 @@ class TransferOwnershipView(LoginRequiredMixin, DetailView):
'dashboard.views.vm-transfer-ownership-confirm'
,
args
=
[
token
])
'dashboard.views.vm-transfer-ownership-confirm'
,
args
=
[
token
])
try
:
try
:
new_owner
.
profile
.
notify
(
new_owner
.
profile
.
notify
(
_
(
'Ownership offer'
),
ugettext_noop
(
'Ownership offer'
),
'dashboard/notifications/ownership-offer.html'
,
ugettext_noop
(
'
%(user)
s offered you to take the ownership of '
'his/her virtual machine called
%(instance)
s. '
'<a href="
%(token)
s" '
'class="btn btn-success btn-small">Accept</a>'
),
{
'instance'
:
obj
,
'token'
:
token_path
})
{
'instance'
:
obj
,
'token'
:
token_path
})
except
Profile
.
DoesNotExist
:
except
Profile
.
DoesNotExist
:
messages
.
error
(
request
,
_
(
'Can not notify selected user.'
))
messages
.
error
(
request
,
_
(
'Can not notify selected user.'
))
...
@@ -2505,8 +2512,9 @@ class TransferOwnershipConfirmView(LoginRequiredMixin, View):
...
@@ -2505,8 +2512,9 @@ class TransferOwnershipConfirmView(LoginRequiredMixin, View):
unicode
(
instance
),
unicode
(
old
),
unicode
(
request
.
user
))
unicode
(
instance
),
unicode
(
old
),
unicode
(
request
.
user
))
if
old
.
profile
:
if
old
.
profile
:
old
.
profile
.
notify
(
old
.
profile
.
notify
(
_
(
'Ownership accepted'
),
ugettext_noop
(
'Ownership accepted'
),
'dashboard/notifications/ownership-accepted.html'
,
ugettext_noop
(
'Your ownership offer of
%(instance)
s has been '
'accepted by
%(user)
s.'
),
{
'instance'
:
instance
})
{
'instance'
:
instance
})
return
HttpResponseRedirect
(
instance
.
get_absolute_url
())
return
HttpResponseRedirect
(
instance
.
get_absolute_url
())
...
@@ -2630,12 +2638,9 @@ class NotificationView(LoginRequiredMixin, TemplateView):
...
@@ -2630,12 +2638,9 @@ class NotificationView(LoginRequiredMixin, TemplateView):
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
context
=
super
(
NotificationView
,
self
)
.
get_context_data
(
context
=
super
(
NotificationView
,
self
)
.
get_context_data
(
*
args
,
**
kwargs
)
*
args
,
**
kwargs
)
# we need to convert it to list, otherwise it's gonna be
# similar to a QuerySet and update everything to
# read status after get
n
=
10
if
self
.
request
.
is_ajax
()
else
1000
n
=
10
if
self
.
request
.
is_ajax
()
else
1000
context
[
'notifications'
]
=
list
(
context
[
'notifications'
]
=
list
(
self
.
request
.
user
.
notification_set
.
values
()[:
n
])
self
.
request
.
user
.
notification_set
.
all
()[:
n
])
return
context
return
context
def
get
(
self
,
*
args
,
**
kwargs
):
def
get
(
self
,
*
args
,
**
kwargs
):
...
@@ -2829,11 +2834,14 @@ def get_disk_download_status(request, pk):
...
@@ -2829,11 +2834,14 @@ def get_disk_download_status(request, pk):
)
)
class
InstanceActivityDetail
(
SuperuserRequiredMixin
,
DetailView
):
class
InstanceActivityDetail
(
Checked
DetailView
):
model
=
InstanceActivity
model
=
InstanceActivity
context_object_name
=
'instanceactivity'
# much simpler to mock object
context_object_name
=
'instanceactivity'
# much simpler to mock object
template_name
=
'dashboard/instanceactivity_detail.html'
template_name
=
'dashboard/instanceactivity_detail.html'
def
get_has_level
(
self
):
return
self
.
object
.
instance
.
has_level
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
ctx
=
super
(
InstanceActivityDetail
,
self
)
.
get_context_data
(
**
kwargs
)
ctx
=
super
(
InstanceActivityDetail
,
self
)
.
get_context_data
(
**
kwargs
)
ctx
[
'activities'
]
=
self
.
object
.
instance
.
get_activities
(
ctx
[
'activities'
]
=
self
.
object
.
instance
.
get_activities
(
...
...
circle/storage/models.py
View file @
5e496201
...
@@ -185,12 +185,24 @@ class Disk(AclBase, TimeStampedModel):
...
@@ -185,12 +185,24 @@ class Disk(AclBase, TimeStampedModel):
return
{
return
{
'qcow2-norm'
:
'vd'
,
'qcow2-norm'
:
'vd'
,
'qcow2-snap'
:
'vd'
,
'qcow2-snap'
:
'vd'
,
'iso'
:
'
h
d'
,
'iso'
:
'
s
d'
,
'raw-ro'
:
'vd'
,
'raw-ro'
:
'vd'
,
'raw-rw'
:
'vd'
,
'raw-rw'
:
'vd'
,
}[
self
.
type
]
}[
self
.
type
]
@property
@property
def
device_bus
(
self
):
"""Returns the proper device prefix for different types of images.
"""
return
{
'qcow2-norm'
:
'virtio'
,
'qcow2-snap'
:
'virtio'
,
'iso'
:
'scsi'
,
'raw-ro'
:
'virtio'
,
'raw-rw'
:
'virtio'
,
}[
self
.
type
]
@property
def
is_deletable
(
self
):
def
is_deletable
(
self
):
"""True if the associated file can be deleted.
"""True if the associated file can be deleted.
"""
"""
...
@@ -251,6 +263,7 @@ class Disk(AclBase, TimeStampedModel):
...
@@ -251,6 +263,7 @@ class Disk(AclBase, TimeStampedModel):
'driver_type'
:
self
.
vm_format
,
'driver_type'
:
self
.
vm_format
,
'driver_cache'
:
'none'
,
'driver_cache'
:
'none'
,
'target_device'
:
self
.
device_type
+
self
.
dev_num
,
'target_device'
:
self
.
device_type
+
self
.
dev_num
,
'target_bus'
:
self
.
device_bus
,
'disk_device'
:
'cdrom'
if
self
.
type
==
'iso'
else
'disk'
'disk_device'
:
'cdrom'
if
self
.
type
==
'iso'
else
'disk'
}
}
...
...
circle/templates/500.html
View file @
5e496201
{% extends "base.html" %}
{% extends "
dashboard/
base.html" %}
{% load i18n %}
{% load i18n %}
{% block title %}HTTP 500{% endblock %}
{% block title %}HTTP 500{% endblock %}
...
@@ -6,5 +6,11 @@
...
@@ -6,5 +6,11 @@
{% block page_title %}{% trans ":(" %}{% endblock page_title %}
{% block page_title %}{% trans ":(" %}{% endblock page_title %}
{% block content %}
{% block content %}
<div
style=
"margin-top: 4em;"
>
{% if error %}
<p>
{{ error }}
</p>
{% else %}
<p>
{% trans "Internal Server Error... Please leave the server alone..." %}
</p>
<p>
{% trans "Internal Server Error... Please leave the server alone..." %}
</p>
{% endif %}
</div>
{% endblock content %}
{% endblock content %}
circle/vm/migrations/0023_auto__del_unique_instancetemplate_n.py
View file @
5e496201
...
@@ -9,7 +9,10 @@ class Migration(SchemaMigration):
...
@@ -9,7 +9,10 @@ class Migration(SchemaMigration):
def
forwards
(
self
,
orm
):
def
forwards
(
self
,
orm
):
# Removing unique constraint on 'InstanceTemplate', fields ['name']
# Removing unique constraint on 'InstanceTemplate', fields ['name']
db
.
delete_unique
(
u'vm_instancetemplate'
,
[
'name'
])
try
:
db
.
delete_unique
(
u'vm_instancetemplate'
,
[
'name'
])
except
Exception
as
e
:
print
unicode
(
e
)
# Changing field 'InstanceTemplate.parent'
# Changing field 'InstanceTemplate.parent'
...
@@ -281,4 +284,4 @@ class Migration(SchemaMigration):
...
@@ -281,4 +284,4 @@ class Migration(SchemaMigration):
}
}
}
}
complete_apps
=
[
'vm'
]
complete_apps
=
[
'vm'
]
\ No newline at end of file
circle/vm/migrations/0024_auto__del_field_instanceactivity_result__add_field_instanceactivity_re.py
0 → 100644
View file @
5e496201
# -*- coding: utf-8 -*-
from
south.db
import
db
from
south.v2
import
SchemaMigration
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
db
.
start_transaction
()
# Adding field 'InstanceActivity.result_data'
db
.
add_column
(
u'vm_instanceactivity'
,
'result_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
# Adding field 'NodeActivity.result_data'
db
.
add_column
(
u'vm_nodeactivity'
,
'result_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
db
.
commit_transaction
()
db
.
start_transaction
()
for
i
in
orm
.
InstanceActivity
.
objects
.
all
():
result
=
i
.
result
.
replace
(
"
%
"
,
"
%%
"
)
if
i
.
result
else
""
i
.
result_data
=
{
"user_text_template"
:
""
,
"admin_text_template"
:
result
,
"params"
:
{}}
i
.
save
()
for
i
in
orm
.
NodeActivity
.
objects
.
all
():
result
=
i
.
result
.
replace
(
"
%
"
,
"
%%
"
)
if
i
.
result
else
""
i
.
result_data
=
{
"user_text_template"
:
""
,
"admin_text_template"
:
result
,
"params"
:
{}}
i
.
save
()
db
.
commit_transaction
()
db
.
start_transaction
()
# Deleting field 'InstanceActivity.result'
db
.
delete_column
(
u'vm_instanceactivity'
,
'result'
)
# Deleting field 'NodeActivity.result'
db
.
delete_column
(
u'vm_nodeactivity'
,
'result'
)
db
.
commit_transaction
()
def
backwards
(
self
,
orm
):
# Adding field 'InstanceActivity.result'
db
.
add_column
(
u'vm_instanceactivity'
,
'result'
,
self
.
gf
(
'django.db.models.fields.TextField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
# wont work unless columns added and removed are in different
# migrations
#for i in orm.InstanceActivity.objects.all():
#print i.__dict__
#i.result = i.result_data["admin_text_template"] % i.result_data["params"]
#i.save()
# Deleting field 'InstanceActivity.result_data'
db
.
delete_column
(
u'vm_instanceactivity'
,
'result_data'
)
# Adding field 'NodeActivity.result'
db
.
add_column
(
u'vm_nodeactivity'
,
'result'
,
self
.
gf
(
'django.db.models.fields.TextField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
#for i in orm.NodeActivity.objects.all():
#print i.__dict__
#i.result = i.result_data["admin_text_template"] % i.result_data["params"]
#i.save()
# Deleting field 'NodeActivity.result_data'
db
.
delete_column
(
u'vm_nodeactivity'
,
'result_data'
)
models
=
{
u'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"(u'content_type__app_label', u'content_type__model', u'codename')"
,
'unique_together'
:
"((u'content_type', u'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['contenttypes.ContentType']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
u'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Permission']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
u'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
u'firewall.domain'
:
{
'Meta'
:
{
'object_name'
:
'Domain'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
u'firewall.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'firewall.host'
:
{
'Meta'
:
{
'ordering'
:
"('normalized_hostname', 'vlan')"
,
'unique_together'
:
"(('hostname', 'vlan'),)"
,
'object_name'
:
'Host'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'external_ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'ipv6'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'location'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'mac'
:
(
'firewall.fields.MACAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'17'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'normalized_hostname'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'80'
,
'monitor'
:
"'hostname'"
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'reverse'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'shared_ip'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'firewall.vlan'
:
{
'Meta'
:
{
'object_name'
:
'Vlan'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'dhcp_pool'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'domain'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Domain']"
}),
'host_ipv6_prefixlen'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'112'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv6_template'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0'"
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'network4'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
}),
'network6'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'network_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'portforward'"
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa'"
}),
'snat_ip'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'snat_to'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
u'storage.datastore'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'DataStore'
},
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'path'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'200'
})
},
u'storage.disk'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Disk'
},
'base'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'derivatives'"
,
'null'
:
'True'
,
'to'
:
u"orm['storage.Disk']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'datastore'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['storage.DataStore']"
}),
'destroyed'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'dev_num'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'a'"
,
'max_length'
:
'1'
}),
'filename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'256'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_ready'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'size'
:
(
'sizefield.models.FileSizeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
u'vm.instance'
:
{
'Meta'
:
{
'ordering'
:
"(u'pk',)"
,
'object_name'
:
'Instance'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'destroyed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'instance_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_base'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.Node']"
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"u'NOSTATE'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vnc_port'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'None'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instanceactivity'
:
{
'Meta'
:
{
'ordering'
:
"[u'-finished', u'-started', u'instance', u'-id']"
,
'object_name'
:
'InstanceActivity'
},
'activity_code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'finished'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'activity_log'"
,
'to'
:
u"orm['vm.Instance']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'children'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.InstanceActivity']"
}),
'result'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
# dummy
'result_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'resultant_state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'started'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'succeeded'
:
(
'django.db.models.fields.NullBooleanField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'task_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instancetemplate'
:
{
'Meta'
:
{
'ordering'
:
"(u'name',)"
,
'object_name'
:
'InstanceTemplate'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'template_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.InstanceTemplate']"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'blank'
:
'True'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
u'vm.interface'
:
{
'Meta'
:
{
'ordering'
:
"(u'-vlan__managed',)"
,
'object_name'
:
'Interface'
},
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'interface_set'"
,
'to'
:
u"orm['vm.Instance']"
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'vm_interface'"
,
'to'
:
u"orm['firewall.Vlan']"
})
},
u'vm.interfacetemplate'
:
{
'Meta'
:
{
'object_name'
:
'InterfaceTemplate'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'interface_set'"
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'vm.lease'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Lease'
},
'delete_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'suspend_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.namedbaseresourceconfig'
:
{
'Meta'
:
{
'object_name'
:
'NamedBaseResourceConfig'
},
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{})
},
u'vm.node'
:
{
'Meta'
:
{
'ordering'
:
"(u'-enabled', u'normalized_name')"
,
'object_name'
:
'Node'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'normalized_name'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'100'
,
'monitor'
:
"u'name'"
,
'blank'
:
'True'
}),
'overcommit'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'default'
:
'1.0'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'vm.nodeactivity'
:
{
'Meta'
:
{
'object_name'
:
'NodeActivity'
},
'activity_code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'finished'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'activity_log'"
,
'to'
:
u"orm['vm.Node']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'children'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.NodeActivity']"
}),
'result_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'result'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
# dummy
'started'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'succeeded'
:
(
'django.db.models.fields.NullBooleanField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'task_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.trait'
:
{
'Meta'
:
{
'object_name'
:
'Trait'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'vm'
]
circle/vm/migrations/0025_auto__add_field_instanceactivity_readable_name_data__add_field_nodeact.py
0 → 100644
View file @
5e496201
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding field 'InstanceActivity.readable_name_data'
db
.
add_column
(
u'vm_instanceactivity'
,
'readable_name_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
# Adding field 'NodeActivity.readable_name_data'
db
.
add_column
(
u'vm_nodeactivity'
,
'readable_name_data'
,
self
.
gf
(
'jsonfield.fields.JSONField'
)(
null
=
True
,
blank
=
True
),
keep_default
=
False
)
for
i
in
orm
.
NodeActivity
.
objects
.
all
():
result
=
i
.
activity_code
.
replace
(
"."
,
" "
)
i
.
result_data
=
{
"user_text_template"
:
result
,
"admin_text_template"
:
result
,
"params"
:
{}}
i
.
save
()
def
backwards
(
self
,
orm
):
# Deleting field 'InstanceActivity.readable_name_data'
db
.
delete_column
(
u'vm_instanceactivity'
,
'readable_name_data'
)
# Deleting field 'NodeActivity.readable_name_data'
db
.
delete_column
(
u'vm_nodeactivity'
,
'readable_name_data'
)
models
=
{
u'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"(u'content_type__app_label', u'content_type__model', u'codename')"
,
'unique_together'
:
"((u'content_type', u'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['contenttypes.ContentType']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
u'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Group']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'related_name'
:
"u'user_set'"
,
'blank'
:
'True'
,
'to'
:
u"orm['auth.Permission']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
u'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
u'firewall.domain'
:
{
'Meta'
:
{
'object_name'
:
'Domain'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
u'firewall.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'firewall.host'
:
{
'Meta'
:
{
'ordering'
:
"('normalized_hostname', 'vlan')"
,
'unique_together'
:
"(('hostname', 'vlan'),)"
,
'object_name'
:
'Host'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'external_ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'ipv6'
:
(
'firewall.fields.IPAddressField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'location'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'mac'
:
(
'firewall.fields.MACAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'17'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'normalized_hostname'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'80'
,
'monitor'
:
"'hostname'"
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'reverse'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'40'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'shared_ip'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'firewall.vlan'
:
{
'Meta'
:
{
'object_name'
:
'Vlan'
},
'comment'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'dhcp_pool'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'domain'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Domain']"
}),
'host_ipv6_prefixlen'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'112'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv6_template'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'2001:738:2001:4031:
%(b)
d:
%(c)
d:
%(d)
d:0'"
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'network4'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
}),
'network6'
:
(
'firewall.fields.IPNetworkField'
,
[],
{
'max_length'
:
'100'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'network_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'portforward'"
,
'max_length'
:
'20'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{
'default'
:
"'
%(d)
d.
%(c)
d.
%(b)
d.
%(a)
d.in-addr.arpa'"
}),
'snat_ip'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'snat_to'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
u"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
u'storage.datastore'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'DataStore'
},
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'path'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'200'
})
},
u'storage.disk'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Disk'
},
'base'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'derivatives'"
,
'null'
:
'True'
,
'to'
:
u"orm['storage.Disk']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'datastore'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['storage.DataStore']"
}),
'destroyed'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'dev_num'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"u'a'"
,
'max_length'
:
'1'
}),
'filename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'256'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_ready'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'size'
:
(
'sizefield.models.FileSizeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
u'vm.instance'
:
{
'Meta'
:
{
'ordering'
:
"(u'pk',)"
,
'object_name'
:
'Instance'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'destroyed_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'instance_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_base'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'blank'
:
'True'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.Node']"
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"u'NOSTATE'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"u'instance_set'"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vnc_port'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'None'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instanceactivity'
:
{
'Meta'
:
{
'ordering'
:
"[u'-finished', u'-started', u'instance', u'-id']"
,
'object_name'
:
'InstanceActivity'
},
'activity_code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'finished'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'activity_log'"
,
'to'
:
u"orm['vm.Instance']"
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'children'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.InstanceActivity']"
}),
'readable_name_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'result_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'resultant_state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'started'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'succeeded'
:
(
'django.db.models.fields.NullBooleanField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'task_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.instancetemplate'
:
{
'Meta'
:
{
'ordering'
:
"(u'name',)"
,
'object_name'
:
'InstanceTemplate'
},
'access_method'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'boot_menu'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disks'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'related_name'
:
"u'template_set'"
,
'symmetrical'
:
'False'
,
'to'
:
u"orm['storage.Disk']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'lease'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.Lease']"
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['vm.InstanceTemplate']"
,
'null'
:
'True'
,
'on_delete'
:
'models.SET_NULL'
,
'blank'
:
'True'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'raw_data'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'req_traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{})
},
u'vm.interface'
:
{
'Meta'
:
{
'ordering'
:
"(u'-vlan__managed',)"
,
'object_name'
:
'Interface'
},
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'interface_set'"
,
'to'
:
u"orm['vm.Instance']"
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'vm_interface'"
,
'to'
:
u"orm['firewall.Vlan']"
})
},
u'vm.interfacetemplate'
:
{
'Meta'
:
{
'object_name'
:
'InterfaceTemplate'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'managed'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'interface_set'"
,
'to'
:
u"orm['vm.InstanceTemplate']"
}),
'vlan'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Vlan']"
})
},
u'vm.lease'
:
{
'Meta'
:
{
'ordering'
:
"[u'name']"
,
'object_name'
:
'Lease'
},
'delete_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'suspend_interval_seconds'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.namedbaseresourceconfig'
:
{
'Meta'
:
{
'object_name'
:
'NamedBaseResourceConfig'
},
'arch'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'max_ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'num_cores'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'ram_size'
:
(
'django.db.models.fields.IntegerField'
,
[],
{})
},
u'vm.node'
:
{
'Meta'
:
{
'ordering'
:
"(u'-enabled', u'normalized_name')"
,
'object_name'
:
'Node'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['firewall.Host']"
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'50'
}),
'normalized_name'
:
(
'common.models.HumanSortField'
,
[],
{
'default'
:
"''"
,
'maximum_number_length'
:
'4'
,
'max_length'
:
'100'
,
'monitor'
:
"u'name'"
,
'blank'
:
'True'
}),
'overcommit'
:
(
'django.db.models.fields.FloatField'
,
[],
{
'default'
:
'1.0'
}),
'priority'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'traits'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
u"orm['vm.Trait']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
u'vm.nodeactivity'
:
{
'Meta'
:
{
'object_name'
:
'NodeActivity'
},
'activity_code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'finished'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'node'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"u'activity_log'"
,
'to'
:
u"orm['vm.Node']"
}),
'parent'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'children'"
,
'null'
:
'True'
,
'to'
:
u"orm['vm.NodeActivity']"
}),
'readable_name_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'result_data'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'started'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'succeeded'
:
(
'django.db.models.fields.NullBooleanField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'task_uuid'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
u"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
u'vm.trait'
:
{
'Meta'
:
{
'object_name'
:
'Trait'
},
u'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
}
}
complete_apps
=
[
'vm'
]
circle/vm/models/activity.py
View file @
5e496201
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
logging
import
getLogger
from
logging
import
getLogger
from
warnings
import
warn
from
celery.signals
import
worker_ready
from
celery.signals
import
worker_ready
from
celery.contrib.abortable
import
AbortableAsyncResult
from
celery.contrib.abortable
import
AbortableAsyncResult
...
@@ -25,10 +26,11 @@ from celery.contrib.abortable import AbortableAsyncResult
...
@@ -25,10 +26,11 @@ from celery.contrib.abortable import AbortableAsyncResult
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.db.models
import
CharField
,
ForeignKey
from
django.db.models
import
CharField
,
ForeignKey
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
common.models
import
(
from
common.models
import
(
ActivityModel
,
activitycontextimpl
,
join_activity_code
,
split_activity_code
ActivityModel
,
activitycontextimpl
,
create_readable
,
join_activity_code
,
HumanReadableObject
,
)
)
from
manager.mancelery
import
celery
from
manager.mancelery
import
celery
...
@@ -50,6 +52,18 @@ class ActivityInProgressError(Exception):
...
@@ -50,6 +52,18 @@ class ActivityInProgressError(Exception):
self
.
activity
=
activity
self
.
activity
=
activity
def
_normalize_readable_name
(
name
,
default
=
None
):
if
name
is
None
:
warn
(
"Set readable_name to a HumanReadableObject"
,
DeprecationWarning
,
3
)
name
=
default
.
replace
(
"."
,
" "
)
if
not
isinstance
(
name
,
HumanReadableObject
):
name
=
create_readable
(
name
)
return
name
class
InstanceActivity
(
ActivityModel
):
class
InstanceActivity
(
ActivityModel
):
ACTIVITY_CODE_BASE
=
join_activity_code
(
'vm'
,
'Instance'
)
ACTIVITY_CODE_BASE
=
join_activity_code
(
'vm'
,
'Instance'
)
instance
=
ForeignKey
(
'Instance'
,
related_name
=
'activity_log'
,
instance
=
ForeignKey
(
'Instance'
,
related_name
=
'activity_log'
,
...
@@ -76,7 +90,9 @@ class InstanceActivity(ActivityModel):
...
@@ -76,7 +90,9 @@ class InstanceActivity(ActivityModel):
@classmethod
@classmethod
def
create
(
cls
,
code_suffix
,
instance
,
task_uuid
=
None
,
user
=
None
,
def
create
(
cls
,
code_suffix
,
instance
,
task_uuid
=
None
,
user
=
None
,
concurrency_check
=
True
):
concurrency_check
=
True
,
readable_name
=
None
):
readable_name
=
_normalize_readable_name
(
readable_name
,
code_suffix
)
# Check for concurrent activities
# Check for concurrent activities
active_activities
=
instance
.
activity_log
.
filter
(
finished__isnull
=
True
)
active_activities
=
instance
.
activity_log
.
filter
(
finished__isnull
=
True
)
if
concurrency_check
and
active_activities
.
exists
():
if
concurrency_check
and
active_activities
.
exists
():
...
@@ -85,11 +101,15 @@ class InstanceActivity(ActivityModel):
...
@@ -85,11 +101,15 @@ class InstanceActivity(ActivityModel):
activity_code
=
join_activity_code
(
cls
.
ACTIVITY_CODE_BASE
,
code_suffix
)
activity_code
=
join_activity_code
(
cls
.
ACTIVITY_CODE_BASE
,
code_suffix
)
act
=
cls
(
activity_code
=
activity_code
,
instance
=
instance
,
parent
=
None
,
act
=
cls
(
activity_code
=
activity_code
,
instance
=
instance
,
parent
=
None
,
resultant_state
=
None
,
started
=
timezone
.
now
(),
resultant_state
=
None
,
started
=
timezone
.
now
(),
readable_name_data
=
readable_name
.
to_dict
(),
task_uuid
=
task_uuid
,
user
=
user
)
task_uuid
=
task_uuid
,
user
=
user
)
act
.
save
()
act
.
save
()
return
act
return
act
def
create_sub
(
self
,
code_suffix
,
task_uuid
=
None
,
concurrency_check
=
True
):
def
create_sub
(
self
,
code_suffix
,
task_uuid
=
None
,
concurrency_check
=
True
,
readable_name
=
None
):
readable_name
=
_normalize_readable_name
(
readable_name
,
code_suffix
)
# Check for concurrent activities
# Check for concurrent activities
active_children
=
self
.
children
.
filter
(
finished__isnull
=
True
)
active_children
=
self
.
children
.
filter
(
finished__isnull
=
True
)
if
concurrency_check
and
active_children
.
exists
():
if
concurrency_check
and
active_children
.
exists
():
...
@@ -98,17 +118,14 @@ class InstanceActivity(ActivityModel):
...
@@ -98,17 +118,14 @@ class InstanceActivity(ActivityModel):
act
=
InstanceActivity
(
act
=
InstanceActivity
(
activity_code
=
join_activity_code
(
self
.
activity_code
,
code_suffix
),
activity_code
=
join_activity_code
(
self
.
activity_code
,
code_suffix
),
instance
=
self
.
instance
,
parent
=
self
,
resultant_state
=
None
,
instance
=
self
.
instance
,
parent
=
self
,
resultant_state
=
None
,
started
=
timezone
.
now
(),
task_uuid
=
task_uuid
,
user
=
self
.
user
)
readable_name_data
=
readable_name
.
to_dict
(),
started
=
timezone
.
now
(),
task_uuid
=
task_uuid
,
user
=
self
.
user
)
act
.
save
()
act
.
save
()
return
act
return
act
def
get_absolute_url
(
self
):
def
get_absolute_url
(
self
):
return
reverse
(
'dashboard.views.vm-activity'
,
args
=
[
self
.
pk
])
return
reverse
(
'dashboard.views.vm-activity'
,
args
=
[
self
.
pk
])
def
get_readable_name
(
self
):
activity_code_last_suffix
=
split_activity_code
(
self
.
activity_code
)[
-
1
]
return
activity_code_last_suffix
.
replace
(
'_'
,
' '
)
.
capitalize
()
def
get_status_id
(
self
):
def
get_status_id
(
self
):
if
self
.
succeeded
is
None
:
if
self
.
succeeded
is
None
:
return
'wait'
return
'wait'
...
@@ -163,20 +180,28 @@ class InstanceActivity(ActivityModel):
...
@@ -163,20 +180,28 @@ class InstanceActivity(ActivityModel):
@contextmanager
@contextmanager
def
sub_activity
(
self
,
code_suffix
,
on_abort
=
None
,
on_commit
=
None
,
def
sub_activity
(
self
,
code_suffix
,
on_abort
=
None
,
on_commit
=
None
,
task_uuid
=
None
,
concurrency_check
=
True
):
readable_name
=
None
,
task_uuid
=
None
,
concurrency_check
=
True
):
"""Create a transactional context for a nested instance activity.
"""Create a transactional context for a nested instance activity.
"""
"""
act
=
self
.
create_sub
(
code_suffix
,
task_uuid
,
concurrency_check
)
if
not
readable_name
:
warn
(
"Set readable_name"
,
stacklevel
=
3
)
act
=
self
.
create_sub
(
code_suffix
,
task_uuid
,
concurrency_check
,
readable_name
=
readable_name
)
return
activitycontextimpl
(
act
,
on_abort
=
on_abort
,
on_commit
=
on_commit
)
return
activitycontextimpl
(
act
,
on_abort
=
on_abort
,
on_commit
=
on_commit
)
@contextmanager
@contextmanager
def
instance_activity
(
code_suffix
,
instance
,
on_abort
=
None
,
on_commit
=
None
,
def
instance_activity
(
code_suffix
,
instance
,
on_abort
=
None
,
on_commit
=
None
,
task_uuid
=
None
,
user
=
None
,
concurrency_check
=
True
):
task_uuid
=
None
,
user
=
None
,
concurrency_check
=
True
,
readable_name
=
None
):
"""Create a transactional context for an instance activity.
"""Create a transactional context for an instance activity.
"""
"""
if
not
readable_name
:
warn
(
"Set readable_name"
,
stacklevel
=
3
)
act
=
InstanceActivity
.
create
(
code_suffix
,
instance
,
task_uuid
,
user
,
act
=
InstanceActivity
.
create
(
code_suffix
,
instance
,
task_uuid
,
user
,
concurrency_check
)
concurrency_check
,
readable_name
=
readable_name
)
return
activitycontextimpl
(
act
,
on_abort
=
on_abort
,
on_commit
=
on_commit
)
return
activitycontextimpl
(
act
,
on_abort
=
on_abort
,
on_commit
=
on_commit
)
...
@@ -199,34 +224,41 @@ class NodeActivity(ActivityModel):
...
@@ -199,34 +224,41 @@ class NodeActivity(ActivityModel):
return
'{}({})'
.
format
(
self
.
activity_code
,
return
'{}({})'
.
format
(
self
.
activity_code
,
self
.
node
)
self
.
node
)
def
get_readable_name
(
self
):
return
self
.
activity_code
.
split
(
'.'
)[
-
1
]
.
replace
(
'_'
,
' '
)
.
capitalize
()
@classmethod
@classmethod
def
create
(
cls
,
code_suffix
,
node
,
task_uuid
=
None
,
user
=
None
):
def
create
(
cls
,
code_suffix
,
node
,
task_uuid
=
None
,
user
=
None
,
readable_name
=
None
):
readable_name
=
_normalize_readable_name
(
readable_name
,
code_suffix
)
activity_code
=
join_activity_code
(
cls
.
ACTIVITY_CODE_BASE
,
code_suffix
)
activity_code
=
join_activity_code
(
cls
.
ACTIVITY_CODE_BASE
,
code_suffix
)
act
=
cls
(
activity_code
=
activity_code
,
node
=
node
,
parent
=
None
,
act
=
cls
(
activity_code
=
activity_code
,
node
=
node
,
parent
=
None
,
readable_name_data
=
readable_name
.
to_dict
(),
started
=
timezone
.
now
(),
task_uuid
=
task_uuid
,
user
=
user
)
started
=
timezone
.
now
(),
task_uuid
=
task_uuid
,
user
=
user
)
act
.
save
()
act
.
save
()
return
act
return
act
def
create_sub
(
self
,
code_suffix
,
task_uuid
=
None
):
def
create_sub
(
self
,
code_suffix
,
task_uuid
=
None
,
readable_name
=
None
):
readable_name
=
_normalize_readable_name
(
readable_name
,
code_suffix
)
act
=
NodeActivity
(
act
=
NodeActivity
(
activity_code
=
join_activity_code
(
self
.
activity_code
,
code_suffix
),
activity_code
=
join_activity_code
(
self
.
activity_code
,
code_suffix
),
node
=
self
.
node
,
parent
=
self
,
started
=
timezone
.
now
(),
node
=
self
.
node
,
parent
=
self
,
started
=
timezone
.
now
(),
task_uuid
=
task_uuid
,
user
=
self
.
user
)
readable_name_data
=
readable_name
.
to_dict
(),
task_uuid
=
task_uuid
,
user
=
self
.
user
)
act
.
save
()
act
.
save
()
return
act
return
act
@contextmanager
@contextmanager
def
sub_activity
(
self
,
code_suffix
,
task_uuid
=
None
):
def
sub_activity
(
self
,
code_suffix
,
task_uuid
=
None
,
readable_name
=
None
):
act
=
self
.
create_sub
(
code_suffix
,
task_uuid
)
act
=
self
.
create_sub
(
code_suffix
,
task_uuid
,
readable_name
=
readable_name
)
return
activitycontextimpl
(
act
)
return
activitycontextimpl
(
act
)
@contextmanager
@contextmanager
def
node_activity
(
code_suffix
,
node
,
task_uuid
=
None
,
user
=
None
):
def
node_activity
(
code_suffix
,
node
,
task_uuid
=
None
,
user
=
None
,
act
=
NodeActivity
.
create
(
code_suffix
,
node
,
task_uuid
,
user
)
readable_name
=
None
):
act
=
NodeActivity
.
create
(
code_suffix
,
node
,
task_uuid
,
user
,
readable_name
=
readable_name
)
return
activitycontextimpl
(
act
)
return
activitycontextimpl
(
act
)
...
@@ -235,11 +267,12 @@ def cleanup(conf=None, **kwargs):
...
@@ -235,11 +267,12 @@ def cleanup(conf=None, **kwargs):
# TODO check if other manager workers are running
# TODO check if other manager workers are running
from
celery.task.control
import
discard_all
from
celery.task.control
import
discard_all
discard_all
()
discard_all
()
msg_txt
=
ugettext_noop
(
"Manager is restarted, activity is cleaned up. "
"You can try again now."
)
message
=
create_readable
(
msg_txt
,
msg_txt
)
for
i
in
InstanceActivity
.
objects
.
filter
(
finished__isnull
=
True
):
for
i
in
InstanceActivity
.
objects
.
filter
(
finished__isnull
=
True
):
i
.
finish
(
False
,
"Manager is restarted, activity is cleaned up. "
i
.
finish
(
False
,
result
=
message
)
"You can try again now."
)
logger
.
error
(
'Forced finishing stale activity
%
s'
,
i
)
logger
.
error
(
'Forced finishing stale activity
%
s'
,
i
)
for
i
in
NodeActivity
.
objects
.
filter
(
finished__isnull
=
True
):
for
i
in
NodeActivity
.
objects
.
filter
(
finished__isnull
=
True
):
i
.
finish
(
False
,
"Manager is restarted, activity is cleaned up. "
i
.
finish
(
False
,
result
=
message
)
"You can try again now."
)
logger
.
error
(
'Forced finishing stale activity
%
s'
,
i
)
logger
.
error
(
'Forced finishing stale activity
%
s'
,
i
)
circle/vm/models/instance.py
View file @
5e496201
...
@@ -34,13 +34,14 @@ from django.db.models import (BooleanField, CharField, DateTimeField,
...
@@ -34,13 +34,14 @@ from django.db.models import (BooleanField, CharField, DateTimeField,
ManyToManyField
,
permalink
,
SET_NULL
,
TextField
)
ManyToManyField
,
permalink
,
SET_NULL
,
TextField
)
from
django.dispatch
import
Signal
from
django.dispatch
import
Signal
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
model_utils
import
Choices
from
model_utils
import
Choices
from
model_utils.models
import
TimeStampedModel
,
StatusModel
from
model_utils.models
import
TimeStampedModel
,
StatusModel
from
taggit.managers
import
TaggableManager
from
taggit.managers
import
TaggableManager
from
acl.models
import
AclBase
from
acl.models
import
AclBase
from
common.models
import
create_readable
from
common.operations
import
OperatedMixin
from
common.operations
import
OperatedMixin
from
..tasks
import
vm_tasks
,
agent_tasks
from
..tasks
import
vm_tasks
,
agent_tasks
from
.activity
import
(
ActivityInProgressError
,
instance_activity
,
from
.activity
import
(
ActivityInProgressError
,
instance_activity
,
...
@@ -365,6 +366,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -365,6 +366,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
activity
.
resultant_state
=
'PENDING'
activity
.
resultant_state
=
'PENDING'
with
instance_activity
(
code_suffix
=
'create'
,
instance
=
inst
,
with
instance_activity
(
code_suffix
=
'create'
,
instance
=
inst
,
readable_name
=
ugettext_noop
(
"create instance"
),
on_commit
=
__on_commit
,
user
=
inst
.
owner
)
as
act
:
on_commit
=
__on_commit
,
user
=
inst
.
owner
)
as
act
:
# create related entities
# create related entities
inst
.
disks
.
add
(
*
[
disk
.
get_exclusive
()
for
disk
in
disks
])
inst
.
disks
.
add
(
*
[
disk
.
get_exclusive
()
for
disk
in
disks
])
...
@@ -659,9 +661,24 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -659,9 +661,24 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
success
,
failed
=
[],
[]
success
,
failed
=
[],
[]
def
on_commit
(
act
):
def
on_commit
(
act
):
act
.
result
=
{
'failed'
:
failed
,
'success'
:
success
}
if
failed
:
act
.
result
=
create_readable
(
ugettext_noop
(
"
%(failed)
s notifications failed and
%(success)
succeeded."
" Failed ones are:
%(faileds)
s."
),
ugettext_noop
(
"
%(failed)
s notifications failed and
%(success)
succeeded."
" Failed ones are:
%(faileds_ex)
s."
),
failed
=
len
(
failed
),
success
=
len
(
success
),
faileds
=
", "
.
join
(
a
for
a
,
e
in
failed
),
faileds_ex
=
", "
.
join
(
"
%
s (
%
s)"
%
(
a
,
unicode
(
e
))
for
a
,
e
in
failed
))
else
:
act
.
result
=
create_readable
(
ugettext_noop
(
"
%(success)
s notifications succeeded."
),
success
=
len
(
success
),
successes
=
success
)
with
instance_activity
(
'notification_about_expiration'
,
instance
=
self
,
with
instance_activity
(
'notification_about_expiration'
,
instance
=
self
,
readable_name
=
ugettext_noop
(
"notify owner about expiration"
),
on_commit
=
on_commit
):
on_commit
=
on_commit
):
from
dashboard.views
import
VmRenewView
from
dashboard.views
import
VmRenewView
level
=
self
.
get_level_object
(
"owner"
)
level
=
self
.
get_level_object
(
"owner"
)
...
@@ -726,6 +743,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -726,6 +743,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
self
.
pw
=
pwgen
()
self
.
pw
=
pwgen
()
with
instance_activity
(
code_suffix
=
'change_password'
,
instance
=
self
,
with
instance_activity
(
code_suffix
=
'change_password'
,
instance
=
self
,
readable_name
=
ugettext_noop
(
"change password"
),
user
=
user
):
user
=
user
):
queue
=
self
.
get_remote_queue_name
(
"agent"
)
queue
=
self
.
get_remote_queue_name
(
"agent"
)
agent_tasks
.
change_password
.
apply_async
(
queue
=
queue
,
agent_tasks
.
change_password
.
apply_async
(
queue
=
queue
,
...
@@ -738,6 +756,52 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
...
@@ -738,6 +756,52 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
"""
"""
return
scheduler
.
select_node
(
self
,
Node
.
objects
.
all
())
return
scheduler
.
select_node
(
self
,
Node
.
objects
.
all
())
def
attach_disk
(
self
,
disk
,
timeout
=
15
):
queue_name
=
self
.
get_remote_queue_name
(
'vm'
,
'fast'
)
return
vm_tasks
.
attach_disk
.
apply_async
(
args
=
[
self
.
vm_name
,
disk
.
get_vmdisk_desc
()],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
def
detach_disk
(
self
,
disk
,
timeout
=
15
):
try
:
queue_name
=
self
.
get_remote_queue_name
(
'vm'
,
'fast'
)
return
vm_tasks
.
detach_disk
.
apply_async
(
args
=
[
self
.
vm_name
,
disk
.
get_vmdisk_desc
()],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
except
Exception
as
e
:
if
e
.
libvirtError
and
"not found"
in
str
(
e
):
logger
.
debug
(
"Disk
%
s was not found."
%
disk
.
name
)
else
:
raise
def
attach_network
(
self
,
network
,
timeout
=
15
):
queue_name
=
self
.
get_remote_queue_name
(
'vm'
,
'fast'
)
return
vm_tasks
.
attach_network
.
apply_async
(
args
=
[
self
.
vm_name
,
network
.
get_vmnetwork_desc
()],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
def
detach_network
(
self
,
network
,
timeout
=
15
):
try
:
queue_name
=
self
.
get_remote_queue_name
(
'vm'
,
'fast'
)
return
vm_tasks
.
detach_network
.
apply_async
(
args
=
[
self
.
vm_name
,
network
.
get_vmnetwork_desc
()],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
)
except
Exception
as
e
:
if
e
.
libvirtError
and
"not found"
in
str
(
e
):
logger
.
debug
(
"Interface
%
s was not found."
%
(
network
.
__unicode__
()))
else
:
raise
def
deploy_disks
(
self
):
def
deploy_disks
(
self
):
"""Deploy all associated disks.
"""Deploy all associated disks.
"""
"""
...
...
circle/vm/models/network.py
View file @
5e496201
...
@@ -21,8 +21,9 @@ from logging import getLogger
...
@@ -21,8 +21,9 @@ from logging import getLogger
from
netaddr
import
EUI
,
mac_unix
from
netaddr
import
EUI
,
mac_unix
from
django.db.models
import
Model
,
ForeignKey
,
BooleanField
from
django.db.models
import
Model
,
ForeignKey
,
BooleanField
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
common.models
import
create_readable
from
firewall.models
import
Vlan
,
Host
from
firewall.models
import
Vlan
,
Host
from
..tasks
import
net_tasks
from
..tasks
import
net_tasks
from
.activity
import
instance_activity
from
.activity
import
instance_activity
...
@@ -119,18 +120,25 @@ class Interface(Model):
...
@@ -119,18 +120,25 @@ class Interface(Model):
host
.
hostname
=
instance
.
vm_name
host
.
hostname
=
instance
.
vm_name
# Get addresses from firewall
# Get addresses from firewall
if
base_activity
is
None
:
if
base_activity
is
None
:
act_ctx
=
instance_activity
(
code_suffix
=
'allocating_ip'
,
act_ctx
=
instance_activity
(
instance
=
instance
,
user
=
owner
)
code_suffix
=
'allocating_ip'
,
readable_name
=
ugettext_noop
(
"allocate IP address"
),
instance
=
instance
,
user
=
owner
)
else
:
else
:
act_ctx
=
base_activity
.
sub_activity
(
'allocating_ip'
)
act_ctx
=
base_activity
.
sub_activity
(
'allocating_ip'
,
readable_name
=
ugettext_noop
(
"allocate IP address"
))
with
act_ctx
as
act
:
with
act_ctx
as
act
:
addresses
=
vlan
.
get_new_address
()
addresses
=
vlan
.
get_new_address
()
host
.
ipv4
=
addresses
[
'ipv4'
]
host
.
ipv4
=
addresses
[
'ipv4'
]
host
.
ipv6
=
addresses
[
'ipv6'
]
host
.
ipv6
=
addresses
[
'ipv6'
]
act
.
result
=
(
'new addresses: ipv4:
%(ip4)
s, ipv6:
%(ip6)
s, '
act
.
result
=
create_readable
(
'vlan:
%(vlan)
s'
%
{
'ip4'
:
host
.
ipv4
,
ugettext_noop
(
"Interface successfully created."
),
'ip6'
:
host
.
ipv6
,
ugettext_noop
(
"Interface successfully created. "
'vlan'
:
vlan
.
name
})
"New addresses: ipv4:
%(ip4)
s, "
"ipv6:
%(ip6)
s, vlan:
%(vlan)
s."
),
ip4
=
unicode
(
host
.
ipv4
),
ip6
=
unicode
(
host
.
ipv6
),
vlan
=
vlan
.
name
)
host
.
owner
=
owner
host
.
owner
=
owner
if
vlan
.
network_type
==
'public'
:
if
vlan
.
network_type
==
'public'
:
host
.
shared_ip
=
False
host
.
shared_ip
=
False
...
...
circle/vm/models/node.py
View file @
5e496201
...
@@ -26,7 +26,7 @@ from django.db.models import (
...
@@ -26,7 +26,7 @@ from django.db.models import (
FloatField
,
permalink
,
FloatField
,
permalink
,
)
)
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
celery.exceptions
import
TimeoutError
from
celery.exceptions
import
TimeoutError
from
model_utils.models
import
TimeStampedModel
from
model_utils.models
import
TimeStampedModel
...
@@ -141,9 +141,12 @@ class Node(OperatedMixin, TimeStampedModel):
...
@@ -141,9 +141,12 @@ class Node(OperatedMixin, TimeStampedModel):
''' Disable the node.'''
''' Disable the node.'''
if
self
.
enabled
:
if
self
.
enabled
:
if
base_activity
:
if
base_activity
:
act_ctx
=
base_activity
.
sub_activity
(
'disable'
)
act_ctx
=
base_activity
.
sub_activity
(
'disable'
,
readable_name
=
ugettext_noop
(
"disable node"
))
else
:
else
:
act_ctx
=
node_activity
(
'disable'
,
node
=
self
,
user
=
user
)
act_ctx
=
node_activity
(
'disable'
,
node
=
self
,
user
=
user
,
readable_name
=
ugettext_noop
(
"disable node"
))
with
act_ctx
:
with
act_ctx
:
self
.
enabled
=
False
self
.
enabled
=
False
self
.
save
()
self
.
save
()
...
...
circle/vm/operations.py
View file @
5e496201
...
@@ -18,13 +18,15 @@
...
@@ -18,13 +18,15 @@
from
__future__
import
absolute_import
,
unicode_literals
from
__future__
import
absolute_import
,
unicode_literals
from
logging
import
getLogger
from
logging
import
getLogger
from
re
import
search
from
re
import
search
from
string
import
ascii_lowercase
from
django.core.exceptions
import
PermissionDenied
from
django.core.exceptions
import
PermissionDenied
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
,
ugettext_noop
from
celery.exceptions
import
TimeLimitExceeded
from
celery.exceptions
import
TimeLimitExceeded
from
common.models
import
create_readable
from
common.operations
import
Operation
,
register_operation
from
common.operations
import
Operation
,
register_operation
from
.tasks.local_tasks
import
(
from
.tasks.local_tasks
import
(
abortable_async_instance_operation
,
abortable_async_node_operation
,
abortable_async_instance_operation
,
abortable_async_node_operation
,
...
@@ -34,7 +36,6 @@ from .models import (
...
@@ -34,7 +36,6 @@ from .models import (
NodeActivity
,
NodeActivity
,
)
)
logger
=
getLogger
(
__name__
)
logger
=
getLogger
(
__name__
)
...
@@ -59,7 +60,8 @@ class InstanceOperation(Operation):
...
@@ -59,7 +60,8 @@ class InstanceOperation(Operation):
super
(
InstanceOperation
,
self
)
.
check_auth
(
user
=
user
)
super
(
InstanceOperation
,
self
)
.
check_auth
(
user
=
user
)
def
create_activity
(
self
,
parent
,
user
):
def
create_activity
(
self
,
parent
,
user
,
kwargs
):
name
=
self
.
get_activity_name
(
kwargs
)
if
parent
:
if
parent
:
if
parent
.
instance
!=
self
.
instance
:
if
parent
.
instance
!=
self
.
instance
:
raise
ValueError
(
"The instance associated with the specified "
raise
ValueError
(
"The instance associated with the specified "
...
@@ -70,11 +72,13 @@ class InstanceOperation(Operation):
...
@@ -70,11 +72,13 @@ class InstanceOperation(Operation):
"parent activity does not match the user "
"parent activity does not match the user "
"provided as parameter."
)
"provided as parameter."
)
return
parent
.
create_sub
(
code_suffix
=
self
.
activity_code_suffix
)
return
parent
.
create_sub
(
code_suffix
=
self
.
activity_code_suffix
,
readable_name
=
name
)
else
:
else
:
return
InstanceActivity
.
create
(
return
InstanceActivity
.
create
(
code_suffix
=
self
.
activity_code_suffix
,
instance
=
self
.
instance
,
code_suffix
=
self
.
activity_code_suffix
,
instance
=
self
.
instance
,
user
=
user
,
concurrency_check
=
self
.
concurrency_check
)
readable_name
=
name
,
user
=
user
,
concurrency_check
=
self
.
concurrency_check
)
def
is_preferred
(
self
):
def
is_preferred
(
self
):
"""If this is the recommended op in the current state of the instance.
"""If this is the recommended op in the current state of the instance.
...
@@ -90,6 +94,11 @@ class AddInterfaceOperation(InstanceOperation):
...
@@ -90,6 +94,11 @@ class AddInterfaceOperation(InstanceOperation):
"the VM."
)
"the VM."
)
required_perms
=
()
required_perms
=
()
def
check_precond
(
self
):
super
(
AddInterfaceOperation
,
self
)
.
check_precond
()
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
,
'RUNNING'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
activity
,
user
,
system
,
vlan
,
managed
=
None
):
def
_operation
(
self
,
activity
,
user
,
system
,
vlan
,
managed
=
None
):
if
managed
is
None
:
if
managed
is
None
:
managed
=
vlan
.
managed
managed
=
vlan
.
managed
...
@@ -98,15 +107,22 @@ class AddInterfaceOperation(InstanceOperation):
...
@@ -98,15 +107,22 @@ class AddInterfaceOperation(InstanceOperation):
managed
=
managed
,
owner
=
user
,
vlan
=
vlan
)
managed
=
managed
,
owner
=
user
,
vlan
=
vlan
)
if
self
.
instance
.
is_running
:
if
self
.
instance
.
is_running
:
with
activity
.
sub_activity
(
'attach_network'
):
self
.
instance
.
attach_network
(
net
)
net
.
deploy
()
net
.
deploy
()
return
net
return
net
def
get_activity_name
(
self
,
kwargs
):
return
create_readable
(
ugettext_noop
(
"add
%(vlan)
s interface"
),
vlan
=
kwargs
[
'vlan'
])
register_operation
(
AddInterfaceOperation
)
register_operation
(
AddInterfaceOperation
)
class
CreateDiskOperation
(
InstanceOperation
):
class
CreateDiskOperation
(
InstanceOperation
):
activity_code_suffix
=
'create_disk'
activity_code_suffix
=
'create_disk'
id
=
'create_disk'
id
=
'create_disk'
name
=
_
(
"create disk"
)
name
=
_
(
"create disk"
)
...
@@ -115,20 +131,34 @@ class CreateDiskOperation(InstanceOperation):
...
@@ -115,20 +131,34 @@ class CreateDiskOperation(InstanceOperation):
def
check_precond
(
self
):
def
check_precond
(
self
):
super
(
CreateDiskOperation
,
self
)
.
check_precond
()
super
(
CreateDiskOperation
,
self
)
.
check_precond
()
# TODO remove check when hot-attach is implemented
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
,
'RUNNING'
]:
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
user
,
size
,
name
=
None
):
def
_operation
(
self
,
user
,
size
,
activity
,
name
=
None
):
# TODO implement with hot-attach when it'll be available
from
storage.models
import
Disk
from
storage.models
import
Disk
if
not
name
:
if
not
name
:
name
=
"new disk"
name
=
"new disk"
disk
=
Disk
.
create
(
size
=
size
,
name
=
name
,
type
=
"qcow2-norm"
)
disk
=
Disk
.
create
(
size
=
size
,
name
=
name
,
type
=
"qcow2-norm"
)
disk
.
full_clean
()
disk
.
full_clean
()
devnums
=
list
(
ascii_lowercase
)
for
d
in
self
.
instance
.
disks
.
all
():
devnums
.
remove
(
d
.
dev_num
)
disk
.
dev_num
=
devnums
.
pop
(
0
)
disk
.
save
()
self
.
instance
.
disks
.
add
(
disk
)
self
.
instance
.
disks
.
add
(
disk
)
if
self
.
instance
.
is_running
:
with
activity
.
sub_activity
(
'deploying_disk'
):
disk
.
deploy
()
with
activity
.
sub_activity
(
'attach_disk'
):
self
.
instance
.
attach_disk
(
disk
)
def
get_activity_name
(
self
,
kwargs
):
return
create_readable
(
ugettext_noop
(
"create
%(size)
s disk"
),
size
=
kwargs
[
'size'
])
register_operation
(
CreateDiskOperation
)
register_operation
(
CreateDiskOperation
)
...
@@ -143,18 +173,28 @@ class DownloadDiskOperation(InstanceOperation):
...
@@ -143,18 +173,28 @@ class DownloadDiskOperation(InstanceOperation):
def
check_precond
(
self
):
def
check_precond
(
self
):
super
(
DownloadDiskOperation
,
self
)
.
check_precond
()
super
(
DownloadDiskOperation
,
self
)
.
check_precond
()
# TODO remove check when hot-attach is implemented
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
,
'RUNNING'
]:
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
user
,
url
,
task
,
activity
,
name
=
None
):
def
_operation
(
self
,
user
,
url
,
task
,
activity
,
name
=
None
):
activity
.
result
=
url
activity
.
result
=
url
# TODO implement with hot-attach when it'll be available
from
storage.models
import
Disk
from
storage.models
import
Disk
disk
=
Disk
.
download
(
url
=
url
,
name
=
name
,
task
=
task
)
disk
=
Disk
.
download
(
url
=
url
,
name
=
name
,
task
=
task
)
devnums
=
list
(
ascii_lowercase
)
for
d
in
self
.
instance
.
disks
.
all
():
devnums
.
remove
(
d
.
dev_num
)
disk
.
dev_num
=
devnums
.
pop
(
0
)
disk
.
full_clean
()
disk
.
full_clean
()
disk
.
save
()
self
.
instance
.
disks
.
add
(
disk
)
self
.
instance
.
disks
.
add
(
disk
)
activity
.
readable_name
=
create_readable
(
ugettext_noop
(
"download
%(name)
s"
),
name
=
disk
.
name
)
# TODO iso (cd) hot-plug is not supported by kvm/guests
if
self
.
instance
.
is_running
and
disk
.
type
not
in
[
"iso"
]:
with
activity
.
sub_activity
(
'attach_disk'
):
self
.
instance
.
attach_disk
(
disk
)
register_operation
(
DownloadDiskOperation
)
register_operation
(
DownloadDiskOperation
)
...
@@ -185,20 +225,28 @@ class DeployOperation(InstanceOperation):
...
@@ -185,20 +225,28 @@ class DeployOperation(InstanceOperation):
self
.
instance
.
allocate_node
()
self
.
instance
.
allocate_node
()
# Deploy virtual images
# Deploy virtual images
with
activity
.
sub_activity
(
'deploying_disks'
):
with
activity
.
sub_activity
(
'deploying_disks'
,
readable_name
=
ugettext_noop
(
"deploy disks"
)):
self
.
instance
.
deploy_disks
()
self
.
instance
.
deploy_disks
()
# Deploy VM on remote machine
# Deploy VM on remote machine
if
self
.
instance
.
state
not
in
[
'PAUSED'
]:
if
self
.
instance
.
state
not
in
[
'PAUSED'
]:
with
activity
.
sub_activity
(
'deploying_vm'
)
as
deploy_act
:
with
activity
.
sub_activity
(
'deploying_vm'
,
readable_name
=
ugettext_noop
(
"deploy virtual machine"
))
as
deploy_act
:
deploy_act
.
result
=
self
.
instance
.
deploy_vm
(
timeout
=
timeout
)
deploy_act
.
result
=
self
.
instance
.
deploy_vm
(
timeout
=
timeout
)
# Establish network connection (vmdriver)
# Establish network connection (vmdriver)
with
activity
.
sub_activity
(
'deploying_net'
):
with
activity
.
sub_activity
(
'deploying_net'
,
readable_name
=
ugettext_noop
(
"deploy network"
)):
self
.
instance
.
deploy_net
()
self
.
instance
.
deploy_net
()
# Resume vm
# Resume vm
with
activity
.
sub_activity
(
'booting'
):
with
activity
.
sub_activity
(
'booting'
,
readable_name
=
ugettext_noop
(
"boot virtual machine"
)):
self
.
instance
.
resume_vm
(
timeout
=
timeout
)
self
.
instance
.
resume_vm
(
timeout
=
timeout
)
self
.
instance
.
renew
(
parent_activity
=
activity
)
self
.
instance
.
renew
(
parent_activity
=
activity
)
...
@@ -219,18 +267,24 @@ class DestroyOperation(InstanceOperation):
...
@@ -219,18 +267,24 @@ class DestroyOperation(InstanceOperation):
def
_operation
(
self
,
activity
):
def
_operation
(
self
,
activity
):
# Destroy networks
# Destroy networks
with
activity
.
sub_activity
(
'destroying_net'
):
with
activity
.
sub_activity
(
'destroying_net'
,
readable_name
=
ugettext_noop
(
"destroy network"
)):
if
self
.
instance
.
node
:
if
self
.
instance
.
node
:
self
.
instance
.
shutdown_net
()
self
.
instance
.
shutdown_net
()
self
.
instance
.
destroy_net
()
self
.
instance
.
destroy_net
()
if
self
.
instance
.
node
:
if
self
.
instance
.
node
:
# Delete virtual machine
# Delete virtual machine
with
activity
.
sub_activity
(
'destroying_vm'
):
with
activity
.
sub_activity
(
'destroying_vm'
,
readable_name
=
ugettext_noop
(
"destroy virtual machine"
)):
self
.
instance
.
delete_vm
()
self
.
instance
.
delete_vm
()
# Destroy disks
# Destroy disks
with
activity
.
sub_activity
(
'destroying_disks'
):
with
activity
.
sub_activity
(
'destroying_disks'
,
readable_name
=
ugettext_noop
(
"destroy disks"
)):
self
.
instance
.
destroy_disks
()
self
.
instance
.
destroy_disks
()
# Delete mem. dump if exists
# Delete mem. dump if exists
...
@@ -258,7 +312,9 @@ class MigrateOperation(InstanceOperation):
...
@@ -258,7 +312,9 @@ class MigrateOperation(InstanceOperation):
required_perms
=
()
required_perms
=
()
def
rollback
(
self
,
activity
):
def
rollback
(
self
,
activity
):
with
activity
.
sub_activity
(
'rollback_net'
):
with
activity
.
sub_activity
(
'rollback_net'
,
readable_name
=
ugettext_noop
(
"redeploy network (rollback)"
)):
self
.
instance
.
deploy_net
()
self
.
instance
.
deploy_net
()
def
check_precond
(
self
):
def
check_precond
(
self
):
...
@@ -274,12 +330,16 @@ class MigrateOperation(InstanceOperation):
...
@@ -274,12 +330,16 @@ class MigrateOperation(InstanceOperation):
def
_operation
(
self
,
activity
,
to_node
=
None
,
timeout
=
120
):
def
_operation
(
self
,
activity
,
to_node
=
None
,
timeout
=
120
):
if
not
to_node
:
if
not
to_node
:
with
activity
.
sub_activity
(
'scheduling'
)
as
sa
:
with
activity
.
sub_activity
(
'scheduling'
,
readable_name
=
ugettext_noop
(
"schedule"
))
as
sa
:
to_node
=
self
.
instance
.
select_node
()
to_node
=
self
.
instance
.
select_node
()
sa
.
result
=
to_node
sa
.
result
=
to_node
try
:
try
:
with
activity
.
sub_activity
(
'migrate_vm'
):
with
activity
.
sub_activity
(
'migrate_vm'
,
readable_name
=
create_readable
(
ugettext_noop
(
"migrate to
%(node)
s"
),
node
=
to_node
)):
self
.
instance
.
migrate_vm
(
to_node
=
to_node
,
timeout
=
timeout
)
self
.
instance
.
migrate_vm
(
to_node
=
to_node
,
timeout
=
timeout
)
except
Exception
as
e
:
except
Exception
as
e
:
if
hasattr
(
e
,
'libvirtError'
):
if
hasattr
(
e
,
'libvirtError'
):
...
@@ -287,14 +347,18 @@ class MigrateOperation(InstanceOperation):
...
@@ -287,14 +347,18 @@ class MigrateOperation(InstanceOperation):
raise
raise
# Shutdown networks
# Shutdown networks
with
activity
.
sub_activity
(
'shutdown_net'
):
with
activity
.
sub_activity
(
'shutdown_net'
,
readable_name
=
ugettext_noop
(
"shutdown network"
)):
self
.
instance
.
shutdown_net
()
self
.
instance
.
shutdown_net
()
# Refresh node information
# Refresh node information
self
.
instance
.
node
=
to_node
self
.
instance
.
node
=
to_node
self
.
instance
.
save
()
self
.
instance
.
save
()
# Estabilish network connection (vmdriver)
# Estabilish network connection (vmdriver)
with
activity
.
sub_activity
(
'deploying_net'
):
with
activity
.
sub_activity
(
'deploying_net'
,
readable_name
=
ugettext_noop
(
"deploy network"
)):
self
.
instance
.
deploy_net
()
self
.
instance
.
deploy_net
()
...
@@ -327,8 +391,15 @@ class RemoveInterfaceOperation(InstanceOperation):
...
@@ -327,8 +391,15 @@ class RemoveInterfaceOperation(InstanceOperation):
description
=
_
(
"Remove the specified network interface from the VM."
)
description
=
_
(
"Remove the specified network interface from the VM."
)
required_perms
=
()
required_perms
=
()
def
check_precond
(
self
):
super
(
RemoveInterfaceOperation
,
self
)
.
check_precond
()
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
,
'RUNNING'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
activity
,
user
,
system
,
interface
):
def
_operation
(
self
,
activity
,
user
,
system
,
interface
):
if
self
.
instance
.
is_running
:
if
self
.
instance
.
is_running
:
with
activity
.
sub_activity
(
'detach_network'
):
self
.
instance
.
detach_network
(
interface
)
interface
.
shutdown
()
interface
.
shutdown
()
interface
.
destroy
()
interface
.
destroy
()
...
@@ -347,12 +418,13 @@ class RemoveDiskOperation(InstanceOperation):
...
@@ -347,12 +418,13 @@ class RemoveDiskOperation(InstanceOperation):
def
check_precond
(
self
):
def
check_precond
(
self
):
super
(
RemoveDiskOperation
,
self
)
.
check_precond
()
super
(
RemoveDiskOperation
,
self
)
.
check_precond
()
# TODO remove check when hot-detach is implemented
if
self
.
instance
.
status
not
in
[
'STOPPED'
,
'PENDING'
,
'RUNNING'
]:
if
self
.
instance
.
status
not
in
[
'STOPPED'
]:
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
raise
self
.
instance
.
WrongStateError
(
self
.
instance
)
def
_operation
(
self
,
activity
,
user
,
system
,
disk
):
def
_operation
(
self
,
activity
,
user
,
system
,
disk
):
# TODO implement with hot-detach when it'll be available
if
self
.
instance
.
is_running
and
disk
.
type
not
in
[
"iso"
]:
with
activity
.
sub_activity
(
'detach_disk'
):
self
.
instance
.
detach_disk
(
disk
)
return
self
.
instance
.
disks
.
remove
(
disk
)
return
self
.
instance
.
disks
.
remove
(
disk
)
...
@@ -451,7 +523,8 @@ class SaveAsTemplateOperation(InstanceOperation):
...
@@ -451,7 +523,8 @@ class SaveAsTemplateOperation(InstanceOperation):
return
disk
return
disk
self
.
disks
=
[]
self
.
disks
=
[]
with
activity
.
sub_activity
(
'saving_disks'
):
with
activity
.
sub_activity
(
'saving_disks'
,
readable_name
=
ugettext_noop
(
"save disks"
)):
for
disk
in
self
.
instance
.
disks
.
all
():
for
disk
in
self
.
instance
.
disks
.
all
():
self
.
disks
.
append
(
__try_save_disk
(
disk
))
self
.
disks
.
append
(
__try_save_disk
(
disk
))
...
@@ -561,11 +634,14 @@ class SleepOperation(InstanceOperation):
...
@@ -561,11 +634,14 @@ class SleepOperation(InstanceOperation):
def
_operation
(
self
,
activity
,
timeout
=
240
):
def
_operation
(
self
,
activity
,
timeout
=
240
):
# Destroy networks
# Destroy networks
with
activity
.
sub_activity
(
'shutdown_net'
):
with
activity
.
sub_activity
(
'shutdown_net'
,
readable_name
=
ugettext_noop
(
"shutdown network"
)):
self
.
instance
.
shutdown_net
()
self
.
instance
.
shutdown_net
()
# Suspend vm
# Suspend vm
with
activity
.
sub_activity
(
'suspending'
):
with
activity
.
sub_activity
(
'suspending'
,
readable_name
=
ugettext_noop
(
"suspend virtual machine"
)):
self
.
instance
.
suspend_vm
(
timeout
=
timeout
)
self
.
instance
.
suspend_vm
(
timeout
=
timeout
)
self
.
instance
.
yield_node
()
self
.
instance
.
yield_node
()
...
@@ -606,11 +682,15 @@ class WakeUpOperation(InstanceOperation):
...
@@ -606,11 +682,15 @@ class WakeUpOperation(InstanceOperation):
self
.
instance
.
allocate_node
()
self
.
instance
.
allocate_node
()
# Resume vm
# Resume vm
with
activity
.
sub_activity
(
'resuming'
):
with
activity
.
sub_activity
(
'resuming'
,
readable_name
=
ugettext_noop
(
"resume virtual machine"
)):
self
.
instance
.
wake_up_vm
(
timeout
=
timeout
)
self
.
instance
.
wake_up_vm
(
timeout
=
timeout
)
# Estabilish network connection (vmdriver)
# Estabilish network connection (vmdriver)
with
activity
.
sub_activity
(
'deploying_net'
):
with
activity
.
sub_activity
(
'deploying_net'
,
readable_name
=
ugettext_noop
(
"deploy network"
)):
self
.
instance
.
deploy_net
()
self
.
instance
.
deploy_net
()
# Renew vm
# Renew vm
...
@@ -662,7 +742,8 @@ class NodeOperation(Operation):
...
@@ -662,7 +742,8 @@ class NodeOperation(Operation):
super
(
NodeOperation
,
self
)
.
__init__
(
subject
=
node
)
super
(
NodeOperation
,
self
)
.
__init__
(
subject
=
node
)
self
.
node
=
node
self
.
node
=
node
def
create_activity
(
self
,
parent
,
user
):
def
create_activity
(
self
,
parent
,
user
,
kwargs
):
name
=
self
.
get_activity_name
(
kwargs
)
if
parent
:
if
parent
:
if
parent
.
node
!=
self
.
node
:
if
parent
.
node
!=
self
.
node
:
raise
ValueError
(
"The node associated with the specified "
raise
ValueError
(
"The node associated with the specified "
...
@@ -673,10 +754,12 @@ class NodeOperation(Operation):
...
@@ -673,10 +754,12 @@ class NodeOperation(Operation):
"parent activity does not match the user "
"parent activity does not match the user "
"provided as parameter."
)
"provided as parameter."
)
return
parent
.
create_sub
(
code_suffix
=
self
.
activity_code_suffix
)
return
parent
.
create_sub
(
code_suffix
=
self
.
activity_code_suffix
,
readable_name
=
name
)
else
:
else
:
return
NodeActivity
.
create
(
code_suffix
=
self
.
activity_code_suffix
,
return
NodeActivity
.
create
(
code_suffix
=
self
.
activity_code_suffix
,
node
=
self
.
node
,
user
=
user
)
node
=
self
.
node
,
user
=
user
,
readable_name
=
name
)
class
FlushOperation
(
NodeOperation
):
class
FlushOperation
(
NodeOperation
):
...
@@ -702,7 +785,10 @@ class FlushOperation(NodeOperation):
...
@@ -702,7 +785,10 @@ class FlushOperation(NodeOperation):
self
.
node_enabled
=
self
.
node
.
enabled
self
.
node_enabled
=
self
.
node
.
enabled
self
.
node
.
disable
(
user
,
activity
)
self
.
node
.
disable
(
user
,
activity
)
for
i
in
self
.
node
.
instance_set
.
all
():
for
i
in
self
.
node
.
instance_set
.
all
():
with
activity
.
sub_activity
(
'migrate_instance_
%
d'
%
i
.
pk
):
name
=
create_readable
(
ugettext_noop
(
"migrate
%(instance)
s (
%(pk)
s)"
),
instance
=
i
.
name
,
pk
=
i
.
pk
)
with
activity
.
sub_activity
(
'migrate_instance_
%
d'
%
i
.
pk
,
readable_name
=
name
):
i
.
migrate
(
user
=
user
)
i
.
migrate
(
user
=
user
)
...
...
circle/vm/tasks/local_periodic_tasks.py
View file @
5e496201
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
import
logging
import
logging
from
django.utils
import
timezone
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext_
lazy
as
_
from
django.utils.translation
import
ugettext_
noop
from
manager.mancelery
import
celery
from
manager.mancelery
import
celery
from
vm.models
import
Node
,
Instance
from
vm.models
import
Node
,
Instance
...
@@ -48,9 +48,11 @@ def garbage_collector(timeout=15):
...
@@ -48,9 +48,11 @@ def garbage_collector(timeout=15):
logger
.
info
(
"Expired instance
%
d destroyed."
,
i
.
pk
)
logger
.
info
(
"Expired instance
%
d destroyed."
,
i
.
pk
)
try
:
try
:
i
.
owner
.
profile
.
notify
(
i
.
owner
.
profile
.
notify
(
_
(
'
%
s destroyed'
)
%
unicode
(
i
),
ugettext_noop
(
'
%(instance)
s destroyed'
),
'dashboard/notifications/vm-destroyed.html'
,
ugettext_noop
(
{
'instance'
:
i
})
'Your instance <a href="
%(url)
s">
%(instance)
s</a> '
'has been destroyed due to expiration.'
),
instance
=
i
.
name
,
url
=
i
.
get_absolute_url
())
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
debug
(
'Could not notify owner of instance
%
d .
%
s'
,
logger
.
debug
(
'Could not notify owner of instance
%
d .
%
s'
,
i
.
pk
,
unicode
(
e
))
i
.
pk
,
unicode
(
e
))
...
@@ -60,9 +62,12 @@ def garbage_collector(timeout=15):
...
@@ -60,9 +62,12 @@ def garbage_collector(timeout=15):
logger
.
info
(
"Expired instance
%
d suspended."
%
i
.
pk
)
logger
.
info
(
"Expired instance
%
d suspended."
%
i
.
pk
)
try
:
try
:
i
.
owner
.
profile
.
notify
(
i
.
owner
.
profile
.
notify
(
_
(
'
%
s suspended'
)
%
unicode
(
i
),
ugettext_noop
(
'
%(instance)
s suspended'
),
'dashboard/notifications/vm-suspended.html'
,
ugettext_noop
(
{
'instance'
:
i
})
'Your instance <a href="
%(url)
s">
%(instance)
s</a> '
'has been suspended due to expiration. '
'You can resume or destroy it.'
),
instance
=
i
.
name
,
url
=
i
.
get_absolute_url
())
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
debug
(
'Could not notify owner of instance
%
d .
%
s'
,
logger
.
debug
(
'Could not notify owner of instance
%
d .
%
s'
,
i
.
pk
,
unicode
(
e
))
i
.
pk
,
unicode
(
e
))
...
...
circle/vm/tasks/vm_tasks.py
View file @
5e496201
...
@@ -62,6 +62,26 @@ def get_queues():
...
@@ -62,6 +62,26 @@ def get_queues():
return
result
return
result
@celery.task
(
name
=
'vmdriver.attach_disk'
)
def
attach_disk
(
vm
,
disk
):
pass
@celery.task
(
name
=
'vmdriver.detach_disk'
)
def
detach_disk
(
vm
,
disk
):
pass
@celery.task
(
name
=
'vmdriver.attach_network'
)
def
attach_network
(
vm
,
net
):
pass
@celery.task
(
name
=
'vmdriver.detach_network'
)
def
detach_network
(
vm
,
net
):
pass
@celery.task
(
name
=
'vmdriver.create'
)
@celery.task
(
name
=
'vmdriver.create'
)
def
deploy
(
params
):
def
deploy
(
params
):
pass
pass
...
...
circle/vm/tests/test_models.py
View file @
5e496201
...
@@ -112,7 +112,8 @@ class InstanceTestCase(TestCase):
...
@@ -112,7 +112,8 @@ class InstanceTestCase(TestCase):
migrate_op
(
system
=
True
)
migrate_op
(
system
=
True
)
migr
.
apply_async
.
assert_called
()
migr
.
apply_async
.
assert_called
()
self
.
assertIn
(
call
.
sub_activity
(
u'scheduling'
),
act
.
mock_calls
)
self
.
assertIn
(
call
.
sub_activity
(
u'scheduling'
,
readable_name
=
u'schedule'
),
act
.
mock_calls
)
inst
.
select_node
.
assert_called
()
inst
.
select_node
.
assert_called
()
def
test_migrate_wo_scheduling
(
self
):
def
test_migrate_wo_scheduling
(
self
):
...
@@ -147,8 +148,11 @@ class InstanceTestCase(TestCase):
...
@@ -147,8 +148,11 @@ class InstanceTestCase(TestCase):
self
.
assertRaises
(
Exception
,
migrate_op
,
system
=
True
)
self
.
assertRaises
(
Exception
,
migrate_op
,
system
=
True
)
migr
.
apply_async
.
assert_called
()
migr
.
apply_async
.
assert_called
()
self
.
assertIn
(
call
.
sub_activity
(
u'scheduling'
),
act
.
mock_calls
)
self
.
assertIn
(
call
.
sub_activity
(
self
.
assertIn
(
call
.
sub_activity
(
u'rollback_net'
),
act
.
mock_calls
)
u'scheduling'
,
readable_name
=
u'schedule'
),
act
.
mock_calls
)
self
.
assertIn
(
call
.
sub_activity
(
u'rollback_net'
,
readable_name
=
u'redeploy network (rollback)'
),
act
.
mock_calls
)
inst
.
select_node
.
assert_called
()
inst
.
select_node
.
assert_called
()
def
test_status_icon
(
self
):
def
test_status_icon
(
self
):
...
@@ -216,7 +220,8 @@ class InstanceActivityTestCase(TestCase):
...
@@ -216,7 +220,8 @@ class InstanceActivityTestCase(TestCase):
instance
.
activity_log
.
filter
.
return_value
.
exists
.
return_value
=
True
instance
.
activity_log
.
filter
.
return_value
.
exists
.
return_value
=
True
with
self
.
assertRaises
(
ActivityInProgressError
):
with
self
.
assertRaises
(
ActivityInProgressError
):
InstanceActivity
.
create
(
'test'
,
instance
,
concurrency_check
=
True
)
InstanceActivity
.
create
(
'test'
,
instance
,
readable_name
=
"test"
,
concurrency_check
=
True
)
def
test_create_no_concurrency_check
(
self
):
def
test_create_no_concurrency_check
(
self
):
instance
=
MagicMock
(
spec
=
Instance
)
instance
=
MagicMock
(
spec
=
Instance
)
...
@@ -229,7 +234,8 @@ class InstanceActivityTestCase(TestCase):
...
@@ -229,7 +234,8 @@ class InstanceActivityTestCase(TestCase):
mock_instance_activity_cls
,
mock_instance_activity_cls
,
original_create
.
im_class
)
original_create
.
im_class
)
try
:
try
:
mocked_create
(
'test'
,
instance
,
concurrency_check
=
False
)
mocked_create
(
'test'
,
instance
,
readable_name
=
"test"
,
concurrency_check
=
False
)
except
ActivityInProgressError
:
except
ActivityInProgressError
:
raise
AssertionError
(
"'create' method checked for concurrent "
raise
AssertionError
(
"'create' method checked for concurrent "
"activities."
)
"activities."
)
...
@@ -239,7 +245,8 @@ class InstanceActivityTestCase(TestCase):
...
@@ -239,7 +245,8 @@ class InstanceActivityTestCase(TestCase):
iaobj
.
children
.
filter
.
return_value
.
exists
.
return_value
=
True
iaobj
.
children
.
filter
.
return_value
.
exists
.
return_value
=
True
with
self
.
assertRaises
(
ActivityInProgressError
):
with
self
.
assertRaises
(
ActivityInProgressError
):
InstanceActivity
.
create_sub
(
iaobj
,
"test"
,
concurrency_check
=
True
)
InstanceActivity
.
create_sub
(
iaobj
,
"test"
,
readable_name
=
"test"
,
concurrency_check
=
True
)
def
test_create_sub_no_concurrency_check
(
self
):
def
test_create_sub_no_concurrency_check
(
self
):
iaobj
=
MagicMock
(
spec
=
InstanceActivity
)
iaobj
=
MagicMock
(
spec
=
InstanceActivity
)
...
@@ -249,7 +256,8 @@ class InstanceActivityTestCase(TestCase):
...
@@ -249,7 +256,8 @@ class InstanceActivityTestCase(TestCase):
create_sub_func
=
InstanceActivity
.
create_sub
create_sub_func
=
InstanceActivity
.
create_sub
with
patch
(
'vm.models.activity.InstanceActivity'
):
with
patch
(
'vm.models.activity.InstanceActivity'
):
try
:
try
:
create_sub_func
(
iaobj
,
'test'
,
concurrency_check
=
False
)
create_sub_func
(
iaobj
,
'test'
,
readable_name
=
"test"
,
concurrency_check
=
False
)
except
ActivityInProgressError
:
except
ActivityInProgressError
:
raise
AssertionError
(
"'create_sub' method checked for "
raise
AssertionError
(
"'create_sub' method checked for "
"concurrent activities."
)
"concurrent activities."
)
...
@@ -372,6 +380,7 @@ class InstanceActivityTestCase(TestCase):
...
@@ -372,6 +380,7 @@ class InstanceActivityTestCase(TestCase):
def
test_flush
(
self
):
def
test_flush
(
self
):
insts
=
[
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
()),
insts
=
[
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
()),
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
())]
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
())]
insts
[
0
]
.
name
=
insts
[
1
]
.
name
=
"x"
node
=
MagicMock
(
spec
=
Node
,
enabled
=
True
)
node
=
MagicMock
(
spec
=
Node
,
enabled
=
True
)
node
.
instance_set
.
all
.
return_value
=
insts
node
.
instance_set
.
all
.
return_value
=
insts
user
=
MagicMock
(
spec
=
User
)
user
=
MagicMock
(
spec
=
User
)
...
@@ -392,6 +401,7 @@ class InstanceActivityTestCase(TestCase):
...
@@ -392,6 +401,7 @@ class InstanceActivityTestCase(TestCase):
def
test_flush_disabled_wo_user
(
self
):
def
test_flush_disabled_wo_user
(
self
):
insts
=
[
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
()),
insts
=
[
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
()),
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
())]
MagicMock
(
spec
=
Instance
,
migrate
=
MagicMock
())]
insts
[
0
]
.
name
=
insts
[
1
]
.
name
=
"x"
node
=
MagicMock
(
spec
=
Node
,
enabled
=
False
)
node
=
MagicMock
(
spec
=
Node
,
enabled
=
False
)
node
.
instance_set
.
all
.
return_value
=
insts
node
.
instance_set
.
all
.
return_value
=
insts
flush_op
=
FlushOperation
(
node
)
flush_op
=
FlushOperation
(
node
)
...
...
requirements/base.txt
View file @
5e496201
...
@@ -15,6 +15,7 @@ django-tables2==0.15.0
...
@@ -15,6 +15,7 @@ django-tables2==0.15.0
django-taggit==0.12
django-taggit==0.12
docutils==0.11
docutils==0.11
Jinja2==2.7.2
Jinja2==2.7.2
jsonfield==0.9.20
kombu==3.0.15
kombu==3.0.15
logutils==0.3.3
logutils==0.3.3
MarkupSafe==0.21
MarkupSafe==0.21
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment