Merge branch 'master' of ssh://git.planet-lab.org/git/plstackapi
diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py
index 66e26eb..3ddf871 100644
--- a/planetstack/core/admin.py
+++ b/planetstack/core/admin.py
@@ -266,7 +266,7 @@
class SliverInline(PlStackTabularInline):
model = Sliver
- fields = ['backend_status_icon', 'all_ips_string', 'instance_name', 'slice', 'numberCores', 'deploymentNetwork', 'image', 'node']
+ fields = ['backend_status_icon', 'all_ips_string', 'instance_name', 'slice', 'deploymentNetwork', 'flavor', 'image', 'node']
extra = 0
readonly_fields = ['backend_status_icon', 'all_ips_string', 'instance_name']
suit_classes = 'suit-tab suit-tab-slivers'
@@ -277,13 +277,7 @@
def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
if db_field.name == 'deploymentNetwork':
kwargs['queryset'] = Deployment.select_by_acl(request.user)
- # the inscrutable jquery selector below says:
- # find the closest parent "tr" to the current element
- # then find the child with class "field-node"
- # then find the child with that is a select
- # then return its id
- kwargs['widget'] = forms.Select(attrs={'onChange': "update_nodes(this, $($(this).closest('tr')[0]).find('.field-node select')[0].id)"})
- #kwargs['widget'] = forms.Select(attrs={'onChange': "console.log($($($(this).closest('tr')[0]).children('.field-node')[0]).children('select')[0].id);"})
+ kwargs['widget'] = forms.Select(attrs={'onChange': "sliver_deployment_changed(this);"})
field = super(SliverInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
@@ -759,21 +753,28 @@
)
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
- #deployment_nodes = {}
- #for node in Node.objects.all():
- # deployment_nodes[node.deployment.id] = get(deployment_nodes, node.deployment.id, []).append( (node.id, node.name) )
-
deployment_nodes = []
for node in Node.objects.all():
deployment_nodes.append( (node.deployment.id, node.id, node.name) )
- context["deployment_nodes"] = deployment_nodes
+ deployment_flavors = []
+ for flavor in Flavor.objects.all():
+ for deployment in flavor.deployments.all():
+ deployment_flavors.append( (deployment.id, flavor.id, flavor.name) )
+ site_login_bases = []
+ for site in Site.objects.all():
+ site_login_bases.append((site.id, site.login_base))
+
+ context["deployment_nodes"] = deployment_nodes
+ context["deployment_flavors"] = deployment_flavors
+ context["site_login_bases"] = site_login_bases
return super(SliceAdmin, self).render_change_form(request, context, add, change, form_url, obj)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'site':
kwargs['queryset'] = Site.select_by_user(request.user)
+ kwargs['widget'] = forms.Select(attrs={'onChange': "update_slice_prefix(this, $($(this).closest('fieldset')[0]).find('.field-name input')[0].id)"})
return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
@@ -894,10 +895,10 @@
class SliverAdmin(PlanetStackBaseAdmin):
form = SliverForm
fieldsets = [
- ('Sliver Details', {'fields': ['backend_status_text', 'slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
+ ('Sliver Details', {'fields': ['backend_status_text', 'slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'flavor', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
]
readonly_fields = ('backend_status_text', )
- list_display = ['backend_status_icon', 'ip', 'instance_name', 'slice', 'numberCores', 'image', 'node', 'deploymentNetwork']
+ list_display = ['backend_status_icon', 'ip', 'instance_name', 'slice', 'flavor', 'image', 'node', 'deploymentNetwork']
list_display_links = ('backend_status_icon', 'ip',)
suit_form_tabs =(('general', 'Sliver Details'),
@@ -906,7 +907,7 @@
inlines = [TagInline]
- user_readonly_fields = ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'numberCores', 'image']
+ user_readonly_fields = ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'flavor', 'image']
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'slice':
diff --git a/planetstack/core/dashboard/views/view_common.py b/planetstack/core/dashboard/views/view_common.py
index 7a42f2f..7d51435 100644
--- a/planetstack/core/dashboard/views/view_common.py
+++ b/planetstack/core/dashboard/views/view_common.py
@@ -68,7 +68,7 @@
for sliver in slice.slivers.all():
#sites_used['deploymentSites'] = sliver.node.deployment.name
# sites_used[sliver.image.name] = sliver.image.name
- sites_used[sliver.node.site.name] = sliver.numberCores
+ sites_used[sliver.node.site.name] = 1 #sliver.numberCores
sliceid = Slice.objects.get(id=entry.slice.id).id
try:
sliverList = Sliver.objects.filter(slice=entry.slice.id)
@@ -204,8 +204,7 @@
node=node,
image = image,
creator = User.objects.get(email=user),
- deploymentNetwork=node.deployment,
- numberCores =1 )
+ deploymentNetwork=node.deployment)
sliver.save()
node.sliverCount = node.sliverCount + 1
diff --git a/planetstack/core/fixtures/demo_data.json b/planetstack/core/fixtures/demo_data.json
index 4ae8ea5..400148f 100644
--- a/planetstack/core/fixtures/demo_data.json
+++ b/planetstack/core/fixtures/demo_data.json
@@ -9603,6 +9603,187 @@
}
},
{
+ "pk": 1,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-02T20:38:23.122Z",
+ "name": "m1.tiny",
+ "created": "2014-09-02T20:38:23.122Z",
+ "deleted": false,
+ "description": "openstack tiny instance",
+ "deployments": [
+ 7,
+ 10,
+ 9,
+ 8,
+ 6,
+ 5
+ ],
+ "default": false,
+ "flavor": "m1.tiny",
+ "backend_status": "Provisioning in progress",
+ "order": 0,
+ "enacted": null
+ }
+},
+{
+ "pk": 2,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-02T20:59:40.518Z",
+ "name": "m1.small",
+ "created": "2014-09-02T20:59:40.518Z",
+ "deleted": false,
+ "description": "small openstack instance",
+ "deployments": [
+ 7,
+ 10,
+ 9,
+ 8,
+ 6,
+ 5,
+ 11
+ ],
+ "default": true,
+ "flavor": "m1.small",
+ "backend_status": "Provisioning in progress",
+ "order": 1,
+ "enacted": null
+ }
+},
+{
+ "pk": 3,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-02T21:00:28.795Z",
+ "name": "m1.medium",
+ "created": "2014-09-02T21:00:28.795Z",
+ "deleted": false,
+ "description": "medium openstack flavor",
+ "deployments": [
+ 7,
+ 10,
+ 9,
+ 8,
+ 6,
+ 5,
+ 11
+ ],
+ "default": false,
+ "flavor": "m1.medium",
+ "backend_status": "Provisioning in progress",
+ "order": 2,
+ "enacted": null
+ }
+},
+{
+ "pk": 4,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-02T21:00:57.360Z",
+ "name": "m1.large",
+ "created": "2014-09-02T21:00:49.945Z",
+ "deleted": false,
+ "description": "large openstack flavor",
+ "deployments": [
+ 7,
+ 10,
+ 9,
+ 8,
+ 6,
+ 5,
+ 11
+ ],
+ "default": false,
+ "flavor": "m1.large",
+ "backend_status": "Provisioning in progress",
+ "order": 3,
+ "enacted": null
+ }
+},
+{
+ "pk": 5,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-02T21:01:15.285Z",
+ "name": "m1.xlarge",
+ "created": "2014-09-02T21:01:15.285Z",
+ "deleted": false,
+ "description": "extra large openstack flavor",
+ "deployments": [
+ 7,
+ 10,
+ 9,
+ 8,
+ 6,
+ 5,
+ 11
+ ],
+ "default": false,
+ "flavor": "m1.xlarge",
+ "backend_status": "Provisioning in progress",
+ "order": 4,
+ "enacted": null
+ }
+},
+{
+ "pk": 6,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-03T00:25:30.120Z",
+ "name": "m3.medium",
+ "created": "2014-09-03T00:25:30.120Z",
+ "deleted": false,
+ "description": "ec2 flavor m3.medium",
+ "deployments": [
+ 11
+ ],
+ "default": false,
+ "flavor": "m3.medium",
+ "backend_status": "Provisioning in progress",
+ "order": 33,
+ "enacted": null
+ }
+},
+{
+ "pk": 7,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-03T00:25:50.419Z",
+ "name": "m3.large",
+ "created": "2014-09-03T00:25:50.419Z",
+ "deleted": false,
+ "description": "ec2 flavor m3.large",
+ "deployments": [
+ 11
+ ],
+ "default": false,
+ "flavor": "m3.large",
+ "backend_status": "Provisioning in progress",
+ "order": 34,
+ "enacted": null
+ }
+},
+{
+ "pk": 8,
+ "model": "core.flavor",
+ "fields": {
+ "updated": "2014-09-03T00:26:11.770Z",
+ "name": "m3.2xlarge",
+ "created": "2014-09-03T00:26:11.770Z",
+ "deleted": false,
+ "description": "ec2 flavor m3.2xlarge",
+ "deployments": [
+ 11
+ ],
+ "default": false,
+ "flavor": "m3.2xlarge",
+ "backend_status": "Provisioning in progress",
+ "order": 35,
+ "enacted": null
+ }
+},
+{
"pk": 40,
"model": "core.sliver",
"fields": {
diff --git a/planetstack/core/models/__init__.py b/planetstack/core/models/__init__.py
index 40d9f29..5a4798f 100644
--- a/planetstack/core/models/__init__.py
+++ b/planetstack/core/models/__init__.py
@@ -23,10 +23,10 @@
from .planetstack import PlanetStackRole
from .planetstack import PlanetStackPrivilege
from .slicetag import SliceTag
+from .flavor import Flavor
from .sliver import Sliver
from .reservation import ReservedResource
from .reservation import Reservation
from .network import Network, NetworkParameterType, NetworkParameter, NetworkSliver, NetworkTemplate, Router, NetworkSlice, NetworkDeployments
-from .flavor import Flavor
from .billing import Account, Invoice, Charge, UsableObject, Payment
diff --git a/planetstack/core/models/flavor.py b/planetstack/core/models/flavor.py
index 0cc14f0..84a5427 100644
--- a/planetstack/core/models/flavor.py
+++ b/planetstack/core/models/flavor.py
@@ -1,7 +1,7 @@
import os
import socket
from django.db import models
-from core.models import PlCoreBase, Site, Slice, Sliver, Deployment
+from core.models import PlCoreBase, Deployment
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
diff --git a/planetstack/core/models/sliver.py b/planetstack/core/models/sliver.py
index e0ce5e2..ec7f266 100644
--- a/planetstack/core/models/sliver.py
+++ b/planetstack/core/models/sliver.py
@@ -9,11 +9,31 @@
from core.models import Deployment
from core.models import User
from core.models import Tag
+from core.models import Flavor
from django.contrib.contenttypes import generic
+def get_default_flavor(deployment = None):
+ # Find a default flavor that can be used for a sliver. This is particularly
+ # useful in evolution. It's also intended this helper function can be used
+ # for admin.py when users
+
+ if deployment:
+ flavors = deployment.flavors.all()
+ else:
+ flavors = Flavor.objects.all()
+
+ if not flavors:
+ return None
+
+ for flavor in flavors:
+ if flavor.default:
+ return flavor
+
+ return flavors[0]
+
# Create your models here.
class Sliver(PlCoreBase):
- instance_id = models.CharField(null=True, blank=True, max_length=200, help_text="Nova instance id")
+ instance_id = models.CharField(null=True, blank=True, max_length=200, help_text="Nova instance id")
name = models.CharField(max_length=200, help_text="Sliver name")
instance_name = models.CharField(blank=True, null=True, max_length=200, help_text="OpenStack generated name")
ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True)
@@ -24,6 +44,7 @@
node = models.ForeignKey(Node, related_name='slivers')
deploymentNetwork = models.ForeignKey(Deployment, verbose_name='deployment', related_name='sliver_deploymentNetwork')
numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=0)
+ flavor = models.ForeignKey(Flavor, help_text="Flavor of this instance", default=get_default_flavor)
tags = generic.GenericRelation(Tag)
userData = models.TextField(blank=True, null=True, help_text="user_data passed to instance during creation")
diff --git a/planetstack/templates/admin/core/slice/change_form.html b/planetstack/templates/admin/core/slice/change_form.html
index e97364b..1084004 100644
--- a/planetstack/templates/admin/core/slice/change_form.html
+++ b/planetstack/templates/admin/core/slice/change_form.html
@@ -1,5 +1,5 @@
{% extends 'admin/change_form.html' %}
-{% block extrahead %}
+{% block extrahead %}
{{ block.super }}
<script>
deployment_nodes = [
@@ -8,12 +8,17 @@
{% endfor %}
];
-sites = [
-{% for s in sites %}
- [{{ s.0 }}, {{ s.1 }}],
+deployment_flavors = [
+{% for dn in deployment_flavors %}
+ [{{ dn.0 }}, {{ dn.1 }} , "{{ dn.2 }}"],
{% endfor %}
];
-
+
+site_login_bases = [
+{% for s in site_login_bases %}
+ [{{ s.0 }}, "{{ s.1 }}"],
+{% endfor %}
+];
function update_nodes(deployment_select, node_select_id) {
deployment_id = $(deployment_select).val();
@@ -28,11 +33,39 @@
$("#"+node_select_id).empty().append(html);
}
+function update_flavors(deployment_select, flavor_select_id) {
+ deployment_id = $(deployment_select).val();
+ html = "<option value=''>---------</option>\n";
+ for (i in deployment_flavors) {
+ dn = deployment_flavors[i];
+ if (dn[0] == deployment_id) {
+ html = html + '<option value="' + dn[1] + '">' + dn[2] + '</option>\n'
+ }
+ }
+ //console.log(html);
+ $("#"+flavor_select_id).empty().append(html);
+}
+
+function sliver_deployment_changed(deployment_select) {
+ /* the inscrutable jquery selector below says:
+ find the closest parent "tr" to the current element
+ then find the child with class "field-node"
+ then find the child with that is a select
+ then return its id
+ */
+ nodes_select_id = $($(deployment_select).closest('tr')[0]).find('.field-node select')[0].id;
+ update_nodes(deployment_select, nodes_select_id);
+ flavors_select_id = $($(deployment_select).closest('tr')[0]).find('.field-flavor select')[0].id;
+ update_flavors(deployment_select, flavors_select_id);
+}
+
function update_slice_prefix(site_select, slice_name_id) {
site_id = $(site_select).val();
slice_prefix="";
- if (site_id in sites) {
- slice_prefix=sites[site_id]+"_";
+ for (i in site_login_bases) {
+ if (site_login_bases[i][0] == site_id) {
+ slice_prefix=site_login_bases[i][1]+"_";
+ }
}
$("#"+slice_name_id).val(slice_prefix);
}