Skip to content

Commit

Permalink
Prevent recursive DSE snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvoncek committed Jan 12, 2024
1 parent 4ed1fd5 commit 9ee5d1a
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
11 changes: 10 additions & 1 deletion medusa/cassandra_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,20 @@ def create_dse_snapshot(self, backup_name):
That folder is nested in the parent folder, just like for regular tables
This way, we can reuse a lot of code later on
"""

def _ignore_snapshots(folder, contents):
ignored = set()

Check warning on line 450 in medusa/cassandra_utils.py

View check run for this annotation

Codecov / codecov/patch

medusa/cassandra_utils.py#L449-L450

Added lines #L449 - L450 were not covered by tests
if folder.endswith('metadata/snapshots'):
logging.info(f'Ignoring {contents} in folder {folder}')

Check warning on line 452 in medusa/cassandra_utils.py

View check run for this annotation

Codecov / codecov/patch

medusa/cassandra_utils.py#L452

Added line #L452 was not covered by tests
for c in contents:
ignored.add(c)
return ignored

Check warning on line 455 in medusa/cassandra_utils.py

View check run for this annotation

Codecov / codecov/patch

medusa/cassandra_utils.py#L454-L455

Added lines #L454 - L455 were not covered by tests

tag = "{}{}".format(self.SNAPSHOT_PREFIX, backup_name)
if not self.dse_snapshot_exists(tag):
src_path = self._dse_root / self._dse_metadata_folder
dst_path = self._dse_root / self._dse_metadata_folder / 'snapshots' / tag
shutil.copytree(src_path, dst_path)
shutil.copytree(src_path, dst_path, ignore=_ignore_snapshots)

Check warning on line 461 in medusa/cassandra_utils.py

View check run for this annotation

Codecov / codecov/patch

medusa/cassandra_utils.py#L461

Added line #L461 was not covered by tests

return Cassandra.DseSnapshot(self, tag)

Expand Down
6 changes: 5 additions & 1 deletion medusa/service/snapshot/nodetool_snapshot_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ def create_snapshot(self, *, tag):
# create the Nodetool command
cmd = self._nodetool.nodetool + ['snapshot', '-t', tag]
logging.debug('Executing: {}'.format(' '.join(cmd)))
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, universal_newlines=True)
try:
subprocess.check_output(cmd, universal_newlines=True)
except subprocess.CalledProcessError as e:
logging.error('nodetool output: {}'.format(e.output))
logging.error('Creating snapshot failed and without a snapshot we cannot do a backup')

Check warning on line 36 in medusa/service/snapshot/nodetool_snapshot_service.py

View check run for this annotation

Codecov / codecov/patch

medusa/service/snapshot/nodetool_snapshot_service.py#L32-L36

Added lines #L32 - L36 were not covered by tests

def delete_snapshot(self, *, tag):
# create the Nodetool command
Expand Down
20 changes: 15 additions & 5 deletions tests/integration/features/integration_tests.feature
Original file line number Diff line number Diff line change
Expand Up @@ -1058,16 +1058,26 @@ Feature: Integration tests
@29
Scenario Outline: Backup and restore a DSE cluster with search enabled
Given I have a fresh DSE cluster version "6.8.38" with "<client encryption>" running named "scenario29"
Given I am using "<storage>" as storage provider in ccm cluster "<client encryption>"
Given I am using "<storage>" as storage provider in ccm cluster "<client encryption>" with gRPC server
Then the gRPC server is up
When I create the "test" table in keyspace "medusa"
And I create a search index on the "test" table in keyspace "medusa"
And I load 100 rows in the "medusa.test" table
When I run a DSE "nodetool flush" command
Then I can make a search query against the "medusa"."test" table
When I perform a backup in "differential" mode of the node named "first_backup" with md5 checks "disabled"
Then I can see the backup named "first_backup" when I list the backups
And the backup "first_backup" has server_type "dse" in its metadata
When I restore the backup named "first_backup"
When I perform an async backup over gRPC in "differential" mode of the node named "backup29-1"
Then the backup index exists
Then I can see the backup named "backup29-1" when I list the backups
And the backup "backup29-1" has server_type "dse" in its metadata
Then I verify over gRPC that the backup "backup29-1" exists and is of type "differential"
Then I verify over gRPC that the backup "backup29-1" has expected status SUCCESS
When I perform an async backup over gRPC in "differential" mode of the node named "backup29-2"
Then the backup index exists
Then I can see the backup named "backup29-2" when I list the backups
And the backup "backup29-2" has server_type "dse" in its metadata
Then I verify over gRPC that the backup "backup29-2" exists and is of type "differential"
Then I verify over gRPC that the backup "backup29-2" has expected status SUCCESS
When I restore the backup named "backup29-2"
And I wait for the DSE Search indexes to be rebuilt
Then I have 100 rows in the "medusa.test" table in ccm cluster "<client encryption>"
Then I can make a search query against the "medusa"."test" table
Expand Down

0 comments on commit 9ee5d1a

Please # to comment.