export: Add a --deactivate flag which happens just prior to export.

This removes a manual step during export.
This commit is contained in:
Alex Vandiver
2020-08-28 15:17:21 -07:00
committed by Tim Abbott
parent 15d7e7a6fd
commit b23a55e669
2 changed files with 21 additions and 15 deletions

View File

@@ -260,9 +260,9 @@ you're exporting data. There are two ways to do this:
preferred if you're not hosting multiple organizations, because it has preferred if you're not hosting multiple organizations, because it has
no side effects other than disabling the Zulip server for the no side effects other than disabling the Zulip server for the
duration. duration.
1. `manage.py deactivate_realm -r 'target_org'`, which deactivates the target 1. Pass `--deactivate` to `./manage export`, which first deactivates
organization, logging out all active login sessions and preventing all the target organization, logging out all active login sessions and
accounts from logging in or accessing the API. This is preventing all accounts from logging in or accessing the API. This is
preferred for environments like Zulip Cloud where you might want to preferred for environments like Zulip Cloud where you might want to
export a single organization without disrupting any other users, and export a single organization without disrupting any other users, and
the intent is to move hosting of the organization (and forcing users the intent is to move hosting of the organization (and forcing users
@@ -281,9 +281,9 @@ following commands:
``` ```
cd /home/zulip/deployments/current cd /home/zulip/deployments/current
# supervisorctl stop all # Stops the Zulip server # supervisorctl stop all # Stops the Zulip server
# ./manage.py deactivate_realm -r '' # Deactivates the organization # export DEACTIVATE_FLAG="--deactivate" # Deactivates the organization
./manage.py export -r '' # Exports the data ./manage.py export -r '' $DEACTIVATE_FLAG # Exports the data
``` ```
(The `-r` option lets you specify the organization to export; `''` is (The `-r` option lets you specify the organization to export; `''` is

View File

@@ -7,6 +7,7 @@ from typing import Any
from django.conf import settings from django.conf import settings
from django.core.management.base import CommandError from django.core.management.base import CommandError
from zerver.lib.actions import do_deactivate_realm
from zerver.lib.export import export_realm_wrapper from zerver.lib.export import export_realm_wrapper
from zerver.lib.management import ZulipBaseCommand from zerver.lib.management import ZulipBaseCommand
from zerver.models import Message, Reaction, UserProfile from zerver.models import Message, Reaction, UserProfile
@@ -53,12 +54,8 @@ class Command(ZulipBaseCommand):
The proper procedure for using this to export a realm is as follows: The proper procedure for using this to export a realm is as follows:
* Use `./manage.py deactivate_realm` to deactivate the realm, so * Use `./manage.py export --deactivate` to deactivate and export
nothing happens in the realm being exported during the export the realm, producing a data tarball.
process.
* Use `./manage.py export` to export the realm, producing a data
tarball.
* Transfer the tarball to the new server and unpack it. * Transfer the tarball to the new server and unpack it.
@@ -69,9 +66,8 @@ class Command(ZulipBaseCommand):
* Inform the users about the things broken above. * Inform the users about the things broken above.
We recommend testing by exporting without having deactivated the We recommend testing by exporting without `--deactivate` first, to
realm first, to make sure you have the procedure right and make sure you have the procedure right and minimize downtime.
minimize downtime.
Performance: In one test, the tool exported a realm with hundreds Performance: In one test, the tool exported a realm with hundreds
of users and ~1M messages of history with --threads=1 in about 3 of users and ~1M messages of history with --threads=1 in about 3
@@ -94,6 +90,9 @@ class Command(ZulipBaseCommand):
parser.add_argument('--public-only', parser.add_argument('--public-only',
action="store_true", action="store_true",
help='Export only public stream messages and associated attachments') help='Export only public stream messages and associated attachments')
parser.add_argument('--deactivate-realm',
action="store_true",
help='Deactivate the realm immediately before exporting')
parser.add_argument('--consent-message-id', parser.add_argument('--consent-message-id',
dest="consent_message_id", dest="consent_message_id",
action="store", action="store",
@@ -125,6 +124,9 @@ class Command(ZulipBaseCommand):
if public_only and consent_message_id is not None: if public_only and consent_message_id is not None:
raise CommandError('Please pass either --public-only or --consent-message-id') raise CommandError('Please pass either --public-only or --consent-message-id')
if options["deactivate_realm"] and realm.deactivated:
raise CommandError(f"The realm {realm.string_id} is already deactivated. Aborting...")
if consent_message_id is not None: if consent_message_id is not None:
try: try:
message = Message.objects.get(id=consent_message_id) message = Message.objects.get(id=consent_message_id)
@@ -174,6 +176,10 @@ class Command(ZulipBaseCommand):
except FileExistsError: except FileExistsError:
raise CommandError(f"Refusing to overwrite existing tarball: {tarball_path}. Aborting...") raise CommandError(f"Refusing to overwrite existing tarball: {tarball_path}. Aborting...")
if options["deactivate_realm"]:
print(f"\033[94mDeactivating realm\033[0m: {realm.string_id}")
do_deactivate_realm(realm)
def percent_callback(bytes_transferred: Any) -> None: def percent_callback(bytes_transferred: Any) -> None:
sys.stdout.write('.') sys.stdout.write('.')
sys.stdout.flush() sys.stdout.flush()