diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index ab6ec02..df0ea06 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -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 @@ -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 @@ -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 @@ -68,4 +71,4 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: verbose: true - password: ${{ secrets.PYPI_API_TOKEN }} \ No newline at end of file + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/cli.py b/cli.py index 702db94..9518902 100644 --- a/cli.py +++ b/cli.py @@ -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__ @@ -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() diff --git a/weaviate_cli/commands/cancel.py b/weaviate_cli/commands/cancel.py new file mode 100644 index 0000000..012608e --- /dev/null +++ b/weaviate_cli/commands/cancel.py @@ -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() diff --git a/weaviate_cli/commands/get.py b/weaviate_cli/commands/get.py index 7519c2b..5917a1b 100644 --- a/weaviate_cli/commands/get.py +++ b/weaviate_cli/commands/get.py @@ -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 @@ -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() diff --git a/weaviate_cli/managers/backup_manager.py b/weaviate_cli/managers/backup_manager.py index 957e880..0b469f8 100644 --- a/weaviate_cli/managers/backup_manager.py +++ b/weaviate_cli/managers/backup_manager.py @@ -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}" + )