Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Fukász Rómeó Ervin
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
c5c309fa
authored
Dec 15, 2015
by
Czémán Arnold
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
storage: add create views and forms for storage, small changes on model
parent
1e70ee0c
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
511 additions
and
16 deletions
+511
-16
circle/dashboard/forms.py
+69
-2
circle/dashboard/static/dashboard/dashboard.js
+56
-1
circle/dashboard/static/dashboard/dashboard.less
+3
-3
circle/dashboard/templates/dashboard/_data_store_host-create.html
+36
-0
circle/dashboard/templates/dashboard/_disk-list-element.html
+2
-1
circle/dashboard/templates/dashboard/_storage-choose.html
+37
-0
circle/dashboard/templates/dashboard/_storage-create.html
+42
-0
circle/dashboard/templates/dashboard/storage-list.html
+0
-1
circle/dashboard/templates/dashboard/storage/hostname_selector.html
+44
-0
circle/dashboard/urls.py
+7
-2
circle/dashboard/views/storage.py
+176
-4
circle/storage/migrations/0004_auto_20151212_0402.py
+31
-0
circle/storage/models.py
+8
-2
No files found.
circle/dashboard/forms.py
View file @
c5c309fa
...
...
@@ -54,7 +54,7 @@ from firewall.models import Vlan, Host
from
vm.models
import
(
InstanceTemplate
,
Lease
,
InterfaceTemplate
,
Node
,
Trait
,
Instance
)
from
storage.models
import
DataStore
,
Disk
from
storage.models
import
DataStore
,
Disk
,
DataStoreHost
from
django.contrib.admin.widgets
import
FilteredSelectMultiple
from
django.contrib.auth.models
import
Permission
from
.models
import
Profile
,
GroupProfile
,
Message
...
...
@@ -1614,7 +1614,74 @@ class DataStoreForm(ModelForm):
class
Meta
:
model
=
DataStore
fields
=
(
"name"
,
"path"
,
"hostname"
,
)
fields
=
(
"type"
,
"name"
,
"path"
,
"hostname"
,
)
class
CephDataStoreForm
(
DataStoreForm
):
hostnames
=
forms
.
ModelMultipleChoiceField
(
queryset
=
None
,
required
=
False
,
label
=
_
(
"Hostnames"
))
other_hostnames
=
forms
.
MultipleChoiceField
(
required
=
False
,
label
=
_
(
"Other hostnames"
))
type
=
forms
.
CharField
(
widget
=
forms
.
HiddenInput
())
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
DataStoreForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
hostnames
=
self
.
fields
[
"hosts"
]
.
queryset
.
all
()
other_hostnames
=
set
(
DataStoreHost
.
objects
.
all
())
-
set
(
hostnames
)
self
.
fields
[
'hostnames'
]
.
queryset
=
hostnames
self
.
fields
[
'other_hostnames'
]
.
initial
=
other_hostnames
@property
def
helper
(
self
):
helper
=
FormHelper
()
helper
.
layout
=
Layout
(
Fieldset
(
''
,
'ceph_user'
,
'secret_uuid'
,
),
FormActions
(
Submit
(
'submit'
,
_
(
'Save'
)),
)
)
return
helper
class
Meta
:
model
=
DataStore
fields
=
(
"type"
,
"name"
,
"path"
,
"hostname"
,
"ceph_user"
,
"secret_uuid"
,
"hosts"
)
class
DataStoreHostForm
(
ModelForm
):
@property
def
helper
(
self
):
helper
=
FormHelper
()
helper
.
layout
=
Layout
(
Fieldset
(
''
,
'name'
,
'address'
,
'port'
,
),
FormActions
(
Submit
(
'submit'
,
_
(
'Save'
)),
)
)
return
helper
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
DataStoreHostForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
fields
[
'port'
]
.
initial
=
6789
class
Meta
:
model
=
DataStoreHost
fields
=
(
"name"
,
"address"
,
"port"
)
class
StorageListSearchForm
(
forms
.
Form
):
...
...
circle/dashboard/static/dashboard/dashboard.js
View file @
c5c309fa
...
...
@@ -52,7 +52,7 @@ $(function () {
return
false
;
});
$
(
'.template-choose'
).
click
(
function
(
e
)
{
$
(
'.template-choose
, .storage-choose
'
).
click
(
function
(
e
)
{
$
.
ajax
({
type
:
'GET'
,
url
:
$
(
this
).
prop
(
'href'
),
...
...
@@ -73,11 +73,66 @@ $(function () {
}
return
true
;
});
$
(
"#storage-choose-next-button"
).
click
(
function
()
{
var
radio
=
$
(
'input[type="radio"]:checked'
,
"#storage-choose-form"
).
val
();
if
(
!
radio
)
{
$
(
"#storage-choose-alert"
).
addClass
(
"alert-warning"
)
.
text
(
gettext
(
"Select an option to proceed!"
));
return
false
;
}
return
true
;
});
}
});
return
false
;
});
$
(
'.data_store_host-create'
).
click
(
function
(
e
)
{
$
.
ajax
({
type
:
'GET'
,
url
:
$
(
this
).
prop
(
'href'
),
success
:
function
(
data
)
{
$
(
'body'
).
append
(
data
);
var
modal
=
$
(
'#confirmation-modal'
);
modal
.
modal
(
'show'
);
modal
.
on
(
'hidden.bs.modal'
,
function
()
{
modal
.
remove
();
});
$
(
"#data_store_host_host-create-btn"
).
click
(
function
(){
var
form
=
$
(
"#data_store_host_form"
)
$
.
post
(
form
.
attr
(
"action"
),
form
.
serialize
(),
function
(
data
){
if
(
data
.
status
===
true
){
$
(
'#id_other_hostnames'
)
.
append
(
$
(
'<option>'
)
.
text
(
data
.
response
.
text
)
.
attr
(
'value'
,
data
.
response
.
val
));
modal
.
modal
(
"hide"
);
$
(
'body'
).
removeClass
(
'modal-open'
);
$
(
'.modal-backdrop'
).
remove
();
}
else
{
var
error_msg
=
$
(
"#data_store_host-create-alert"
);
error_msg
.
empty
();
error_msg
.
append
(
data
.
response
);
error_msg
.
show
();
}
},
"json"
);
return
false
;
});
}
});
return
false
;
});
$
(
'#storage-create-form'
).
submit
(
function
(){
$
(
'#id_hostnames option'
).
prop
(
'selected'
,
true
);
});
$
(
'[href=#index-graph-view]'
).
click
(
function
(
e
)
{
var
box
=
$
(
this
).
data
(
'index-box'
);
$
(
"#"
+
box
+
"-list-view"
).
hide
();
...
...
circle/dashboard/static/dashboard/dashboard.less
View file @
c5c309fa
...
...
@@ -471,7 +471,7 @@ footer a, footer a:hover, footer a:visited {
margin-bottom: 20px;
}
.template-choose-list {
.template-choose-list
, .storage-choose-list
{
max-width: 600px;
}
...
...
@@ -481,13 +481,13 @@ footer a, footer a:hover, footer a:visited {
padding-right: 50px;
}
.template-choose-list-element {
.template-choose-list-element
, .storage-choose-list-element
{
padding: 6px 10px;
cursor: pointer;
margin-bottom: 15px; /* bootstrap panel default is 20px */
}
.template-choose-list input[type="radio"] {
.template-choose-list input[type="radio"]
, .storage-choose-list input[type="radio"]
{
float: right;
}
...
...
circle/dashboard/templates/dashboard/_data_store_host-create.html
0 → 100644
View file @
c5c309fa
{% load i18n %}
{% load crispy_forms_tags %}
<form
id=
"data_store_host_form"
action=
"{% url "
dashboard
.
views
.
storage-host-create
"
%}"
method=
"POST"
>
<div
class=
"alert alert-danger"
style=
"display: none;"
id=
"data_store_host-create-alert"
>
</div>
{% with form=form %}
{% include "display-form-errors.html" %}
{% endwith %}
{% csrf_token %}
<div
class=
"row"
>
<div
class=
"col-xs-12"
>
{{ form.name|as_crispy_field }}
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-xs-9"
>
{{ form.address|as_crispy_field }}
</div>
<div
class=
"col-xs-3"
>
{{ form.port|as_crispy_field }}
</div>
</div>
<input
type=
"submit"
value=
"{% trans "
Create
new
host
"
%}"
class=
"btn btn-success"
id=
"data_store_host_host-create-btn"
>
</form>
<style>
fieldset
{
margin-top
:
40px
;
}
fieldset
legend
{
font-weight
:
bold
;
}
</style>
circle/dashboard/templates/dashboard/_disk-list-element.html
View file @
c5c309fa
...
...
@@ -26,5 +26,6 @@
{% if request.user.is_superuser %}
<small>
{% trans "File name" %}: {{ d.filename }}
</small><br/>
<small>
{% trans "Bus" %}: {{ d.device_bus }}
</small>
<small>
{% trans "Bus" %}: {{ d.device_bus }}
</small><br/>
<small>
{% trans "Data store" %}: {{ d.datastore }}
</small>
{% endif %}
circle/dashboard/templates/dashboard/_storage-choose.html
0 → 100644
View file @
c5c309fa
{% load i18n %}
<div
class=
"alert alert-info"
id=
"storage-choose-alert"
>
{% trans "Choose the type of the data store that you want to create." %}
</div>
<form
action=
"{% url "
dashboard
.
views
.
storage-choose
"
%}"
method=
"POST"
id=
"storage-choose-form"
>
{% csrf_token %}
<div
class=
"storage-choose-list"
>
{% for t in types %}
<div
class=
"panel panel-default storage-choose-list-element"
>
<input
type=
"radio"
name=
"type"
value=
"{{ t.0 }}"
/>
{{ t.1 }}
<div
class=
"clearfix"
></div>
</div>
{% endfor %}
<button
type=
"submit"
id=
"storage-choose-next-button"
class=
"btn btn-success pull-right"
>
{% trans "Next" %}
</button>
<div
class=
"clearfix"
></div>
</div>
</form>
<script>
$
(
function
()
{
$
(
".storage-choose-list-element"
).
click
(
function
()
{
$
(
"input"
,
$
(
this
)).
prop
(
"checked"
,
true
);
});
$
(
".storage-choose-list-element"
).
hover
(
function
()
{
$
(
"small"
,
$
(
this
)).
stop
().
fadeIn
(
200
);
},
function
()
{
$
(
"small"
,
$
(
this
)).
stop
().
fadeOut
(
200
);
}
);
});
</script>
circle/dashboard/templates/dashboard/_storage-create.html
0 → 100644
View file @
c5c309fa
{% load i18n %}
{% load crispy_forms_tags %}
<form
id=
"storage-create-form"
action=
""
method=
"POST"
>
{% with form=form %}
{% include "display-form-errors.html" %}
{% endwith %}
{% csrf_token %}
{{ form.type }}
<fieldset>
<legend>
{% trans "General settings" %}
</legend>
{{ form.name|as_crispy_field }}
{{ form.path|as_crispy_field }}
{{ form.hostname|as_crispy_field }}
</fieldset>
{% if form.type.value == "ceph_block" %}
<fieldset>
<legend>
{% trans "Ceph block storage authentication settings" %}
</legend>
{{ form.ceph_user|as_crispy_field }}
{{ form.secret_uuid|as_crispy_field }}
</fieldset>
<fieldset>
<legend>
{% trans "Select or add new Ceph monitor hostname(s)" %}
</legend>
{% include 'dashboard/storage/hostname_selector.html' %}
</fieldset>
{% endif %}
<fieldset>
<input
type=
"submit"
value=
"{% trans "
Create
new
data
store
"
%}"
class=
"btn btn-success"
>
</fieldset>
</form>
<style>
fieldset
{
margin-top
:
40px
;
}
fieldset
legend
{
font-weight
:
bold
;
}
</style>
circle/dashboard/templates/dashboard/storage-list.html
View file @
c5c309fa
...
...
@@ -23,7 +23,6 @@
<div
class=
"input-group"
>
{{ search_form.s }}
<div
class=
"input-group-btn"
>
{{ search_form.stype }}
<button
type=
"submit"
class=
"btn btn-primary input-tags"
>
<i
class=
"fa fa-search"
></i>
</button>
...
...
circle/dashboard/templates/dashboard/storage/hostname_selector.html
0 → 100644
View file @
c5c309fa
<div
class=
"row"
>
<div
class=
"col-xs-5"
>
<div
class=
"controls"
>
<select
multiple=
"multiple"
class=
"selectmultiple form-control"
id=
"id_hostnames"
name=
"hostnames"
>
{% for hostname in hostnames %}
<option
value=
"{{ hostname.id }}"
>
{{ hostname }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"col-xs-1"
>
<div
class=
"row text-center"
>
<div
class=
"btn"
onclick=
"move('#id_hostnames', '#id_other_hostnames')"
>
<i
class=
"fa fa-arrow-left fa-2x"
></i>
</div>
</div>
<div
class=
"row text-center"
>
<div
class=
"btn"
onclick=
"move('#id_other_hostnames', '#id_hostnames')"
>
<i
class=
"fa fa-arrow-right fa-2x"
></i>
</div>
</div>
</div>
<div
class=
"col-xs-5"
>
<div
class=
"controls"
>
<select
multiple=
"multiple"
class=
"selectmultiple form-control"
id=
"id_other_hostnames"
name=
"other_hostnames"
>
{% for hostname in other_hostnames %}
<option
value=
"{{ hostname.id }}"
>
{{ hostname }}
</option>
{% endfor %}
</select>
</div>
</div>
<div
class=
"col-xs-1 text-left"
>
<a
href=
"{% url "
dashboard
.
views
.
storage-host-create
"
%}"
class=
"btn btn-success btn-xs data_store_host-create"
>
<i
class=
"fa fa-plus fa-2x"
></i>
</a>
</div>
</div>
<script
type=
"text/javascript"
>
function
move
(
to
,
from
){
var
selected_items
=
$
(
from
).
find
(
":selected"
);
$
(
to
).
append
(
selected_items
);
}
</script>
circle/dashboard/urls.py
View file @
c5c309fa
...
...
@@ -53,7 +53,8 @@ from .views import (
OpenSearchDescriptionView
,
NodeActivityView
,
UserList
,
StorageDetail
,
StorageList
,
DiskDetail
,
StorageDetail
,
StorageList
,
StorageChoose
,
StorageCreate
,
DiskDetail
,
DataStoreHostCreate
,
MessageList
,
MessageDetail
,
MessageCreate
,
MessageDelete
,
)
from
.views.vm
import
vm_ops
,
vm_mass_ops
...
...
@@ -233,13 +234,17 @@ urlpatterns = patterns(
url
(
r'^vm/opensearch.xml$'
,
OpenSearchDescriptionView
.
as_view
(),
name
=
"dashboard.views.vm-opensearch"
),
url
(
r'^storage/create/(?P<type>.+)$'
,
StorageCreate
.
as_view
(),
name
=
"dashboard.views.storage-create"
),
url
(
r'^storage/(?P<pk>\d+)/$'
,
StorageDetail
.
as_view
(),
name
=
'dashboard.views.storage-detail'
),
url
(
r'^storage/list/$'
,
StorageList
.
as_view
(),
name
=
"dashboard.views.storage-list"
),
url
(
r'^storage/choose/$'
,
Storage
Detail
.
as_view
(),
url
(
r'^storage/choose/$'
,
Storage
Choose
.
as_view
(),
name
=
"dashboard.views.storage-choose"
),
url
(
r'^storage/host/create/$'
,
DataStoreHostCreate
.
as_view
(),
name
=
"dashboard.views.storage-host-create"
),
url
(
r'^disk/(?P<pk>\d+)/$'
,
DiskDetail
.
as_view
(),
name
=
"dashboard.views.disk-detail"
),
...
...
circle/dashboard/views/storage.py
View file @
c5c309fa
...
...
@@ -19,25 +19,130 @@ from __future__ import unicode_literals, absolute_import
import
logging
from
django.contrib
import
messages
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
,
reverse_lazy
from
django.db.models
import
Q
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.views.generic
import
UpdateView
from
django.views.generic
import
UpdateView
,
TemplateView
,
CreateView
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.shortcuts
import
redirect
from
django_tables2
import
SingleTableView
from
django.http
import
Http404
,
HttpResponse
from
django.core.exceptions
import
PermissionDenied
from
braces.views
import
SuperuserRequiredMixin
,
LoginRequiredMixin
from
sizefield.utils
import
filesizeformat
from
common.models
import
WorkerNotFound
from
storage.models
import
DataStore
,
Disk
from
storage.models
import
DataStore
,
Disk
,
DataStoreHost
from
..tables
import
DiskListTable
,
StorageListTable
from
..forms
import
DataStoreForm
,
DiskForm
,
StorageListSearchForm
from
..forms
import
(
DataStoreForm
,
CephDataStoreForm
,
DiskForm
,
StorageListSearchForm
,
DataStoreHostForm
)
from
.util
import
FilterMixin
import
json
logger
=
logging
.
getLogger
(
__name__
)
class
StorageChoose
(
LoginRequiredMixin
,
TemplateView
):
def
get_template_names
(
self
):
if
self
.
request
.
is_ajax
():
return
[
'dashboard/_modal.html'
]
else
:
return
[
'dashboard/nojs-wrapper.html'
]
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
context
=
super
(
StorageChoose
,
self
)
.
get_context_data
(
*
args
,
**
kwargs
)
types
=
DataStore
.
TYPES
context
.
update
({
'box_title'
:
_
(
'Choose data store type'
),
'ajax_title'
:
True
,
'template'
:
"dashboard/_storage-choose.html"
,
'types'
:
types
,
})
return
context
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
request
.
user
.
has_perm
(
'storage.add_datastore'
):
raise
PermissionDenied
()
type
=
request
.
POST
.
get
(
"type"
)
if
any
(
type
in
t
for
t
in
DataStore
.
TYPES
):
return
redirect
(
reverse
(
"dashboard.views.storage-create"
,
kwargs
=
{
"type"
:
type
}))
else
:
messages
.
warning
(
request
,
_
(
"Select an option to proceed."
))
return
redirect
(
reverse
(
"dashboard.views.storage-choose"
))
class
StorageCreate
(
SuccessMessageMixin
,
CreateView
):
model
=
DataStore
form
=
None
def
get_template_names
(
self
):
if
self
.
request
.
is_ajax
():
pass
else
:
return
[
'dashboard/nojs-wrapper.html'
]
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
context
=
super
(
StorageCreate
,
self
)
.
get_context_data
(
*
args
,
**
kwargs
)
other_hostnames
=
DataStoreHost
.
objects
.
all
()
context
[
"hostnames_of_datastore"
]
=
[]
context
[
"other_hostnames"
]
=
other_hostnames
context
.
update
({
'box_title'
:
_
(
"Create a new data store"
),
'template'
:
"dashboard/_storage-create.html"
,
})
return
context
def
get
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'storage.add_datastore'
):
raise
PermissionDenied
()
return
super
(
StorageCreate
,
self
)
.
get
(
*
args
,
**
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'storage.add_datastore'
):
raise
PermissionDenied
()
self
.
form
=
self
.
form_class
(
request
.
POST
)
if
not
self
.
form
.
is_valid
():
logger
.
debug
(
"invalid form"
)
return
self
.
get
(
request
,
self
.
form
,
*
args
,
**
kwargs
)
else
:
self
.
form
.
save
()
return
redirect
(
self
.
get_success_url
())
def
get_success_url
(
self
):
return
reverse_lazy
(
"dashboard.views.storage-list"
)
def
get_form
(
self
):
if
self
.
form
is
not
None
:
return
self
.
form
else
:
type
=
self
.
kwargs
.
get
(
"type"
)
fc
=
self
.
form_class
f
=
fc
(
initial
=
{
"type"
:
type
})
return
f
@property
def
form_class
(
self
):
type
=
self
.
kwargs
.
get
(
"type"
)
if
type
==
"file"
:
fc
=
DataStoreForm
elif
type
==
"ceph_block"
:
fc
=
CephDataStoreForm
else
:
raise
Http404
(
_
(
"Invalid creation type"
))
return
fc
class
StorageList
(
LoginRequiredMixin
,
FilterMixin
,
SingleTableView
):
template_name
=
"dashboard/storage-list.html"
model
=
DataStore
...
...
@@ -161,3 +266,70 @@ class DiskDetail(SuperuserRequiredMixin, UpdateView):
def
form_valid
(
self
,
form
):
pass
class
DataStoreHostCreate
(
SuccessMessageMixin
,
CreateView
):
model
=
DataStoreHost
form_class
=
DataStoreHostForm
def
get_template_names
(
self
):
if
self
.
request
.
is_ajax
():
return
[
'dashboard/_modal.html'
]
else
:
return
[
'dashboard/nojs-wrapper.html'
]
def
get_context_data
(
self
,
*
args
,
**
kwargs
):
context
=
super
(
DataStoreHostCreate
,
self
)
.
get_context_data
(
*
args
,
**
kwargs
)
context
.
update
({
'box_title'
:
_
(
"Create a new hostname"
),
'ajax_title'
:
True
,
'template'
:
"dashboard/_data_store_host-create.html"
,
})
return
context
def
get
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.add_datastorehost'
):
raise
PermissionDenied
()
return
super
(
DataStoreHostCreate
,
self
)
.
get
(
*
args
,
**
kwargs
)
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
not
self
.
request
.
user
.
has_perm
(
'vm.add_datastorehost'
):
raise
PermissionDenied
()
form
=
self
.
form_class
(
request
.
POST
)
if
not
form
.
is_valid
():
if
self
.
request
.
is_ajax
():
errors
=
self
.
errors_to_string
(
form
)
return
self
.
json_response
(
False
,
errors
)
else
:
return
self
.
get
(
request
,
form
,
*
args
,
**
kwargs
)
else
:
instance
=
form
.
save
()
if
self
.
request
.
is_ajax
():
resp
=
{
"val"
:
instance
.
id
,
"text"
:
unicode
(
instance
)}
return
self
.
json_response
(
True
,
resp
)
else
:
return
redirect
(
self
.
get_success_url
())
def
json_response
(
self
,
status
,
response
):
resp
=
{
"status"
:
status
,
"response"
:
response
}
return
HttpResponse
(
json
.
dumps
(
resp
),
content_type
=
"application/json"
)
def
errors_to_string
(
self
,
form
):
error_str
=
""
if
form
.
errors
:
for
field
,
error
in
form
.
errors
.
iteritems
():
error_str
+=
"
%
s:
%
s<br />"
%
(
field
,
error
)
for
error
in
form
.
non_field_errors
():
error_str
+=
"
%
s<br />"
%
error
return
error_str
def
get_success_url
(
self
):
return
reverse_lazy
(
"dashboard.views.storage-list"
)
# TODO
circle/storage/migrations/0004_auto_20151212_0402.py
0 → 100644
View file @
c5c309fa
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
import
storage.models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'storage'
,
'0003_auto_20151122_2104'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'datastorehost'
,
name
=
'name'
,
field
=
models
.
CharField
(
default
=
'Monitor1'
,
unique
=
True
,
max_length
=
255
,
verbose_name
=
'name'
),
preserve_default
=
False
,
),
migrations
.
AlterField
(
model_name
=
'datastore'
,
name
=
'path'
,
field
=
models
.
CharField
(
unique
=
True
,
max_length
=
200
,
verbose_name
=
'path'
,
validators
=
[
storage
.
models
.
validate_ascii
]),
),
migrations
.
AlterField
(
model_name
=
'disk'
,
name
=
'filename'
,
field
=
models
.
CharField
(
unique
=
True
,
max_length
=
256
,
verbose_name
=
'filename'
,
validators
=
[
storage
.
models
.
validate_ascii
]),
),
]
circle/storage/models.py
View file @
c5c309fa
...
...
@@ -55,9 +55,13 @@ class DataStoreHost(Model):
""" Address and port of a data store.
"""
name
=
CharField
(
max_length
=
255
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
address
=
CharField
(
max_length
=
1024
,
verbose_name
=
_
(
'address'
))
port
=
IntegerField
(
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'port'
))
def
__unicode__
(
self
):
return
u"
%
s |
%
s:
%
d"
%
(
self
.
name
,
self
.
address
,
self
.
port
)
class
DataStore
(
Model
):
...
...
@@ -133,7 +137,8 @@ class DataStore(Model):
"""
queue_name
=
self
.
get_remote_queue_name
(
'storage'
,
"slow"
)
files
=
set
(
storage_tasks
.
list_files
.
apply_async
(
args
=
[
self
.
type
,
self
.
path
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
))
args
=
[
self
.
type
,
self
.
path
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
))
disks
=
set
([
disk
.
filename
for
disk
in
self
.
disk_set
.
all
()])
orphans
=
[]
...
...
@@ -148,7 +153,8 @@ class DataStore(Model):
"""
queue_name
=
self
.
get_remote_queue_name
(
'storage'
,
"slow"
)
files
=
set
(
storage_tasks
.
list_files
.
apply_async
(
args
=
[
self
.
type
,
self
.
path
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
))
args
=
[
self
.
type
,
self
.
path
],
queue
=
queue_name
)
.
get
(
timeout
=
timeout
))
disks
=
Disk
.
objects
.
filter
(
destroyed__isnull
=
True
,
is_ready
=
True
,
datastore
=
self
)
return
disks
.
exclude
(
filename__in
=
files
)
...
...
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