mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 05:53:43 +00:00 
			
		
		
		
	docs: Add a brief document explaining management commands.
Fixes #1330.
This commit is contained in:
		@@ -85,7 +85,8 @@ templating systems.
 | 
			
		||||
These are distinguished from scripts, below, by needing to run a
 | 
			
		||||
Django context (i.e. with database access).
 | 
			
		||||
 | 
			
		||||
* `zerver/management/commands/` Management commands one might run at a
 | 
			
		||||
* `zerver/management/commands/`
 | 
			
		||||
  [Management commands](management-commands.html) one might run at a
 | 
			
		||||
  production deployment site (e.g. scripts to change a value or
 | 
			
		||||
  deactivate a user properly).
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -134,6 +134,7 @@ Contents:
 | 
			
		||||
   pointer
 | 
			
		||||
   markdown
 | 
			
		||||
   realms
 | 
			
		||||
   management-commands
 | 
			
		||||
   front-end-build-process
 | 
			
		||||
   schema-migrations
 | 
			
		||||
   html_css
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								docs/management-commands.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								docs/management-commands.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
# Management commands
 | 
			
		||||
 | 
			
		||||
Zulip has a number of [Django management commands][django-docs] that
 | 
			
		||||
live under `{zerver,zilencer,analytics}/management/commands/`.
 | 
			
		||||
 | 
			
		||||
If you need some Python code to run with a Zulip context (access to
 | 
			
		||||
the database, etc.) in a script, it should probably go in a management
 | 
			
		||||
command.  The key thing distinguishing these from production scripts
 | 
			
		||||
(`scripts/`) and development scripts (`tools/`) is that management
 | 
			
		||||
commands can access the database.
 | 
			
		||||
 | 
			
		||||
While Zulip takes advantage of built-in Django management commands for
 | 
			
		||||
things like, we have dozens that we've written for a range of
 | 
			
		||||
purposes:
 | 
			
		||||
 | 
			
		||||
* Cron jobs to do regular updates, e.g. `update_analytics_counts.py`,
 | 
			
		||||
  `sync_ldap_user_data`, etc.
 | 
			
		||||
* Useful parts of provisioning or upgrading a Zulip development
 | 
			
		||||
  environment or server, e.g. `makemessages`, `compilemessages`,
 | 
			
		||||
  `populate_db`, `fill_memcached_caches`, etc.
 | 
			
		||||
* The actual scripts run by supervisord to run the persistent
 | 
			
		||||
  processes in a Zulip server, e.g. `runtornado` and `process_queue`.
 | 
			
		||||
* For a sysadmin to verify a Zulip server's configuration during
 | 
			
		||||
installation, e.g. `checkconfig`, `send_test_email`.
 | 
			
		||||
* As the interface for doing those rare operations that don't have a
 | 
			
		||||
  UI yet, e.g. `deactivate_realm`, `reactivate_realm`,
 | 
			
		||||
  `change_user_email` (for the case where the user doesn't control the
 | 
			
		||||
  old email address).
 | 
			
		||||
* For a sysadmin to easily interact with and script common possible
 | 
			
		||||
  changes they might want to make to the database on a Zulip server.
 | 
			
		||||
  E.g. `send_password_reset_email`, `export`, `purge_queue`.
 | 
			
		||||
 | 
			
		||||
## Writing management commands
 | 
			
		||||
 | 
			
		||||
It's generally pretty easy to template off an existing management
 | 
			
		||||
command to write a new one.  Some good examples are
 | 
			
		||||
`change_user_email` and `deactivate_realm`.  The Django documentation
 | 
			
		||||
is good, but we have a few pieces advice specific to the Zulip
 | 
			
		||||
project.
 | 
			
		||||
 | 
			
		||||
* If you need to access a realm or user, use the `ZulipBaseCommand`
 | 
			
		||||
  class in `zerver/lib/management.py` so you don't need to write the
 | 
			
		||||
  tedious code of looking those objects up.  This is especially
 | 
			
		||||
  important for users, since the library handles the issues around
 | 
			
		||||
  looking up users by email well (if there's a unique user with that
 | 
			
		||||
  email, just modify it without requiring the user to specify the
 | 
			
		||||
  realm as well, but if there's a collision, throw a nice error).
 | 
			
		||||
* Avoid writing a lot of code in management commands; it's often hard
 | 
			
		||||
  to maintain and thus at risk of bit rot.  Look for code in
 | 
			
		||||
  `zerver/lib/` that already does what you need.  For most actions,
 | 
			
		||||
  you can just call a `do_change_foo` type function from
 | 
			
		||||
  `zerver/lib/actions.py` to do all the work; this is usually far
 | 
			
		||||
  better than manipulating the database correctly, since the library
 | 
			
		||||
  functions used by the UI are maintained to correctly live-update the
 | 
			
		||||
  UI if needed.
 | 
			
		||||
 | 
			
		||||
[django-docs]: https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/
 | 
			
		||||
		Reference in New Issue
	
	Block a user