Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
CIRCLE
/
cloud
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
94
Merge Requests
10
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
002facdf
authored
4 years ago
by
Szeberényi Imre
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'template_instance_limit' into 'master'
Template instance limit See merge request
!418
parents
9e18bdbf
729d6f82
Pipeline
#1361
passed with stage
in 0 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
18 deletions
+63
-18
circle/dashboard/forms.py
+10
-2
circle/dashboard/migrations/0008_profile_template_instance_limit.py
+20
-0
circle/dashboard/models.py
+1
-0
circle/dashboard/tests/test_views.py
+2
-2
circle/dashboard/views/vm.py
+27
-14
circle/vm/models/instance.py
+3
-0
No files found.
circle/dashboard/forms.py
View file @
002facdf
...
...
@@ -1336,6 +1336,9 @@ class UserEditForm(forms.ModelForm):
instance_limit
=
forms
.
IntegerField
(
label
=
_
(
'Instance limit'
),
min_value
=
0
,
widget
=
NumberInput
)
template_instance_limit
=
forms
.
IntegerField
(
label
=
_
(
'Template instance limit'
),
min_value
=
0
,
widget
=
NumberInput
)
two_factor_secret
=
forms
.
CharField
(
label
=
_
(
'Two-factor authentication secret'
),
help_text
=
_
(
"Remove the secret key to disable two-factor "
...
...
@@ -1345,18 +1348,23 @@ class UserEditForm(forms.ModelForm):
super
(
UserEditForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
fields
[
"instance_limit"
]
.
initial
=
(
self
.
instance
.
profile
.
instance_limit
)
self
.
fields
[
"template_instance_limit"
]
.
initial
=
(
self
.
instance
.
profile
.
template_instance_limit
)
self
.
fields
[
"two_factor_secret"
]
.
initial
=
(
self
.
instance
.
profile
.
two_factor_secret
)
class
Meta
:
model
=
User
fields
=
(
'email'
,
'first_name'
,
'last_name'
,
'instance_limit'
,
'is_active'
,
"two_factor_secret"
,)
fields
=
(
'email'
,
'first_name'
,
'last_name'
,
'instance_limit'
,
'template_instance_limit'
,
'is_active'
,
'two_factor_secret'
,)
def
save
(
self
,
commit
=
True
):
user
=
super
(
UserEditForm
,
self
)
.
save
()
user
.
profile
.
instance_limit
=
(
self
.
cleaned_data
[
'instance_limit'
]
or
None
)
user
.
profile
.
template_instance_limit
=
(
self
.
cleaned_data
[
'template_instance_limit'
]
or
None
)
user
.
profile
.
two_factor_secret
=
(
self
.
cleaned_data
[
'two_factor_secret'
]
or
None
)
user
.
profile
.
save
()
...
...
This diff is collapsed.
Click to expand it.
circle/dashboard/migrations/0008_profile_template_instance_limit.py
0 → 100644
View file @
002facdf
# -*- coding: utf-8 -*-
# Generated by Django 1.11.25 on 2020-11-06 13:33
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'dashboard'
,
'0007_groupprofile_disk_quota'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'profile'
,
name
=
'template_instance_limit'
,
field
=
models
.
IntegerField
(
default
=
1
),
),
]
This diff is collapsed.
Click to expand it.
circle/dashboard/models.py
View file @
002facdf
...
...
@@ -178,6 +178,7 @@ class Profile(Model):
unique
=
True
,
blank
=
True
,
null
=
True
,
max_length
=
64
,
help_text
=
_
(
'Unique identifier of the person, e.g. a student number.'
))
instance_limit
=
IntegerField
(
default
=
5
)
template_instance_limit
=
IntegerField
(
default
=
1
)
use_gravatar
=
BooleanField
(
verbose_name
=
_
(
"Use Gravatar"
),
default
=
True
,
help_text
=
_
(
"Whether to use email address as Gravatar profile image"
))
...
...
This diff is collapsed.
Click to expand it.
circle/dashboard/tests/test_views.py
View file @
002facdf
...
...
@@ -534,7 +534,7 @@ class VmDetailTest(LoginMixin, MockCeleryMixin, TestCase):
with
patch
.
object
(
DeployOperation
,
'async'
)
as
async
:
response
=
c
.
post
(
"/dashboard/vm/create/"
,
{
'name'
:
'vm'
,
'amount'
:
2
,
'amount'
:
1
,
'customized'
:
1
,
'template'
:
1
,
'cpu_priority'
:
10
,
'cpu_count'
:
1
,
'ram_size'
:
128
,
...
...
@@ -543,7 +543,7 @@ class VmDetailTest(LoginMixin, MockCeleryMixin, TestCase):
assert
async
.
called
self
.
assertEqual
(
response
.
status_code
,
302
)
self
.
assertEqual
(
instance_count
+
2
,
Instance
.
objects
.
all
()
.
count
())
self
.
assertEqual
(
instance_count
+
1
,
Instance
.
objects
.
all
()
.
count
())
def
test_unpermitted_description_update
(
self
):
c
=
Client
()
...
...
This diff is collapsed.
Click to expand it.
circle/dashboard/views/vm.py
View file @
002facdf
...
...
@@ -460,8 +460,7 @@ class VmMigrateView(FormOperationMixin, VmOperationView):
if
isinstance
(
inst
,
Instance
):
nodes_w_traits
=
[
n
.
pk
for
n
in
Node
.
objects
.
filter
(
enabled
=
True
)
if
n
.
online
and
has_traits
(
inst
.
req_traits
.
all
(),
n
)
if
n
.
online
and
has_traits
(
inst
.
req_traits
.
all
(),
n
)
]
ctx
[
'nodes_w_traits'
]
=
nodes_w_traits
...
...
@@ -1166,24 +1165,28 @@ class VmCreate(LoginRequiredMixin, TemplateView):
# limit chekcs
try
:
limit
=
user
.
profile
.
instance_limit
instance_limit
=
user
.
profile
.
instance_limit
template_instance_limit
=
user
.
profile
.
template_instance_limit
except
Exception
as
e
:
logger
.
debug
(
'No profile or instance limit:
%
s'
,
e
)
else
:
try
:
amount
=
int
(
request
.
POST
.
get
(
"amount"
,
1
))
except
:
amount
=
limit
# TODO this should definitely use a Form
current
=
Instance
.
active
.
filter
(
owner
=
user
)
.
count
()
logger
.
debug
(
'current use:
%
d, limit:
%
d'
,
current
,
limit
)
if
current
+
amount
>
limit
:
messages
.
error
(
request
,
_
(
'Instance limit (
%
d) exceeded.'
)
%
limit
)
if
request
.
is_ajax
():
return
HttpResponse
(
json
.
dumps
({
'redirect'
:
'/'
}),
content_type
=
"application/json"
)
else
:
return
redirect
(
'/'
)
# TODO this should definitely use a Form
amount
=
instance_limit
instances
=
Instance
.
active
.
filter
(
owner
=
user
)
.
count
()
template_instances
=
template
.
get_user_instances
(
user
)
.
count
()
logger
.
debug
(
'current instance use:
%
d, limit:
%
d'
,
instances
,
instance_limit
)
logger
.
debug
(
'current template instance use:
%
d, limit:
%
d'
,
template_instances
,
template_instance_limit
)
if
instances
+
amount
>
instance_limit
:
return
self
.
_limit_exceeded
(
instance_limit
,
request
)
if
template_instances
+
amount
>
template_instance_limit
:
return
self
.
_limit_exceeded
(
template_instance_limit
,
request
)
create_func
=
(
self
.
__create_normal
if
request
.
POST
.
get
(
"customized"
)
is
None
else
...
...
@@ -1191,6 +1194,16 @@ class VmCreate(LoginRequiredMixin, TemplateView):
return
create_func
(
request
,
template
,
*
args
,
**
kwargs
)
def
_limit_exceeded
(
self
,
limit
,
request
):
messages
.
error
(
request
,
_
(
'Instance limit (
%
d) exceeded.'
)
%
limit
)
if
request
.
is_ajax
():
return
HttpResponse
(
json
.
dumps
({
'redirect'
:
'/'
}),
content_type
=
"application/json"
)
else
:
return
redirect
(
'/'
)
@require_GET
def
get_vm_screenshot
(
request
,
pk
):
...
...
This diff is collapsed.
Click to expand it.
circle/vm/models/instance.py
View file @
002facdf
...
...
@@ -200,6 +200,9 @@ class InstanceTemplate(AclBase, VirtualMachineDescModel, TimeStampedModel):
def
get_running_instances
(
self
):
return
Instance
.
active
.
filter
(
template
=
self
,
status
=
"RUNNING"
)
def
get_user_instances
(
self
,
user
):
return
Instance
.
active
.
filter
(
template
=
self
,
owner
=
user
)
@property
def
metric_prefix
(
self
):
return
'template.
%
d'
%
self
.
pk
...
...
This diff is collapsed.
Click to expand it.
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