在Dashborad 上添加将Volume 备份到指定的Container 功能
在命令行下是可以通过cinder backup-create 来指定将volume 备份到不同的container 中,但是dashborad 并没有提供页面操作。
一、页面修改
进入/project/vouleme/volume/tables.py 页面添加 backup 按钮
class CreateBackup(tables.LinkAction):
name = "backup"
verbose_name = _("Create Backup")
url = "horizon:project:volumes:volumes:create_backup"
classes = ("ajax-modal","btn-camera")
policy_rules = (("volume","volume:backup"),)
def get_policy_target(self, request, datum=None):
project_id = None
if datum:
project_id = getattr(datum,"os-vol-tenant-attr:tenant_id",None)
return {"project_id":project_id}
def allowed(self, request, volume=None):
return volume.status in "available","in-use"
在viwe.py页面添加类
class CreateBackupView(forms.ModalFormView):
form_class = project_forms.CreateBackupForm
template_name = 'project/volumes/volumes/create_backup.html'
success_url = reverse_lazy("horizon:project:containers:index")
def get_context_data(self, **kwargs):
context = super(CreateBackupView, self).get_context_data(**kwargs)
context['volume_id'] = self.kwargs['volume_id']
try:
volume = cinder.volume_get(self.request, context['volume_id'])
if (volume.status == 'in-use'):
context['attached'] = True
context['form'].set_warning(_("This volume is currently "
"attached to an instance. "
"In some cases, creating a "
"backup from an attached "
"volume can result in a "
"corrupted backup."))
context['usages'] = quotas.tenant_limit_usages(self.request)
except Exception:
exceptions.handle(self.request,
_('Unable to retrieve volume information.'))
return context
def get_initial(self):
return {'volume_id': self.kwargs["volume_id"]}
在form.py页面添加
<pre name="code" class="python">class CreateBackupForm(forms.SelfHandlingForm):
name = forms.CharField(max_length="255", label =_("Backup Name"))
container_list = forms.ChoiceField(label=_("Backup to container"),
help_text=_("Select a container to "
"backup to."))
description = forms.CharField(widget=forms.Textarea,
label=_("Description"),required=False)
def __init__(self, request, *args, **kwargs):
super(CreateBackupForm, self).__init__(request, *args, **kwargs)
# populate volume_id
volume_id = kwargs.get('initial', {}).get('volume_id', [])
self.fields['volume_id'] = forms.CharField(widget=forms.HiddenInput(),
initial=volume_id)
#def populate_avialable_container_choices(self,request,context):
try:
containers = swift.swift_get_containers(request)[0]
except Exception:
containers = []
exceptions.handle(request,
_('Unable to retrive available container.'))
container_list = []
container_list = [(container.get('name'), container.get('name'))
for container in containers ]
container_list.sort()
if not container_list:
container_list.insert(0,("",_("No available container.")))
elif len(container_list) > 1:
container_list.insert(0,("",_("Any Available Container")))
self.fields['container_list'].choices = container_list
def handle(self, request, data):
try:
volume = cinder.volume_get(request,
data['volume_id'])
force = False
message = _('Creating volume backup "%s".') % data['name']
if volume.status == 'in-use':
force = True
message = _('Forcing to create backup "%s" '
'from attached volume.') % data['name']
backup = cinder.volume_backup_create(request,
data['volume_id'],
data['name'],
data['container_list'],
data['description'])
#end add
messages.info(request, message)
return backup
except Exception:
redirect = reverse("horizon:project:volumes:index")
exceptions.handle(request,
_('Unable to create volume backup.'),
redirect=redirect)
二、cinder api 的修改
因为 cinderclient 已经集成了常用的功能,我们只需要调用api即可
<pre name="code" class="python">def volume_backup_create(request,volume_id,
name=None,container=None,description=None):
data = {'name': name,
'container': container,
'description': description}
return VolumeBackup(cinderclient(request).backups.create(
volume_id, **data))