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
6efe1ef5
authored
Feb 09, 2013
by
Őry Máté
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
one: add save as functionality
parent
e9fe67c6
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
494 additions
and
145 deletions
+494
-145
cloud/urls.py
+2
-0
one/admin.py
+1
-0
one/migrations/0009_auto__add_field_instancetype_credit.py
+236
-0
one/models.py
+18
-9
one/static/base.less
+26
-0
one/static/box.less
+21
-0
one/templates/home.html
+3
-0
one/templates/new-template-flow-1.html
+60
-0
one/templates/new-template-flow.html
+47
-120
one/templates/show.html
+23
-0
one/views.py
+57
-16
No files found.
cloud/urls.py
View file @
6efe1ef5
...
...
@@ -26,12 +26,14 @@ urlpatterns = patterns('',
url
(
r'^vm/restart/(?P<iid>\d+)/$'
,
'one.views.vm_restart'
,
name
=
'vm_restart'
),
url
(
r'^vm/port_add/(?P<iid>\d+)/$'
,
'one.views.vm_port_add'
,
name
=
'vm_port_add'
),
url
(
r'^vm/port_del/(?P<iid>\d+)/(?P<proto>tcp|udp)/(?P<public>\d+)/$'
,
'one.views.vm_port_del'
,
name
=
'vm_port_del'
),
url
(
r'^vm/saveas/(?P<vmid>\d+)$'
,
'one.views.vm_saveas'
,
name
=
'vm_saveas'
),
url
(
r'^reload/$'
,
'firewall.views.reload_firewall'
,
name
=
'reload_firewall'
),
url
(
r'^fwapi/$'
,
'firewall.views.firewall_api'
,
name
=
'firewall_api'
),
url
(
r'^store/$'
,
'store.views.index'
,
name
=
'store_index'
),
url
(
r'^store/gui/$'
,
'store.views.gui'
,
name
=
'store_gui'
),
url
(
r'^store/top/$'
,
'store.views.toplist'
,
name
=
'store_top'
),
url
(
r'^ajax/templateWizard$'
,
'one.views.ajax_template_wizard'
,
name
=
'ajax_template_wizard'
),
url
(
r'^ajax/template_name_unique/(?P<name>.*)$'
,
'one.views.ajax_template_name_unique'
,
name
=
'ajax_template_name_unique'
),
url
(
r'^ajax/store/list$'
,
'store.views.ajax_listfolder'
,
name
=
'store_ajax_listfolder'
),
url
(
r'^ajax/store/download$'
,
'store.views.ajax_download'
,
name
=
'store_ajax_download'
),
url
(
r'^ajax/store/upload$'
,
'store.views.ajax_upload'
,
name
=
'store_ajax_upload'
),
...
...
one/admin.py
View file @
6efe1ef5
...
...
@@ -47,6 +47,7 @@ submit_vm.short_description = _('Submit VM')
class
TemplateAdmin
(
contrib
.
admin
.
ModelAdmin
):
model
=
models
.
Template
list_display
=
(
'name'
,
'state'
,
'owner'
,
'system'
)
class
InstanceAdmin
(
contrib
.
admin
.
ModelAdmin
):
model
=
models
.
Instance
...
...
one/migrations/0009_auto__add_field_instancetype_credit.py
0 → 100644
View file @
6efe1ef5
# -*- coding: utf-8 -*-
import
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 'InstanceType.credit'
db
.
add_column
(
'one_instancetype'
,
'credit'
,
self
.
gf
(
'django.db.models.fields.IntegerField'
)(
default
=
1
),
keep_default
=
False
)
def
backwards
(
self
,
orm
):
# Deleting field 'InstanceType.credit'
db
.
delete_column
(
'one_instancetype'
,
'credit'
)
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'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'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'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'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'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'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'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'
}),
'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'
})
},
'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'
}),
'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'
:
"orm['auth.User']"
}),
'ttl'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'600'
})
},
'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'
}),
'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'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
'firewall.host'
:
{
'Meta'
:
{
'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'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
"orm['firewall.Group']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'hostname'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'40'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ipv4'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'39'
}),
'ipv6'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'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'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'pub_ipv4'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'max_length'
:
'39'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'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'
:
"orm['firewall.Vlan']"
})
},
'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'
:
"orm['firewall.Domain']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'interface'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'ipv4'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'39'
}),
'ipv6'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'39'
}),
'modified_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'net4'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'39'
}),
'net6'
:
(
'django.db.models.fields.GenericIPAddressField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'39'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'prefix4'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'16'
}),
'prefix6'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'80'
}),
'reverse_domain'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'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'
:
"orm['firewall.Vlan']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'vid'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
})
},
'one.disk'
:
{
'Meta'
:
{
'ordering'
:
"['name']"
,
'object_name'
:
'Disk'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
})
},
'one.instance'
:
{
'Meta'
:
{
'object_name'
:
'Instance'
},
'active_since'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'firewall_host'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['firewall.Host']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'ip'
:
(
'django.db.models.fields.IPAddressField'
,
[],
{
'max_length'
:
'15'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'one_id'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'pw'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'share'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.Share']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'DEPLOYABLE'"
,
'max_length'
:
'20'
}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.Template']"
}),
'time_of_delete'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
}),
'time_of_suspend'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
})
},
'one.instancetype'
:
{
'CPU'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'Meta'
:
{
'object_name'
:
'InstanceType'
},
'RAM'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'credit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
})
},
'one.network'
:
{
'Meta'
:
{
'ordering'
:
"['name']"
,
'object_name'
:
'Network'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'nat'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'public'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
})
},
'one.share'
:
{
'Meta'
:
{
'object_name'
:
'Share'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{}),
'group'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['school.Group']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_limit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'per_user_limit'
:
(
'django.db.models.fields.IntegerField'
,
[],
{}),
'template'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.Template']"
}),
'type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
})
},
'one.sshkey'
:
{
'Meta'
:
{
'object_name'
:
'SshKey'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'key'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'2000'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'one.template'
:
{
'Meta'
:
{
'object_name'
:
'Template'
},
'access_type'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'description'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'disk'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.Disk']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.InstanceType']"
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'100'
}),
'network'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.Network']"
}),
'owner'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'public'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'state'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'NEW'"
,
'max_length'
:
'10'
}),
'system'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
})
},
'one.userclouddetails'
:
{
'Meta'
:
{
'object_name'
:
'UserCloudDetails'
},
'disk_quota'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'2048'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'instance_quota'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'20'
}),
'share_quota'
:
(
'django.db.models.fields.IntegerField'
,
[],
{
'default'
:
'100'
}),
'smb_password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'20'
}),
'ssh_key'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['one.SshKey']"
,
'null'
:
'True'
}),
'ssh_private_key'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'unique'
:
'True'
})
},
'school.course'
:
{
'Meta'
:
{
'object_name'
:
'Course'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'default_group'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'default_group_of'"
,
'null'
:
'True'
,
'to'
:
"orm['school.Group']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'80'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'owners'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'symmetrical'
:
'False'
,
'to'
:
"orm['school.Person']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'short_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'10'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
'school.group'
:
{
'Meta'
:
{
'unique_together'
:
"(('name', 'course', 'semester'),)"
,
'object_name'
:
'Group'
},
'course'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['school.Course']"
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'members'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'course_groups'"
,
'null'
:
'True'
,
'symmetrical'
:
'False'
,
'to'
:
"orm['school.Person']"
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'80'
}),
'owners'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'blank'
:
'True'
,
'related_name'
:
"'owned_groups'"
,
'null'
:
'True'
,
'symmetrical'
:
'False'
,
'to'
:
"orm['school.Person']"
}),
'semester'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['school.Semester']"
})
},
'school.person'
:
{
'Meta'
:
{
'object_name'
:
'Person'
},
'code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'language'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'hu'"
,
'max_length'
:
'10'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'unique'
:
'True'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
'school.semester'
:
{
'Meta'
:
{
'object_name'
:
'Semester'
},
'end'
:
(
'django.db.models.fields.DateField'
,
[],
{}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'20'
}),
'start'
:
(
'django.db.models.fields.DateField'
,
[],
{})
}
}
complete_apps
=
[
'one'
]
\ No newline at end of file
one/models.py
View file @
6efe1ef5
...
...
@@ -122,10 +122,11 @@ class SshKey(models.Model):
TEMPLATE_STATES
=
((
"INIT"
,
_
(
'init'
)),
(
"PREP"
,
_
(
'perparing'
)),
(
"SAVE"
,
_
(
'saving'
)),
(
"READY"
,
_
(
'ready'
)))
TYPES
=
{
"LAB"
:
{
"verbose_name"
:
_
(
'lab'
),
"
suspend"
:
td
(
hours
=
5
),
"delete"
:
td
(
days
=
15
)},
"PROJECT"
:
{
"verbose_name"
:
_
(
'project'
),
"
suspend"
:
td
(
weeks
=
5
),
"delete"
:
td
(
days
=
366
/
2
)},
"SERVER"
:
{
"verbose_name"
:
_
(
'server'
),
"
suspend"
:
td
(
days
=
365
),
"delete"
:
None
},
TYPES
=
{
"LAB"
:
{
"verbose_name"
:
_
(
'lab'
),
"
id"
:
"LAB"
,
"suspend"
:
td
(
hours
=
5
),
"delete"
:
td
(
days
=
15
),
"help_text"
:
_
(
'For lab or home work with short life time.'
)},
"PROJECT"
:
{
"verbose_name"
:
_
(
'project'
),
"
id"
:
"PROJECT"
,
"suspend"
:
td
(
weeks
=
5
),
"delete"
:
td
(
days
=
366
/
2
),
"help_text"
:
_
(
'For project work.'
)},
"SERVER"
:
{
"verbose_name"
:
_
(
'server'
),
"
id"
:
"SERVER"
,
"suspend"
:
td
(
days
=
365
),
"delete"
:
None
,
"help_text"
:
_
(
'For long term server use.'
)
},
}
TYPES_L
=
sorted
(
TYPES
.
values
(),
key
=
lambda
m
:
m
[
"suspend"
])
TYPES_C
=
tuple
([(
i
[
0
],
i
[
1
][
"verbose_name"
])
for
i
in
TYPES
.
items
()])
class
Share
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
_
(
'name'
))
...
...
@@ -222,10 +223,14 @@ class InstanceType(models.Model):
verbose_name
=
_
(
'name'
))
CPU
=
models
.
IntegerField
(
help_text
=
_
(
'CPU cores.'
))
RAM
=
models
.
IntegerField
(
help_text
=
_
(
'Mebibytes of memory.'
))
credit
=
models
.
IntegerField
(
verbose_name
=
_
(
'credits'
),
help_text
=
_
(
'Price of instance.'
))
def
__unicode__
(
self
):
return
u"
%
s"
%
self
.
name
class
Meta
:
ordering
=
[
'credit'
]
TEMPLATE_STATES
=
((
'NEW'
,
_
(
'new'
)),
(
'PREPARING'
,
_
(
'preparing'
)),
TEMPLATE_STATES
=
((
'NEW'
,
_
(
'new'
)),
(
'SAVING'
,
_
(
'saving'
)),
(
'READY'
,
_
(
'ready'
)),
)
"""
Virtual machine template specifying OS, disk, type and network.
...
...
@@ -455,7 +460,8 @@ class Instance(models.Model):
proc
=
subprocess
.
Popen
([
"/opt/occi.sh"
,
"compute"
,
"delete"
,
"
%
d"
%
self
.
one_id
],
stdout
=
subprocess
.
PIPE
)
(
out
,
err
)
=
proc
.
communicate
()
self
.
firewall_host
.
delete
()
if
self
.
firewall_host
:
self
.
firewall_host
.
delete
()
reload_firewall_lock
()
def
_update_vm
(
self
,
template
):
...
...
@@ -499,7 +505,10 @@ class Instance(models.Model):
imgname
=
"template-
%
d-
%
d"
%
(
self
.
template
.
id
,
self
.
id
)
self
.
_update_vm
(
'<DISK id="0"><SAVE_AS name="
%
s"/></DISK>'
%
imgname
)
self
.
_change_state
(
"SHUTDOWN"
)
def
is_save_as_done
(
self
):
t
=
self
.
template
t
.
state
=
'SAVING'
t
.
save
()
def
check_if_is_save_as_done
(
self
):
self
.
update_state
()
if
self
.
state
!=
'DONE'
:
return
false
...
...
@@ -509,9 +518,9 @@ class Instance(models.Model):
if
len
(
disks
)
!=
1
:
return
false
self
.
template
.
disk_id
=
disks
[
0
]
.
id
self
.
template
.
stat
us
=
'READY'
self
.
template
.
stat
e
=
'READY'
self
.
template
.
save
()
self
.
host
.
delete
()
self
.
firewall_
host
.
delete
()
return
True
...
...
@@ -523,7 +532,7 @@ def delete_instance(sender, instance, using, **kwargs):
if
instance
.
state
!=
"DONE"
:
instance
.
one_delete
()
try
:
instance
.
host
.
delete
()
instance
.
firewall_
host
.
delete
()
except
:
pass
post_delete
.
connect
(
delete_instance
,
sender
=
Instance
,
dispatch_uid
=
"delete_instance"
)
...
...
one/static/base.less
View file @
6efe1ef5
...
...
@@ -43,6 +43,21 @@ body
margin-top:0;
padding:10px;
}
&.wide {
margin-right: 30px;
}
&.note {
background-color: #ffc;
}
ol {
margin-left: 2em;
&.done {
text-color: #aaa;
}
}
}
.big {
font-size: 2em;
}
.wm-list{
list-style: none;
...
...
@@ -75,6 +90,14 @@ ul.messagelist li.error
{
background-image:url(admin/img/icon_error.gif);
}
input.validated {
padding-right: 15px;
&.error
{
background:#fcc url(admin/img/icon_error.gif) right center no-repeat;
padding-right: 15px;
}
}
.errornote
{
...
...
@@ -187,3 +210,6 @@ textarea {
box-shadow: inset 0 0 10px rgba(0,0,0,0.2), 0 0 10px rgba(255,255,0,0.8);
}
}
.hilight {
background-color: #ff6;
}
one/static/box.less
View file @
6efe1ef5
...
...
@@ -282,6 +282,27 @@
background-image: url(icons/computer--plus.png);
}
}
#template-wizard {
.size-summary {
font-size: .8em;
text-align: right;
span {
background-position: left center;
background-repeat: no-repeat;
padding-left: 18px;
}
.cpu{
background-image: url(icons/processor.png)
}
.memory{
background-image: url(icons/memory.png)
}
.credit{
background-image: url(icons/documents-stack.png) /* TODO */
}
}
}
.file-list{
list-style: none;
...
...
one/templates/home.html
View file @
6efe1ef5
...
...
@@ -73,6 +73,9 @@
<div
class=
"contentblock"
id=
"template"
>
<h2>
{% trans "My templates" %}
</h2>
<ul
class=
"wm-list"
>
{% for t in mytemplates %}
<li
class=
"wm"
>
{{t.name}}
</li>
{% endfor %}
<li
class=
"wm"
>
<div
class=
"summary"
>
<div
class=
"quota"
>
...
...
one/templates/new-template-flow-1.html
0 → 100644
View file @
6efe1ef5
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<form
action=
"/ajax/templateWizard"
method=
"post"
id=
"template-wizard"
>
{% csrf_token %}
<div
id=
"new-template-step-1"
class=
"wizard"
>
<div
class=
"progress"
>
<div
class=
"bar-container"
>
<div
class=
"bar"
style=
"width: 33%"
></div>
</div>
<h3>
{% blocktrans with step=1 all=3 %}{{step}}/{{all}}{% endblocktrans %}
</h3>
</div>
<h2>
{% blocktrans with step=1 %}Step {{step}}{% endblocktrans %}
</h2>
<p
class=
"help"
>
{% trans "Please choose the base system you want to customize." %}
</p>
<div
class=
"container"
>
<ul
class=
"tpl-list modal"
>
{% if not templates %}
<p>
{% trans "There are no available templates." %}
</p>
{% endif %}
{% for m in templates %}
<li
class=
"tpl"
>
<div
class=
"summary"
>
<div
class=
"name tpl os-{{m.os_type}}"
title=
"{{m.description}}"
><label><input
type=
"radio"
name=
"base"
value=
"{{m.id}}"
/>
{{m.name}}
</label></div>
<div
class=
"clear"
></div>
</div>
</li>
{% endfor %}
</ul>
</div>
<nav>
<a
href=
"#"
class=
"prev"
>
{% trans "
«
Cancel" %}
</a>
<input
type=
"submit"
class=
"next"
value=
"{% trans "
Next
&
raquo
;"
%}"
/>
<div
class=
"clear"
></div>
</nav>
<script
type=
"text/javascript"
>
$
(
function
(){
$
(
'#template-wizard nav .prev'
).
click
(
function
(){
$
(
'#modal'
).
hide
();
})
$
(
'#template-wizard'
).
unbind
(
'submit'
).
submit
(
function
(
e
){
if
(
$
(
"#template-wizard input[type=radio]:checked"
).
length
==
0
)
{
$
(
"#template-wizard .help"
).
addClass
(
'hilight'
);
}
else
{
$
.
ajax
({
'type'
:
'POST'
,
'url'
:
'/ajax/templateWizard'
,
'data'
:
$
(
'#template-wizard'
).
serialize
(),
'success'
:
function
(
data
)
{
$
(
'#modal-container'
).
html
(
data
);
}
});
}
e
.
preventDefault
();
e
.
stopPropagation
();
return
false
;
})
})
</script>
</div>
</div>
</form>
one/templates/new-template-flow.html
View file @
6efe1ef5
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<form
action=
"/"
method=
"post"
id=
"template-wizard"
>
<div
id=
"new-template-step-1"
class=
"wizard"
>
<div
class=
"progress"
>
<div
class=
"bar-container"
>
<div
class=
"bar"
style=
"width: 33%"
></div>
</div>
<h3>
{% blocktrans with step=1 all=3 %}{{step}}/{{all}}{% endblocktrans %}
</h3>
</div>
<h2>
{% blocktrans with step=1 %}Step {{step}}{% endblocktrans %}
</h2>
<p>
Leírás, mit is kéne itt ezen az ablakon csinálni, és miért jó, ha azt csinálja, amit.
</p>
<div
class=
"container"
>
<ul
class=
"wm-list modal"
>
{% for m in templates %}
<li
class=
"wm"
>
<form
method=
"POST"
action=
"/vm/new/{{m.pk}}/"
>
{% csrf_token %}
<div
class=
"summary"
>
<div
class=
"name wm-on"
>
{{m.name}}
</div>
<div
class=
"status"
>
<input
type=
"submit"
value=
"Indítás"
/>
</div>
<div
class=
"clear"
></div>
</div>
<div
class=
"details"
>
<h3>
{% trans "Details" %}
</h3>
<ul>
<li
class=
"name"
>
{% trans "System" %}:
<span
class=
"value"
>
{{m.disk.name}}
</span></li>
<li
class=
"type"
>
{% trans "Size" %}:
<span
class=
"value"
>
{{m.instance_type.name}}
</span></li>
<li
class=
"memory"
>
{% trans "Memory" %}:
<span
class=
"value"
>
{{m.instance_type.RAM}} MiB
</span></li>
<li
class=
"cpu"
>
{% trans "CPU cores" %}:
<span
class=
"value"
>
{{m.instance_type.CPU}}
</span></li>
</ul>
</div>
</form>
</li>
{% endfor %}
</ul>
</div>
<nav>
<a
href=
"#"
class=
"prev"
>
{% trans "
«
Cancel" %}
</a>
<a
href=
"#"
class=
"next"
>
{% trans "Next
»
" %}
</a>
<div
class=
"clear"
></div>
</nav>
<script
type=
"text/javascript"
>
$
(
function
(){
console
.
log
(
'foo'
);
$
(
'#modal .wm .summary'
).
each
(
function
(){
$
(
this
).
next
(
'.details'
).
show
();
console
.
log
(
$
(
this
).
next
(
'.details'
).
css
(
'display'
),
$
(
this
).
next
(
'.details'
).
css
(
'height'
));
//this.originalHeight=parseInt($(this).next('.details').css('height'));
})
$
(
'#modal .wm .summary'
).
click
(
function
(){
if
(
$
(
this
).
next
(
'.details'
).
is
(
':hidden'
)){
$
(
this
).
next
(
'.details'
)
.
slideDown
(
700
);
$
(
this
).
parent
(
'.wm'
).
addClass
(
'opened'
);
}
else
{
var
that
=
this
;
$
(
this
).
next
(
'.details'
)
.
removeClass
(
'opened'
)
.
slideUp
(
700
);
}
});
$
(
'#new-template-step-1 nav .prev'
).
click
(
function
(){
$
(
'#new-template-step-1'
).
hide
();
$
(
'#new-template-step-1'
).
show
();
})
$
(
'#new-template-step-1 nav .next'
).
click
(
function
(){
$
(
'#new-template-step-1'
).
hide
();
$
(
'#new-template-step-3'
).
show
();
$
.
ajax
({
'type'
:
'POST'
,
'url'
:
'/ajax/templateWizard'
,
'data'
:
$
(
'#template-wizard'
).
serialize
()
})
.
done
(
function
(){
console
.
log
(
'ok'
)});
})
})
</script>
</div>
<div
id=
"new-template-step-2"
class=
"wizard"
style=
"display: none"
>
<form
action=
"/vm/new/{{base.id}}/"
method=
"post"
id=
"template-wizard"
>
{% csrf_token %}
<div
id=
"new-template-step-2"
class=
"wizard"
>
<div
class=
"progress"
>
<div
class=
"bar-container"
>
<div
class=
"bar"
style=
"width: 66%"
></div>
...
...
@@ -90,69 +9,77 @@
<h3>
{% blocktrans with step=2 all=3 %}{{step}}/{{all}}{% endblocktrans %}
</h3>
</div>
<h2>
{% blocktrans with step=2 %}Step {{step}}{% endblocktrans %}
</h2>
<p>
Leírás, mit is kéne itt ezen az ablakon csinálni, és miért jó, ha azt csinálja, amit.
</p>
<p>
{% trans "Change the parameters as needed." %}
</p>
<ul>
<li>
<label
for=
"new-template-name"
>
{% trans "Name" %}
</label>
<input
type=
"text"
placeholder=
"{% trans "
Short
name
of
template
"
%}"
name=
"name"
id=
"new-template-name"
/>
<input
type=
"text"
name=
"name"
id=
"new-template-name"
value=
"{{base.name}}"
class=
"error validated"
title=
"{% trans "
Please
choose
a
different
name
."
%}"
/>
<div
class=
"clear"
></div>
</li>
<li>
<label
for=
"new-template-type"
>
{% trans "Type" %}
</label>
<ul
class=
"radio"
>
<li>
<input
type=
"radio"
name=
"type"
value=
"labor"
id=
"new-template-type-labor"
/>
<label
for=
"new-template-type-labor"
>
{% trans "Lab" %}
</label>
</li>
<li>
<input
type=
"radio"
name=
"type"
value=
"project"
id=
"new-template-type-project"
/>
<label
for=
"new-template-type-project"
>
{% trans "Project" %}
</label>
</li>
</ul>
<div
class=
"clear"
></div>
</li>
<li>
<li
class=
"new-tpl-size"
>
<label
for=
"new-template-size"
>
{% trans "Size" %}
</label>
<ul
class=
"radio"
>
{% for s in sizes %}
<li>
<input
type=
"radio"
name=
"size"
value=
"small"
id=
"new-template-size-small"
/>
<label
for=
"new-template-size-small"
>
Kicsi
</label>
</li>
<li>
<input
type=
"radio"
name=
"size"
value=
"medium"
id=
"new-template-size-medium"
/>
<label
for=
"new-template-size-medium"
>
Közepes
</label>
</li>
<li>
<input
type=
"radio"
name=
"size"
value=
"large"
id=
"new-template-size-large"
/>
<label
for=
"new-template-size-large"
>
Nagy
</label>
<label>
<input
type=
"radio"
name=
"size"
value=
"{{s.id}}"
id=
"new-template-size-{{s.id}}"
{%
if
s =
=
base
.
instance_type
%}
checked=
"checked"
{%
endif
%}
/>
{{s.name}}
</label>
</li>
{% endfor %}
</ul>
{% for s in sizes %}
<p
id=
"new-template-size-summary-{{s.id}}"
class=
"size-summary clear"
{%
if
s
!=
base
.
instance_type
%}
style=
"display:none"
{%
endif
%}
>
<span
class=
"cpu"
>
{% blocktrans count n=s.CPU %}{{n}} core{% plural %}{{n}} cores{% endblocktrans %}
</span>
<span
class=
"memory"
>
{{s.RAM}} MiB
</span>
<span
class=
"credit"
>
{{s.credit}}
</span>
</p>
{% endfor %}
<div
class=
"clear"
></div>
</li>
<li
style=
"border: none"
>
<label
for=
"new-template-description"
>
{% trans "Description" %}
</label>
<textarea
name=
"description"
id=
"new-template-description"
placeholder=
"{% trans "
Comments
about
the
template
"
%}"
>
</textarea>
<textarea
name=
"description"
id=
"new-template-description"
style=
"text-align: left"
>
{{base.description}}
</textarea>
<div
class=
"clear"
></div>
</li>
</ul>
<nav>
<a
href=
"#"
class=
"prev"
>
{% trans "
«
Cancel" %}
</a>
<
a
href=
"#"
class=
"next"
>
{% trans "Next
»
" %}
</a
>
<
input
type=
"submit"
value=
"{% trans "
Launch
"
%}"
/
>
<div
class=
"clear"
></div>
</nav>
<script
type=
"text/javascript"
>
$
(
function
(){
$
(
'#new-template-step-1 nav .next'
).
click
(
function
(){
$
(
'#new-template-step-1'
).
hide
();
$
(
'#new-template-step-2'
).
show
();
})
$
(
'#new-template-step-1 nav .prev'
).
click
(
function
(){
$
(
'#new-template-step-2 nav .prev'
).
click
(
function
(){
$
(
'#modal'
).
hide
();
})
$
(
".new-tpl-size input[name='size']"
).
click
(
function
(
e
){
var
v
=
$
(
".new-tpl-size input[name='size']:checked"
).
val
();
$
(
"p.size-summary"
).
hide
();
$
(
"#new-template-size-summary-"
+
v
).
show
();
});
$
(
"#new-template-name"
).
change
(
function
(
e
){
var
s
=
$
(
this
).
val
();
$
.
ajax
({
'type'
:
'GET'
,
'url'
:
'/ajax/template_name_unique/'
+
s
,
'success'
:
function
(
data
,
b
,
c
)
{
if
(
s
!=
$
(
"#new-template-name"
).
val
())
{
return
True
;
}
if
(
data
==
"True"
)
{
$
(
'#new-template-name'
).
removeClass
(
"error"
);
}
else
{
$
(
'#new-template-name'
).
addClass
(
"error"
);
}
}
});
});
})
</script>
</div>
<div
id=
"new-template-step-3"
class=
"wizard"
style=
"display: none"
>
</div>
</form>
one/templates/show.html
View file @
6efe1ef5
...
...
@@ -21,6 +21,29 @@
{% endblock %}
{% block content %}
{% if i.template.state != "READY" %}
<div
class=
"contentblock wide note big"
>
<p>
{% blocktrans %}This is a master image for your new template.{% endblocktrans %}
</p>
<form
action=
"{% url one.views.vm_saveas id %}"
method=
"POST"
>
{% csrf_token %}
{% if i.template.state == "NEW" %}
<p
style=
"float: right; margin-top:2em;margin-right:1em;"
>
<input
type=
"submit"
value=
"{% trans "
Save
"
%}"
class=
"big"
style=
"background-color:rgba(102, 255, 0, 0.4)"
/>
</p>
{% endif %}
</form>
<ol>
<li
{%
if
i
.
template
.
state =
=
"
SAVING
"
%}
class=
"done"
{%
endif
%}
>
{% blocktrans %}Connect to the machine.{% endblocktrans %}
</li>
<li
{%
if
i
.
template
.
state =
=
"
SAVING
"
%}
class=
"done"
{%
endif
%}
>
{% blocktrans %}Do all the needed installation/customization.{% endblocktrans %}
</li>
<li
{%
if
i
.
template
.
state =
=
"
SAVING
"
%}
class=
"done"
{%
endif
%}
>
{% blocktrans %}Log off (keep the machine running).{% endblocktrans %}
</li>
<li
{%
if
i
.
template
.
state =
=
"
SAVING
"
%}
class=
"done"
{%
endif
%}
>
{% blocktrans %}Click on the "save" button on the right.{% endblocktrans %}
</li>
<li>
{% blocktrans %}The machine will be shut down and its disk saved.{% endblocktrans %}
</li>
<li>
{% blocktrans %}You can share the template with your groups.{% endblocktrans %}
</li>
</ol>
</div>
{% endif %}
<div
class=
"boxes"
>
<div
class=
"contentblock"
id=
"state"
>
<h2>
{{name}}
</h2>
...
...
one/views.py
View file @
6efe1ef5
...
...
@@ -10,7 +10,6 @@ from django.core.mail import mail_managers, send_mail
from
django.db
import
transaction
from
django.forms
import
ModelForm
,
Textarea
from
django.http
import
Http404
#from django_shibboleth.forms import BaseRegisterForm
from
django.shortcuts
import
render
,
render_to_response
,
get_object_or_404
,
redirect
from
django.template
import
RequestContext
from
django.template.loader
import
render_to_string
...
...
@@ -19,11 +18,14 @@ from django.utils.translation import get_language as lang
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.views.decorators.http
import
*
from
django.views.generic
import
*
from
firewall.tasks
import
*
from
one.models
import
*
from
school.models
import
*
import
django.contrib.auth
as
auth
from
firewall.tasks
import
*
import
json
import
logging
logger
=
logging
.
getLogger
(
__name__
)
class
LoginView
(
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
...
...
@@ -32,12 +34,12 @@ class LoginView(View):
nex
=
request
.
GET
[
'next'
]
except
:
pass
return
render_to_response
(
"login.html"
,
RequestContext
(
request
,{
'next'
:
nex
}))
return
render_to_response
(
"login.html"
,
RequestContext
(
request
,
{
'next'
:
nex
}))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
if
request
.
POST
[
'pw'
]
!=
'ezmiez'
:
return
redirect
(
'/'
)
p
,
created
=
User
.
objects
.
get_or_create
(
username
=
request
.
POST
[
'neptun'
])
if
created
:
if
created
:
p
.
set_unusable_password
()
if
not
p
.
email
:
p
.
email
=
"
%
s@nc.hszk.bme.hu"
%
p
.
username
...
...
@@ -70,29 +72,66 @@ def _list_instances(request):
@require_GET
@login_required
def
home
(
request
):
return
render_to_response
(
"home.html"
,
RequestContext
(
request
,{
'templates'
:
Template
.
objects
.
all
(),
return
render_to_response
(
"home.html"
,
RequestContext
(
request
,
{
'templates'
:
Template
.
objects
.
filter
(
state
=
'READY'
),
'mytemplates'
:
Template
.
objects
.
filter
(
owner
=
request
.
user
),
'instances'
:
_list_instances
(
request
),
'groups'
:
request
.
user
.
person_set
.
all
()[
0
]
.
owned_groups
.
all
(),
'semesters'
:
Semester
.
objects
.
all
()
}))
@require_GET
def
ajax_template_name_unique
(
request
,
name
):
s
=
"True"
if
Template
.
objects
.
filter
(
name
=
name
)
.
exists
():
s
=
"False"
return
HttpResponse
(
s
)
class
AjaxTemplateWizard
(
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
return
render_to_response
(
'new-template-flow-1.html'
,
RequestContext
(
request
,{
'templates'
:
Template
.
objects
.
filter
(
public
=
True
)
# + Template.objects.filter(owner=request.user),
}))
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
base
=
get_object_or_404
(
Template
,
id
=
request
.
POST
[
'base'
])
if
base
.
owner
!=
request
.
user
and
not
base
.
public
and
not
request
.
user
.
is_superuser
:
raise
PermissionDenied
()
return
render_to_response
(
'new-template-flow.html'
,
RequestContext
(
request
,
{
'sizes'
:
InstanceType
.
objects
.
all
(),
'base'
:
base
,
}))
ajax_template_wizard
=
login_required
(
AjaxTemplateWizard
.
as_view
())
@require_POST
@login_required
def
ajax_template_wizard
(
request
):
return
render_to_response
(
'new-template-flow.html'
,
RequestContext
(
request
,{
'templates'
:
Template
.
objects
.
all
(),
}))
def
vm_saveas
(
request
,
vmid
):
inst
=
get_object_or_404
(
Instance
,
pk
=
vmid
)
if
inst
.
owner
!=
request
.
user
and
not
request
.
user
.
is_superuser
:
raise
PermissionDenied
()
inst
.
save_as
()
messages
.
success
(
request
,
_
(
"Template is being saved..."
))
return
redirect
(
inst
)
@require_POST
@login_required
def
vm_new
(
request
,
template
):
m
=
get_object_or_404
(
Template
,
pk
=
template
)
base
=
get_object_or_404
(
Template
,
pk
=
template
)
if
"name"
in
request
.
POST
:
if
base
.
owner
!=
request
.
user
and
not
base
.
public
and
not
request
.
user
.
is_superuser
:
raise
PermissionDenied
()
name
=
request
.
POST
[
'name'
]
t
=
Template
.
objects
.
create
(
name
=
name
,
disk
=
base
.
disk
,
instance_type_id
=
request
.
POST
[
'size'
],
network
=
base
.
network
,
owner
=
request
.
user
)
t
.
access_type
=
base
.
access_type
t
.
description
=
request
.
POST
[
'description'
]
t
.
system
=
base
.
system
t
.
save
()
base
=
t
try
:
i
=
Instance
.
submit
(
m
,
request
.
user
)
i
=
Instance
.
submit
(
base
,
request
.
user
,
extra
=
"<RECONTEXT>YES</RECONTEXT>"
)
return
redirect
(
i
)
except
:
raise
except
Exception
as
e
:
logger
.
error
(
'Failed to create virtual machine.'
+
unicode
(
e
))
messages
.
error
(
request
,
_
(
'Failed to create virtual machine.'
))
return
redirect
(
'/'
)
...
...
@@ -111,6 +150,8 @@ vm_list = login_required(VmListView.as_view())
def
vm_show
(
request
,
iid
):
inst
=
get_object_or_404
(
Instance
,
id
=
iid
,
owner
=
request
.
user
)
inst
.
update_state
()
if
inst
.
template
.
state
==
"SAVING"
:
inst
.
check_if_is_save_as_done
()
return
render_to_response
(
"show.html"
,
RequestContext
(
request
,{
'uri'
:
inst
.
get_connect_uri
(),
'state'
:
inst
.
state
,
...
...
@@ -188,7 +229,7 @@ class VmDeleteView(View):
def
get
(
self
,
request
,
iid
,
*
args
,
**
kwargs
):
i
=
get_object_or_404
(
Instance
,
id
=
iid
,
owner
=
request
.
user
)
return
render_to_response
(
"confirm_delete.html"
,
RequestContext
(
request
,{
return
render_to_response
(
"confirm_delete.html"
,
RequestContext
(
request
,
{
'i'
:
i
}))
vm_delete
=
login_required
(
VmDeleteView
.
as_view
())
...
...
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