Skip to content

Commit

Permalink
Merge pull request #86 from weaviate/jose/backup_cancellation
Browse files Browse the repository at this point in the history
Add support for backup cancellation and retreiving backup status
  • Loading branch information
jfrancoa authored Oct 30, 2024
2 parents 3f366ed + fcabcdf commit c142c14
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 5 deletions.
13 changes: 8 additions & 5 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
name: Build and Publish

on:
push:
tags:
- '**'
workflow_run:
workflows: ["Main"]
types:
- completed # only run when the main workflow is completed

jobs:
build-package:
name: Build a package
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags') && github.event.workflow_run.conclusion == 'success'
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -31,7 +33,7 @@ jobs:
gh-release:
name: Create a GitHub Release on new tags
needs: [build-package]
if: startsWith(github.ref, 'refs/tags')
if: startsWith(github.ref, 'refs/tags') && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -50,6 +52,7 @@ jobs:
publish:
runs-on: ubuntu-latest
needs: [gh-release]
if: startsWith(github.ref, 'refs/tags') && github.event.workflow_run.conclusion == 'success'
steps:
- name: Checkout
uses: actions/checkout@v4
Expand All @@ -68,4 +71,4 @@ jobs:
uses: pypa/gh-action-pypi-publish@release/v1
with:
verbose: true
password: ${{ secrets.PYPI_API_TOKEN }}
password: ${{ secrets.PYPI_API_TOKEN }}
2 changes: 2 additions & 0 deletions cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from weaviate_cli.commands.update import update
from weaviate_cli.commands.query import query
from weaviate_cli.commands.restore import restore
from weaviate_cli.commands.cancel import cancel
from weaviate_cli import __version__


Expand Down Expand Up @@ -50,6 +51,7 @@ def main(ctx: click.Context, config_file):
main.add_command(update)
main.add_command(restore)
main.add_command(query)
main.add_command(cancel)

if __name__ == "__main__":
main()
42 changes: 42 additions & 0 deletions weaviate_cli/commands/cancel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import click
import sys
from weaviate_cli.utils import get_client_from_context
from weaviate_cli.managers.backup_manager import BackupManager


# Create Group
@click.group()
def cancel():
"""Cancel operations in Weaviate."""
pass


@cancel.command("backup")
@click.option(
"--backend",
default="s3",
type=click.Choice(["s3", "gcs", "filesystem"]),
help="The backend used for storing the backups (default: s3).",
)
@click.option(
"--backup_id",
default="test-backup",
help="Identifier used for the backup (default: test-backup).",
)
@click.pass_context
def cancel_backup_cli(ctx: click.Context, backend: str, backup_id: str) -> None:
"""Cancel a backup in Weaviate."""

client = None
try:
client = get_client_from_context(ctx)
backup_manager = BackupManager(client)
backup_manager.cancel_backup(backend=backend, backup_id=backup_id)
except Exception as e:
click.echo(f"Error: {e}")
if client:
client.close()
sys.exit(1)
finally:
if client:
client.close()
37 changes: 37 additions & 0 deletions weaviate_cli/commands/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from weaviate_cli.managers.tenant_manager import TenantManager
from weaviate_cli.utils import get_client_from_context
from weaviate_cli.managers.collection_manager import CollectionManager
from weaviate_cli.managers.backup_manager import BackupManager
from weaviate_cli.managers.shard_manager import ShardManager
from weaviate.exceptions import WeaviateConnectionError

Expand Down Expand Up @@ -91,3 +92,39 @@ def get_shards_cli(ctx, collection):
finally:
if client:
client.close()


@get.command("backup")
@click.option(
"--backend",
default="s3",
type=click.Choice(["s3", "gcs", "filesystem"]),
help="The backend used for storing the backups (default: s3).",
)
@click.option(
"--backup_id",
default=None,
help="Identifier for the backup you want to get its status.",
)
@click.option(
"--restore",
is_flag=True,
help="Get the status of the restoration job for the backup.",
)
@click.pass_context
def get_backup_cli(ctx, backend, backup_id, restore):
"""Get backup status for a given backup ID. If --restore is provided, get the status of the restoration job for the backup."""

client = None
try:
client = get_client_from_context(ctx)
backup_man = BackupManager(client)
backup_man.get_backup(backend=backend, backup_id=backup_id, restore=restore)
except Exception as e:
click.echo(f"Error: {e}")
if client:
client.close()
sys.exit(1)
finally:
if client:
client.close()
44 changes: 44 additions & 0 deletions weaviate_cli/managers/backup_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,47 @@ def restore_backup(
)

click.echo(f"Backup '{backup_id}' restored successfully in Weaviate.")

def get_backup(self, backend: str, backup_id: str, restore: bool) -> None:

if restore:
backup = self.client.backup.get_restore_status(
backup_id=backup_id,
backend=backend,
)
print(f"Backup ID: {backup.backup_id}")
print(f"Backup Path: {backup.path}")
print(f"Backup Status: {backup.status}")
if "collections" in backup:
print(f"Collections: {backup.collections}")
else:
if backup_id is not None:
backup = self.client.backup.get_create_status(
backup_id=backup_id, backend=backend
)
print(f"Backup ID: {backup.backup_id}")
print(f"Backup Path: {backup.path}")
print(f"Backup Status: {backup.status}")
if "collections" in backup:
print(f"Collections: {backup.collections}")
else:
raise Exception("This functionality is not supported yet.")
# backups = client.backup.list_backups(backend=backend)
# for backup in backups:
# print(f"Backup ID: {backup.backup_id}")
# print(f"Backup Path: {backup.path}")
# print(f"Backup Status: {backup.status}")
# if "collections" in backup:
# print(f"Collections: {backup.collections}")
# print("------------------------------")

def cancel_backup(self, backend: str, backup_id: str) -> None:
if self.client.backup.cancel(backend=backend, backup_id=backup_id):
click.echo(f"Backup '{backup_id}' cancelled successfully in Weaviate.")
else:
backup_status = self.client.backup.get_create_status(
backend=backend, backup_id=backup_id
)
raise Exception(
f"Error: Backup '{backup_id}' could not be cancelled in Weaviate. Current status: {backup_status.status}"
)

0 comments on commit c142c14

Please sign in to comment.