#增加按钮功能【例如增加增量功能】
vim /opt/horizon-2012.1/horizon/dashboards/nova/instances_and_volumes/instances/tables.py
class SnapshotLink(tables.LinkAction): #创建快照功能,快照流程分析
name = "snapshot"
verbose_name = _("Snapshot")
url = "horizon:nova:images_and_snapshots:snapshots:create" #连接目录如下:
classes = ("ajax-modal", "btn-camera")
def allowed(self, request, instance=None):
return instance.status in ACTIVE_STATES
说明:
vim /opt/horizon-2012.1/horizon/dashboards/nova/images_and_snapshots/snapshots/url.py
#
from django.conf.urls.defaults import patterns, url
from .views import CreateView
urlpatterns = patterns('',
url(r'^(?P[^/]+)/create',
CreateView.as_view(),
name='create')
####
vim /opt/horizon-2012.1/horizon/dashboards/nova/images_and_snapshots/snapshots/views.py
class CreateView(forms.ModalFormView): #vim /opt/horizon-2012.1/horizon/forms/views.py
form_class = CreateSnapshot
template_name = 'nova/images_and_snapshots/snapshots/create.html'
def get_initial(self):
redirect = reverse('horizon:nova:instances_and_volumes:index')
instance_id = self.kwargs["instance_id"]
try:
self.instance = api.server_get(self.request, instance_id)
except:
self.instance = None
msg = _("Unable to retrieve instance.")
exceptions.handle(self.request, msg, redirect)
if self.instance.status != api.nova.INSTANCE_ACTIVE_STATE:
msg = _('To create a snapshot, the instance must be in '
'the "%s" state.') % api.nova.INSTANCE_ACTIVE_STATE
raise exceptions.Http302(redirect, message=msg)
return {"instance_id": instance_id,
"tenant_id": self.request.user.tenant_id}
def get_context_data(self, **kwargs):
context = super(CreateView, self).get_context_data(**kwargs)
context['instance'] = self.instance
return context
#修改实例:单击Snapshot按钮后出现的对话框如下:
name = forms.CharField(max_length="20", label=_("shot Name")) #修改前
#name = forms.CharField(max_length="20", label=_("Snapshot Name")) #修改后
修改完毕,重启apache
vim /opt/horizon-2012.1/horizon/forms/views.py
import os
from django import http
from django.views import generic
## cd /usr/lib/python2.6/site-packages/django/views/generic
class ModalFormView(generic.TemplateView):
vim /usr/lib/python2.6/site-packages/django/views/generic/base.py #
class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
"""
http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
def __init__(self, **kwargs):
"""
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in kwargs.iteritems():
setattr(self, key, value)
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
# sanitize keyword arguments
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError(u"You tried to pass in the %s method name as a "
u"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError(u"%s() received an invalid keyword %r" % (
cls.__name__, key))
def view(request, *args, **kwargs):
self = cls(**initkwargs)
return self.dispatch(request, *args, **kwargs)
# take name and docstring from class
update_wrapper(view, cls, updated=())
# and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
self.request = request
self.args = args
self.kwargs = kwargs
return handler(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
allowed_methods = [m for m in self.http_method_names if hasattr(self, m)]
logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path),
extra={
'status_code': 405,
'request': self.request
}
)
return http.HttpResponseNotAllowed(allowed_methods)
class TemplateResponseMixin(object):
"""
A mixin that can be used to render a template.
"""
template_name = None
response_class = TemplateResponse
def render_to_response(self, context, **response_kwargs):
"""
Returns a response with a template rendered with the given context.
"""
return self.response_class(
request = self.request,
template = self.get_template_names(),
context = context,
**response_kwargs
)
def get_template_names(self):
"""
Returns a list of template names to be used for the request. Must return
a list. May not be called if render_to_response is overridden.
"""
if self.template_name is None:
raise ImproperlyConfigured(
"TemplateResponseMixin requires either a definition of "
"'template_name' or an implementation of 'get_template_names()'")
else:
return [self.template_name]
class TemplateView(TemplateResponseMixin, View): #表示有两个父类
"""
A view that renders a template.
"""
def get_context_data(self, **kwargs):
return {
'params': kwargs
}
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
#add by xk=新增项==============================================#
class IncreaseLink(tables.LinkAction):
name = "increase"
verbose_name = _("Increase")
url = "horizon:nova:images_and_snapshots:snapshots:create"
classes = ("ajax-modal", "btn-camera")
#def allowed(self, request, instance=None):
# retturn instance.status in ACTIVE_STATES
#============================================================#
Add 虚拟机创建规则功能和主机选择功能
vim /opt/horizon-2012.1/horizon/dashboards/nova/images_and_snapshots/images/forms.py +175
class LaunchForm(forms.SelfHandlingForm):
name = forms.CharField(max_length=80, label=_("Server Name"))
image_id = forms.CharField(widget=forms.HiddenInput())
tenant_id = forms.CharField(widget=forms.HiddenInput())
user_data = forms.CharField(widget=forms.Textarea,
label=_("User Data"),
required=False)
flavor = forms.ChoiceField(label=_("Flavor"),
help_text=_("Size of image to launch."))
#add by xk 2012-12-27
rouler = forms.ChoiceField(label=_("rouler"),
help_text=_("Rouler of image to create."))
#-------------------#
..
..
api.server_create(request,
data['name'],
data['image_id'],
data['flavor'],
#add by xk 2012-12-27
data['rouler'],
#--------------------#
meta,
data.get('keypair'),
normalize_newlines(data.get('user_data')),
data.get('security_groups'),
dev_mapping,
instance_count=data.get('count'))
messages.success(request,
_('Instance "%s" launched.') % data["name"])
重启apache #效果如下
#=======launch按钮涉及的页面====================================#
vim /opt/horizon-2012.1/horizon/dashboards/nova/templates/nova/images_and_snapshots/images/_launch.html
vim /opt/horizon-2012.1/horizon/templates/horizon/common/_form_fields.html
Managers interact with a particular type of API (servers, flavors, images,
etc.) and provide CRUD operations for them.
《开源人》