Merge "volume-backup add incremental flag"
This commit is contained in:
commit
34b2e82343
@ -585,8 +585,9 @@ def volume_backup_get(request, backup_id):
|
||||
return VolumeBackup(backup)
|
||||
|
||||
|
||||
def volume_backup_list(request):
|
||||
backups, _, __ = volume_backup_list_paged(request, paginate=False)
|
||||
def volume_backup_list(request, search_opts=None):
|
||||
backups, _, __ = volume_backup_list_paged(request, paginate=False,
|
||||
search_opts=search_opts)
|
||||
return backups
|
||||
|
||||
|
||||
@ -625,7 +626,7 @@ def volume_backup_list_paged_with_page_menu(request, page_number=1,
|
||||
|
||||
@profiler.trace
|
||||
def volume_backup_list_paged(request, marker=None, paginate=False,
|
||||
sort_dir="desc"):
|
||||
sort_dir="desc", search_opts=None):
|
||||
has_more_data = False
|
||||
has_prev_data = False
|
||||
backups = []
|
||||
@ -642,13 +643,13 @@ def volume_backup_list_paged(request, marker=None, paginate=False,
|
||||
sort = 'created_at:' + sort_dir
|
||||
for b in c_client.backups.list(limit=page_size + 1,
|
||||
marker=marker,
|
||||
sort=sort):
|
||||
sort=sort, search_opts=search_opts):
|
||||
backups.append(VolumeBackup(b))
|
||||
|
||||
backups, has_more_data, has_prev_data = update_pagination(
|
||||
backups, page_size, marker, sort_dir)
|
||||
else:
|
||||
for b in c_client.backups.list():
|
||||
for b in c_client.backups.list(search_opts=search_opts):
|
||||
backups.append(VolumeBackup(b))
|
||||
|
||||
return backups, has_more_data, has_prev_data
|
||||
@ -661,6 +662,7 @@ def volume_backup_create(request,
|
||||
name,
|
||||
description,
|
||||
force=False,
|
||||
incremental=False,
|
||||
snapshot_id=None):
|
||||
# need to ensure the container name is not an empty
|
||||
# string, but pass None to get the container name
|
||||
@ -671,6 +673,7 @@ def volume_backup_create(request,
|
||||
name=name,
|
||||
description=description,
|
||||
snapshot_id=snapshot_id,
|
||||
incremental=incremental,
|
||||
force=force)
|
||||
return VolumeBackup(backup)
|
||||
|
||||
|
@ -42,9 +42,30 @@ class CreateBackupForm(forms.SelfHandlingForm):
|
||||
volume_id = forms.CharField(widget=forms.HiddenInput())
|
||||
snapshot_id = forms.ThemableChoiceField(label=_("Backup Snapshot"),
|
||||
required=False)
|
||||
incremental = forms.BooleanField(
|
||||
label=_("Incremental"),
|
||||
required=False,
|
||||
help_text=_("By default, a backup is created as a full backup. "
|
||||
"Check this to do an incremental backup from latest "
|
||||
"backup. Only available if a prior backup exists."))
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super().__init__(request, *args, **kwargs)
|
||||
search_opts = {"volume_id": kwargs['initial']['volume_id'],
|
||||
"status": "available"}
|
||||
try:
|
||||
if not api.cinder.volume_backup_list(request,
|
||||
search_opts=search_opts):
|
||||
self.fields.pop('incremental')
|
||||
except Exception:
|
||||
# Do not include incremental if list of prior backups fails
|
||||
self.fields.pop('incremental')
|
||||
msg = _('Unable to retrieve volume backup list '
|
||||
'for volume "%s", so incremental '
|
||||
'backup is disabled.') % search_opts['volume_id']
|
||||
|
||||
exceptions.handle(self.request, msg)
|
||||
|
||||
if kwargs['initial'].get('snapshot_id'):
|
||||
snap_id = kwargs['initial']['snapshot_id']
|
||||
try:
|
||||
@ -84,12 +105,14 @@ class CreateBackupForm(forms.SelfHandlingForm):
|
||||
volume = api.cinder.volume_get(request, data['volume_id'])
|
||||
snapshot_id = data['snapshot_id'] or None
|
||||
force = False
|
||||
incremental = data.get('incremental', False)
|
||||
if volume.status == 'in-use':
|
||||
force = True
|
||||
backup = api.cinder.volume_backup_create(
|
||||
request, data['volume_id'],
|
||||
data['container_name'], data['name'],
|
||||
data['description'], force=force,
|
||||
incremental=incremental,
|
||||
snapshot_id=snapshot_id
|
||||
)
|
||||
|
||||
|
@ -134,11 +134,13 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
self.assertCountEqual(result, expected_backups)
|
||||
|
||||
@test.create_mocks({api.cinder: ('volume_backup_create',
|
||||
'volume_backup_list',
|
||||
'volume_snapshot_list',
|
||||
'volume_get')})
|
||||
def test_create_backup_available(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
backup = self.cinder_volume_backups.first()
|
||||
self.mock_volume_backup_list.return_value = []
|
||||
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
@ -168,17 +170,61 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=False,
|
||||
incremental=False,
|
||||
snapshot_id=None)
|
||||
|
||||
@test.create_mocks({api.cinder: ('volume_backup_create',
|
||||
'volume_backup_list',
|
||||
'volume_snapshot_list',
|
||||
'volume_get')})
|
||||
def test_create_backup_available_incremental(self):
|
||||
volume = self.cinder_volumes.first()
|
||||
backup = self.cinder_volume_backups.list()[1]
|
||||
prior_backups = [self.cinder_volume_backups.list()[0]]
|
||||
self.mock_volume_backup_list.return_value = prior_backups
|
||||
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
'container_name': backup.container_name,
|
||||
'name': backup.name,
|
||||
'incremental': True,
|
||||
'description': backup.description}
|
||||
url = reverse('horizon:project:volumes:create_backup',
|
||||
args=[volume.id])
|
||||
res = self.client.post(url, formData)
|
||||
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(error=0, warning=0)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
self.mock_volume_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
search_opts={'volume_id': volume.id})
|
||||
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
volume.id)
|
||||
self.mock_volume_backup_create.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
volume.id,
|
||||
backup.container_name,
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=False,
|
||||
incremental=True,
|
||||
snapshot_id=None)
|
||||
|
||||
@test.create_mocks(
|
||||
{api.cinder: ('volume_backup_create', 'volume_snapshot_get',
|
||||
'volume_get')})
|
||||
'volume_get', 'volume_backup_list')})
|
||||
def test_create_backup_from_snapshot_table(self):
|
||||
backup = self.cinder_volume_backups.list()[1]
|
||||
volume = self.cinder_volumes.list()[4]
|
||||
snapshot = self.cinder_volume_snapshots.list()[1]
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_list.return_value = []
|
||||
self.mock_volume_snapshot_get.return_value = snapshot
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
@ -204,18 +250,20 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=False,
|
||||
incremental=False,
|
||||
snapshot_id=backup.snapshot_id)
|
||||
|
||||
@test.create_mocks(
|
||||
{api.cinder: ('volume_backup_create',
|
||||
'volume_snapshot_list',
|
||||
'volume_get')})
|
||||
'volume_get', 'volume_backup_list')})
|
||||
def test_create_backup_from_snapshot_volume_table(self):
|
||||
volume = self.cinder_volumes.list()[4]
|
||||
backup = self.cinder_volume_backups.list()[1]
|
||||
snapshots = self.cinder_volume_snapshots.list()[1:3]
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_list.return_value = []
|
||||
self.mock_volume_snapshot_list.return_value = snapshots
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
@ -244,11 +292,12 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=False,
|
||||
incremental=False,
|
||||
snapshot_id=backup.snapshot_id)
|
||||
|
||||
@test.create_mocks(
|
||||
{api.cinder: ('volume_backup_create', 'volume_snapshot_list',
|
||||
'volume_get')})
|
||||
'volume_get', 'volume_backup_list')})
|
||||
def test_create_backup_in_use(self):
|
||||
# The third volume in the cinder test volume data is in-use
|
||||
volume = self.cinder_volumes.list()[2]
|
||||
@ -258,6 +307,7 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
self.mock_volume_snapshot_list.return_value = snapshots
|
||||
self.mock_volume_backup_list.return_value = []
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
@ -283,7 +333,92 @@ class VolumeBackupsViewTests(test.TestCase):
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=True,
|
||||
snapshot_id=None)
|
||||
snapshot_id=None,
|
||||
incremental=False)
|
||||
|
||||
@test.create_mocks(
|
||||
{api.cinder: ('volume_backup_create', 'volume_snapshot_list',
|
||||
'volume_get', 'volume_backup_list')})
|
||||
def test_create_backup_in_use_incremental(self):
|
||||
volume = self.cinder_volumes.list()[2]
|
||||
|
||||
backup = self.cinder_volume_backups.list()[1]
|
||||
snapshots = []
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
self.mock_volume_snapshot_list.return_value = snapshots
|
||||
prior_backups = [self.cinder_volume_backups.list()[0]]
|
||||
self.mock_volume_backup_list.return_value = prior_backups
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
'container_name': backup.container_name,
|
||||
'name': backup.name,
|
||||
'incremental': True,
|
||||
'description': backup.description}
|
||||
url = reverse('horizon:project:volumes:create_backup',
|
||||
args=[volume.id])
|
||||
|
||||
res = self.client.post(url, formData)
|
||||
self.mock_volume_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
search_opts={'volume_id': volume.id})
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(error=0, warning=0)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
volume.id)
|
||||
self.mock_volume_backup_create.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
volume.id,
|
||||
backup.container_name,
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=True,
|
||||
snapshot_id=None,
|
||||
incremental=True)
|
||||
|
||||
@test.create_mocks(
|
||||
{api.cinder: ('volume_backup_create', 'volume_snapshot_list',
|
||||
'volume_get', 'volume_backup_list')})
|
||||
def test_create_backup_in_use_incremental_set_false(self):
|
||||
volume = self.cinder_volumes.list()[2]
|
||||
|
||||
backup = self.cinder_volume_backups.list()[1]
|
||||
snapshots = []
|
||||
self.mock_volume_get.return_value = volume
|
||||
self.mock_volume_backup_create.return_value = backup
|
||||
self.mock_volume_snapshot_list.return_value = snapshots
|
||||
prior_backups = [self.cinder_volume_backups.list()[0]]
|
||||
self.mock_volume_backup_list.return_value = prior_backups
|
||||
formData = {'method': 'CreateBackupForm',
|
||||
'tenant_id': self.tenant.id,
|
||||
'volume_id': volume.id,
|
||||
'container_name': backup.container_name,
|
||||
'name': backup.name,
|
||||
'incremental': False,
|
||||
'description': backup.description}
|
||||
url = reverse('horizon:project:volumes:create_backup',
|
||||
args=[volume.id])
|
||||
|
||||
res = self.client.post(url, formData)
|
||||
self.mock_volume_snapshot_list.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
search_opts={'volume_id': volume.id})
|
||||
self.assertNoFormErrors(res)
|
||||
self.assertMessageCount(error=0, warning=0)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
self.mock_volume_get.assert_called_once_with(test.IsHttpRequest(),
|
||||
volume.id)
|
||||
self.mock_volume_backup_create.assert_called_once_with(
|
||||
test.IsHttpRequest(),
|
||||
volume.id,
|
||||
backup.container_name,
|
||||
backup.name,
|
||||
backup.description,
|
||||
force=True,
|
||||
snapshot_id=None,
|
||||
incremental=False)
|
||||
|
||||
@test.create_mocks({api.cinder: ('volume_list',
|
||||
'volume_snapshot_list',
|
||||
|
Loading…
Reference in New Issue
Block a user