Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gelencsér Szabolcs
/
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
a4cab8dc
authored
Oct 23, 2016
by
Szabolcs Gelencser
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add template capture, and create from template feature
parent
4e4171b6
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
213 additions
and
71 deletions
+213
-71
circle/dashboard/forms.py
+15
-20
circle/dashboard/views/template.py
+1
-2
circle/vm/migrations/0013_auto_20161016_2121.py
+32
-0
circle/vm/migrations/0014_auto_20161016_2124.py
+29
-0
circle/vm/migrations/0015_auto_20161016_2125.py
+24
-0
circle/vm/migrations/0016_auto_20161016_2130.py
+24
-0
circle/vm/migrations/0017_auto_20161016_2355.py
+26
-0
circle/vm/migrations/0018_instance_vhd_uri.py
+19
-0
circle/vm/models/instance.py
+12
-5
circle/vm/operations.py
+26
-43
circle/vm/tasks/vm_tasks.py
+5
-1
No files found.
circle/dashboard/forms.py
View file @
a4cab8dc
...
...
@@ -468,30 +468,25 @@ class VmSizeChoiceField(forms.ModelChoiceField):
obj
.
os_disk_size_in_mb
,
obj
.
resource_disk_size_in_mb
,
obj
.
max_data_disk_count
)
#TODO: this is terribly slow, should make 4 choicefields, and set choices
# with JS value changed event, and AJAX calls
# ONLY FOR TESTING PURPOSES
class
VmTemplateChoiceField
(
forms
.
ModelChoiceField
):
def
label_from_instance
(
self
,
obj
):
version
=
obj
sku
=
obj
.
sku
offer
=
sku
.
offer
pub
=
offer
.
publisher
return
"
%
s -
%
s -
%
s -
%
s"
%
(
pub
.
name
,
offer
.
name
,
sku
.
name
,
version
.
name
)
class
TemplateForm
(
forms
.
ModelForm
):
azure_vm_size
=
VmSizeChoiceField
(
queryset
=
AzureVirtualMachineSize
.
objects
.
all
())
#TODO: this is terribly slow, should make 4 choicefields, and set choices
# with JS value changed event, and AJAX calls
# ONLY FOR TESTING PURPOSES
def
generate_azure_template_list
():
result
=
[]
for
p
in
AzureBuiltinPublisher
.
objects
.
all
():
for
o
in
p
.
azure_offer
.
all
():
for
s
in
o
.
azure_sku
.
all
():
for
v
in
s
.
azure_version
.
all
():
result
.
append
((
v
.
pk
,
"
%
s -
%
s -
%
s -
%
s"
%
(
p
.
name
,
o
.
name
,
s
.
name
,
v
.
name
),
))
return
result
azure_template
=
forms
.
ChoiceField
(
choices
=
generate_azure_template_list
)
azure_template
=
VmTemplateChoiceField
(
queryset
=
AzureBuiltinVersion
.
objects
.
all
())
networks
=
forms
.
ModelMultipleChoiceField
(
queryset
=
None
,
required
=
False
,
label
=
_
(
"Networks"
))
...
...
circle/dashboard/views/template.py
View file @
a4cab8dc
...
...
@@ -144,13 +144,12 @@ class TemplateCreate(SuccessMessageMixin, CreateView):
networks
=
self
.
__create_networks
(
post
.
pop
(
"networks"
),
request
.
user
)
post
.
pop
(
"parent"
)
post
.
pop
(
"vhd_uri"
)
post
[
'max_ram_size'
]
=
post
[
'ram_size'
]
req_traits
=
post
.
pop
(
"req_traits"
)
tags
=
post
.
pop
(
"tags"
)
post
[
'pw'
]
=
User
.
objects
.
make_random_password
()
+
"aA1"
post
[
'is_base'
]
=
True
post
[
'azure_template'
]
=
AzureBuiltinVersion
.
objects
.
get
(
pk
=
post
[
'azure_template'
])
inst
=
Instance
.
create
(
params
=
post
,
disks
=
[],
networks
=
networks
,
tags
=
tags
,
req_traits
=
req_traits
)
...
...
circle/vm/migrations/0013_auto_20161016_2121.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0012_auto_20161011_1414'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'instancetemplate'
,
name
=
'azure_template'
,
field
=
models
.
ForeignKey
(
default
=
''
,
verbose_name
=
'azure vm template'
,
to
=
'vm.AzureBuiltinVersion'
),
preserve_default
=
False
,
),
migrations
.
AddField
(
model_name
=
'instancetemplate'
,
name
=
'azure_vm_size'
,
field
=
models
.
ForeignKey
(
default
=
''
,
verbose_name
=
'azure vm size'
,
to
=
'vm.AzureVirtualMachineSize'
),
preserve_default
=
False
,
),
migrations
.
AddField
(
model_name
=
'instancetemplate'
,
name
=
'vhd_uri'
,
field
=
models
.
TextField
(
default
=
''
,
verbose_name
=
'vhd uri'
),
preserve_default
=
False
,
),
]
circle/vm/migrations/0014_auto_20161016_2124.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0013_auto_20161016_2121'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_template'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm template'
,
blank
=
True
,
to
=
'vm.AzureBuiltinVersion'
),
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_vm_size'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm size'
,
blank
=
True
,
to
=
'vm.AzureVirtualMachineSize'
),
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'vhd_uri'
,
field
=
models
.
TextField
(
verbose_name
=
'vhd uri'
,
blank
=
True
),
),
]
circle/vm/migrations/0015_auto_20161016_2125.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0014_auto_20161016_2124'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_template'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm template'
,
to
=
'vm.AzureBuiltinVersion'
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_vm_size'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm size'
,
to
=
'vm.AzureVirtualMachineSize'
,
null
=
True
),
),
]
circle/vm/migrations/0016_auto_20161016_2130.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0015_auto_20161016_2125'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_template'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm template'
,
blank
=
True
,
to
=
'vm.AzureBuiltinVersion'
,
null
=
True
),
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_vm_size'
,
field
=
models
.
ForeignKey
(
verbose_name
=
'azure vm size'
,
blank
=
True
,
to
=
'vm.AzureVirtualMachineSize'
,
null
=
True
),
),
]
circle/vm/migrations/0017_auto_20161016_2355.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0016_auto_20161016_2130'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_template'
,
field
=
models
.
ForeignKey
(
default
=
8000
,
verbose_name
=
'azure vm template'
,
to
=
'vm.AzureBuiltinVersion'
),
preserve_default
=
False
,
),
migrations
.
AlterField
(
model_name
=
'instancetemplate'
,
name
=
'azure_vm_size'
,
field
=
models
.
ForeignKey
(
default
=
1
,
verbose_name
=
'azure vm size'
,
to
=
'vm.AzureVirtualMachineSize'
),
preserve_default
=
False
,
),
]
circle/vm/migrations/0018_instance_vhd_uri.py
0 → 100644
View file @
a4cab8dc
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
migrations
,
models
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'vm'
,
'0017_auto_20161016_2355'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'instance'
,
name
=
'vhd_uri'
,
field
=
models
.
TextField
(
verbose_name
=
'vhd uri'
,
blank
=
True
),
),
]
circle/vm/models/instance.py
View file @
a4cab8dc
...
...
@@ -119,6 +119,14 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
'If the machine has agent installed, and '
'the manager should wait for its start.'
))
azure_vm_size
=
ForeignKey
(
AzureVirtualMachineSize
,
verbose_name
=
_
(
'azure vm size'
))
azure_template
=
ForeignKey
(
AzureBuiltinVersion
,
verbose_name
=
_
(
'azure vm template'
))
vhd_uri
=
TextField
(
verbose_name
=
_
(
'vhd uri'
),
blank
=
True
)
class
Meta
:
abstract
=
True
...
...
@@ -262,11 +270,6 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
objects
=
Manager
()
active
=
QueryManager
(
destroyed_at
=
None
)
azure_vm_size
=
ForeignKey
(
AzureVirtualMachineSize
,
verbose_name
=
_
(
'azure vm size'
))
azure_template
=
ForeignKey
(
AzureBuiltinVersion
,
verbose_name
=
_
(
'azure vm template'
))
class
Meta
:
app_label
=
'vm'
db_table
=
'vm_instance'
...
...
@@ -441,6 +444,10 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
if
amount
>
1
and
'
%
d'
not
in
params
[
'name'
]:
params
[
'name'
]
+=
'
%
d'
params
[
'azure_vm_size'
]
=
template
.
azure_vm_size
params
[
'azure_template'
]
=
template
.
azure_template
params
[
'vhd_uri'
]
=
template
.
vhd_uri
customized_params
=
(
dict
(
params
,
name
=
params
[
'name'
]
.
replace
(
'
%
d'
,
str
(
i
)))
for
i
in
xrange
(
amount
))
...
...
circle/vm/operations.py
View file @
a4cab8dc
...
...
@@ -51,7 +51,6 @@ from .models import (
Instance
,
InstanceActivity
,
InstanceTemplate
,
Interface
,
Node
,
NodeActivity
,
pwgen
)
#from storage.models import DataStore
from
.tasks
import
agent_tasks
,
vm_tasks
...
...
@@ -399,7 +398,7 @@ class DeployOperation(InstanceOperation):
def
_operation
(
self
):
nics
=
[
str
(
nic_id
)
for
nic_id
in
self
.
instance
.
interface_set
.
values_list
(
'azure_id'
,
flat
=
True
)]
#storage_name = DataStore.objects.get(pk=1).name
storage_name
=
os
.
getenv
(
"STORAGEACCOUNT"
)
vm_size_version
=
self
.
instance
.
azure_template
vm_size_sku
=
vm_size_version
.
sku
vm_size_offer
=
vm_size_sku
.
offer
...
...
@@ -411,11 +410,12 @@ class DeployOperation(InstanceOperation):
"pw"
:
self
.
instance
.
pw
,
"vm_size"
:
self
.
instance
.
azure_vm_size
.
name
,
"nics"
:
nics
,
"datastore_name"
:
"mylittledatastore"
,
#
storage_name,
"datastore_name"
:
storage_name
,
"os_publisher"
:
vm_size_publisher
.
name
,
"os_offer"
:
vm_size_offer
.
name
,
"os_sku"
:
vm_size_sku
.
name
,
"os_version"
:
vm_size_version
.
name
,
"vhd_uri"
:
self
.
instance
.
vhd_uri
,
}]
azure_id
=
vm_tasks
.
deploy
.
apply_async
(
...
...
@@ -703,8 +703,6 @@ class SaveAsTemplateOperation(InstanceOperation):
"with users and groups. Anyone who has access to a "
"template (and to the networks it uses) will be able to "
"start an instance of it."
)
has_percentage
=
True
abortable
=
True
required_perms
=
(
'vm.create_template'
,
)
accept_states
=
(
'RUNNING'
,
'STOPPED'
)
async_queue
=
"localhost.man.slow"
...
...
@@ -758,27 +756,13 @@ class SaveAsTemplateOperation(InstanceOperation):
'ram_size'
:
self
.
instance
.
ram_size
,
'raw_data'
:
self
.
instance
.
raw_data
,
'system'
:
self
.
instance
.
system
,
'azure_vm_size'
:
self
.
instance
.
azure_vm_size
,
'azure_template'
:
self
.
instance
.
azure_template
}
params
.
update
(
kwargs
)
params
.
pop
(
"parent_activity"
,
None
)
from
storage.models
import
Disk
def
__try_save_disk
(
disk
):
try
:
return
disk
.
save_as
(
task
)
except
Disk
.
WrongDiskTypeError
:
return
disk
self
.
disks
=
[]
for
disk
in
self
.
instance
.
disks
.
all
():
with
activity
.
sub_activity
(
'saving_disk'
,
readable_name
=
create_readable
(
ugettext_noop
(
"saving disk
%(name)
s"
),
name
=
disk
.
name
)
):
self
.
disks
.
append
(
__try_save_disk
(
disk
))
#TODO: create data disks
# create template and do additional setup
tmpl
=
InstanceTemplate
(
**
params
)
...
...
@@ -792,10 +776,22 @@ class SaveAsTemplateOperation(InstanceOperation):
tmpl
.
set_level
(
self
.
instance
.
template
.
owner
,
'owner'
)
tmpl
.
set_level
(
user
,
'owner'
)
try
:
tmpl
.
disks
.
add
(
*
self
.
disks
)
#TODO: add data disks
# create interface templates
for
i
in
self
.
instance
.
interface_set
.
all
():
i
.
save_as_template
(
tmpl
)
# create template in azure
try
:
vhd_uri
=
vm_tasks
.
save_as_template
.
apply_async
(
args
=
[
self
.
instance
.
name
,
self
.
instance
.
pk
],
queue
=
"localhost.vm.fast"
)
.
get
(
timeout
=
1200
)
tmpl
.
vhd_uri
=
vhd_uri
tmpl
.
save
()
#TODO: delete VM (cannot start VM in Azure after generalization)
#self.instance.destroy()
except
:
raise
except
:
tmpl
.
delete
()
raise
...
...
@@ -807,37 +803,24 @@ class SaveAsTemplateOperation(InstanceOperation):
@register_operation
class
ShutdownOperation
(
AbortableRemoteOperationMixin
,
RemoteInstanceOperation
):
class
ShutdownOperation
(
InstanceOperation
):
id
=
'shutdown'
name
=
_
(
"shutdown"
)
description
=
_
(
"Try to halt virtual machine by a standard ACPI signal, "
"allowing the operating system to keep a consistent "
"state. The operation will fail if the machine does not "
"turn itself off in a period."
)
abortable
=
True
required_perms
=
()
accept_states
=
(
'RUNNING'
,
)
resultant_state
=
'STOPPED'
task
=
vm_tasks
.
shutdown
remote_queue
=
(
"vm"
,
"slow"
)
remote_timeout
=
180
def
_operation
(
self
,
task
):
super
(
ShutdownOperation
,
self
)
.
_operation
(
task
=
task
)
self
.
instance
.
yield_node
()
def
on_abort
(
self
,
activity
,
error
):
if
isinstance
(
error
,
TimeLimitExceeded
):
activity
.
result
=
humanize_exception
(
ugettext_noop
(
"The virtual machine did not switch off in the provided time "
"limit. Most of the time this is caused by incorrect ACPI "
"settings. You can also try to power off the machine from the "
"operating system manually."
),
error
)
activity
.
resultant_state
=
None
else
:
super
(
ShutdownOperation
,
self
)
.
on_abort
(
activity
,
error
)
activity
.
resultant_state
=
'RUNNING'
def
_operation
(
self
,
task
):
vm_tasks
.
shutdown
.
apply_async
(
args
=
[
self
.
instance
.
name
],
queue
=
"localhost.vm.fast"
)
.
get
(
timeout
=
1200
)
@register_operation
class
ShutOffOperation
(
InstanceOperation
):
...
...
circle/vm/tasks/vm_tasks.py
View file @
a4cab8dc
...
...
@@ -61,6 +61,10 @@ def get_queues():
cache
.
set
(
key
,
result
,
10
)
return
result
@celery.task
(
name
=
'vmdriver.save_as_template'
)
def
save_as_template
(
vm_name
,
vm_pk
):
pass
@celery.task
(
name
=
'vmdriver.attach_disk'
)
def
attach_disk
(
vm
,
disk
):
...
...
@@ -113,7 +117,7 @@ def resume(params):
@celery.task
(
name
=
'vmdriver.shutdown'
)
def
shutdown
(
params
):
def
shutdown
(
vm_name
):
pass
...
...
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