2019-11-22 02:07:17 +01:00
|
|
|
# Management commands
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
Sometimes, you need to modify or inspect Zulip data from the command
|
|
|
|
line. To help with this, Zulip ships with over 100 command-line tools
|
|
|
|
implemented using the [Django management commands
|
|
|
|
framework][django-management].
|
|
|
|
|
2019-11-22 02:07:17 +01:00
|
|
|
## Running management commands
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
Start by logging in as the `zulip` user on the Zulip server. Then run
|
|
|
|
them as follows:
|
|
|
|
|
|
|
|
```
|
|
|
|
cd /home/zulip/deployments/current
|
|
|
|
|
|
|
|
# Start by reading the help
|
|
|
|
./manage.py <command_name> --help
|
|
|
|
|
|
|
|
# Once you've determine this is the command for you, run it!
|
|
|
|
./manage.py <command_name> <args>
|
|
|
|
```
|
|
|
|
|
|
|
|
A full list of commands is available via `./manage.py help`; you'll
|
|
|
|
primarily want to use those in the `[zerver]` section as those are the
|
|
|
|
ones specifically built for Zulip.
|
|
|
|
|
|
|
|
As a warning, some of them are designed for specific use cases and may
|
|
|
|
cause problems if run in other situations. If you're not sure, it's
|
|
|
|
worth reading the documentation (or the code, usually available at
|
|
|
|
`zerver/management/commands/`; they're generally very simple programs).
|
|
|
|
|
2020-05-17 14:01:32 +02:00
|
|
|
### Accessing an organization's `string_id`
|
2019-11-22 19:46:00 +01:00
|
|
|
|
|
|
|
Since Zulip supports hosting multiple organizations on a single
|
|
|
|
server, many management commands require you specify which
|
2019-12-13 01:06:40 +01:00
|
|
|
organization ("realm") you'd like to modify, either via numerical or
|
|
|
|
string ID (usually the subdomain).
|
2019-11-22 02:07:17 +01:00
|
|
|
|
|
|
|
You can see all the organizations on your Zulip server using
|
|
|
|
`./manage.py list_realms`.
|
|
|
|
|
|
|
|
```
|
|
|
|
zulip@zulip:~$ /home/zulip/deployments/current/manage.py list_realms
|
|
|
|
id string_id name
|
|
|
|
-- --------- ----
|
|
|
|
1 zulipinternal None
|
|
|
|
2 Zulip Community
|
|
|
|
```
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
(Note that every Zulip server has a special `zulipinternal` realm
|
|
|
|
containing system-internal bots like `Notification Bot`; you are
|
|
|
|
unlikely to ever need to interact with that realm.)
|
2019-11-22 02:07:17 +01:00
|
|
|
|
|
|
|
Unless you are
|
|
|
|
[hosting multiple organizations on your Zulip server](../production/multiple-organizations.md),
|
|
|
|
your single Zulip organization on the root domain will have the empty
|
|
|
|
string (`''`) as its `string_id`. So you can run e.g.:
|
2019-11-22 19:46:00 +01:00
|
|
|
|
2019-11-22 02:07:17 +01:00
|
|
|
```
|
|
|
|
zulip@zulip:~$ /home/zulip/deployments/current/manage.py show_admins -r ''
|
|
|
|
```
|
|
|
|
|
|
|
|
Otherwise, the `string_id` will correspond to the organization's
|
|
|
|
subdomain. E.g. on `it.zulip.example.com`, use
|
|
|
|
`/home/zulip/deployments/current/manage.py show_admins -r it`.
|
|
|
|
|
|
|
|
## manage.py shell
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
If you need to query or edit data directly in the Zulip database, the
|
|
|
|
best way to do this is with Django's built-in management shell.
|
|
|
|
|
2019-12-13 01:06:40 +01:00
|
|
|
You can get an IPython shell with full access to code within the Zulip
|
2019-11-22 02:07:17 +01:00
|
|
|
project using `manage.py shell`, e.g., you can do the following to
|
|
|
|
change a user's email address:
|
|
|
|
|
|
|
|
```
|
2019-11-22 19:46:00 +01:00
|
|
|
$ cd /home/zulip/deployments/current/
|
|
|
|
$ ./manage.py shell
|
2019-11-22 02:07:17 +01:00
|
|
|
In [1]: user_profile = get_user_profile_by_email("email@example.com")
|
|
|
|
In [2]: do_change_user_delivery_email(user_profile, "new_email@example.com")
|
|
|
|
```
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
Any Django tutorial can give you helpful advice on querying and
|
2021-04-29 19:06:52 +02:00
|
|
|
formatting data from Zulip's tables for inspection; Zulip's own
|
|
|
|
[new feature tutorial](../tutorials/new-feature-tutorial.md) should help
|
|
|
|
you understand how the codebase is organized.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
We recommend against directly editing objects and saving them using
|
|
|
|
Django's `object.save()`. While this will save your changes to the
|
|
|
|
database, for most objects, in addition to saving the changes to the
|
|
|
|
database, one may also need to flush caches, notify the apps and open
|
|
|
|
browser windows, and record the change in Zulip's `RealmAuditLog`
|
|
|
|
audit history table. For almost any data change you want to do, there
|
|
|
|
is already a function in `zerver.lib.actions.py` with a name like
|
|
|
|
`do_change_full_name` that updates that field and notifies clients
|
|
|
|
correctly.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
For convenience, Zulip automatically import `zerver/models.py` and
|
|
|
|
`zerver/lib/actions.py` into every management shell; if you need to
|
|
|
|
access other functions, you'll need to import them yourself.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
|
|
|
## Other useful manage.py commands
|
|
|
|
|
|
|
|
There are dozens of useful management commands under
|
|
|
|
`zerver/management/commands/`. We detail a few here:
|
|
|
|
|
2019-11-22 19:46:00 +01:00
|
|
|
* `./manage.py help`: Lists all available management commands.
|
|
|
|
* `./manage.py dbshell`: If you're more comfortable with raw SQL than
|
2020-10-26 22:27:53 +01:00
|
|
|
Python, this will open a PostgreSQL SQL shell connected to the Zulip
|
2019-11-22 19:46:00 +01:00
|
|
|
server's database. Beware of changing data; editing data directly
|
2020-10-26 22:27:53 +01:00
|
|
|
with SQL will often not behave correctly because PostgreSQL doesn't
|
2019-11-22 19:46:00 +01:00
|
|
|
know to flush Zulip's caches or notify browsers of changes.
|
|
|
|
* `./manage.py send_custom_email`: Can be used to send an email to a set
|
2019-11-22 02:07:17 +01:00
|
|
|
of users. The `--help` documents how to run it from a `manage.py
|
|
|
|
shell` for use with more complex programmatically computed sets of
|
|
|
|
users.
|
2019-11-22 19:46:00 +01:00
|
|
|
* `./manage.py send_password_reset_email`: Sends password reset email(s)
|
2019-11-22 02:07:17 +01:00
|
|
|
to one or more users.
|
2021-05-10 20:27:13 +02:00
|
|
|
* `./manage.py change_realm_subdomain`: Change subdomain of a realm.
|
2019-11-22 19:46:00 +01:00
|
|
|
* `./manage.py change_user_email`: Change a user's email address.
|
2020-10-22 20:30:35 +02:00
|
|
|
* `./manage.py change_user_role`: Can change are user's role
|
2019-12-13 01:06:40 +01:00
|
|
|
(easier done [via the
|
2020-12-20 14:21:42 +01:00
|
|
|
UI](https://zulip.com/help/change-a-users-role)) or give bots the
|
|
|
|
`can_forge_sender` permission, which is needed for certain special API features.
|
2021-02-23 18:27:45 +01:00
|
|
|
* `./manage.py export_single_user`: does a limited version of the [main
|
2019-11-22 19:46:00 +01:00
|
|
|
export tools](../production/export-and-import.md) containing just
|
|
|
|
the messages accessible by a single user.
|
2021-02-23 18:32:38 +01:00
|
|
|
* `./manage.py reactivate_realm`: Reactivates a realm.
|
2019-11-22 02:07:17 +01:00
|
|
|
|
|
|
|
All of our management commands have internal documentation available
|
|
|
|
via `manage.py command_name --help`.
|
2021-04-29 19:06:52 +02:00
|
|
|
|
|
|
|
## Custom management commands
|
|
|
|
|
|
|
|
Zulip supports several mechanisms for running custom code on a
|
|
|
|
self-hosted Zulip server:
|
|
|
|
|
|
|
|
* Using an existing [integration][integrations] or writing your own
|
|
|
|
[webhook integration][webhook-integrations] or [bot][writing-bots].
|
|
|
|
* Writing a program using the [Zulip API][zulip-api].
|
|
|
|
* [Modifying the Zulip server][modifying-zulip].
|
|
|
|
* Using the interactive [management shell](#manage-py-shell),
|
|
|
|
documented above, for one-time work or prototyping.
|
|
|
|
* Writing a custom management command, detailed here.
|
|
|
|
|
|
|
|
Custom management commands are Python 3 programs that run inside
|
|
|
|
Zulip's context, so that they can access its libraries, database, and
|
|
|
|
code freely. They can be the best choice when you want to run custom
|
|
|
|
code that is not permitted by Zulip's security model (and thus can't
|
|
|
|
be done more easily using the [REST API][zulip-api]) and that you
|
|
|
|
might want to run often (and so the interactive `manage.py shell` is
|
|
|
|
not suitable, though we recommend using the management shell to
|
|
|
|
prototype queries).
|
|
|
|
|
|
|
|
Our developer documentation on [writing management
|
|
|
|
commands][management-commands-dev] explains how to write them.
|
|
|
|
|
|
|
|
Simply writing the command inside a `deployments/` directory is not
|
|
|
|
ideal, because a new such directory is created every time you upgrade
|
|
|
|
the Zulip server.
|
|
|
|
|
|
|
|
Instead, we recommend deploying custom management commands either via
|
|
|
|
the [modifying Zulip][modifying-zulip] process or by storing them in
|
|
|
|
`/etc/zulip` (so they are included in
|
|
|
|
[backups](../production/export-and-import.html#backups)) and then
|
|
|
|
symlinking them into
|
|
|
|
`/home/zulip/deployments/current/zerver/management/` after each
|
|
|
|
upgrade.
|
|
|
|
|
|
|
|
[modifying-zulip]: ../production/upgrade-or-modify.html#modifying-zulip
|
|
|
|
[writing-bots]: https://zulip.com/api/writing-bots
|
|
|
|
[integrations]: https://zulip.com/integrations
|
|
|
|
[zulip-api]: https://zulip.com/api/rest
|
|
|
|
[webhook-integrations]: https://zulip.com/api/incoming-webhooks-overview
|
|
|
|
[management-commands-dev]: ../subsystems/management-commands.md
|
|
|
|
[django-management]: https://docs.djangoproject.com/en/2.2/ref/django-admin/#django-admin-and-manage-py
|