Files
odoo_source/odoo/cli/command.py
T
Xavier Morel cf221d4ba7 [ADD] cli: db manager
Currently dbs can only be managed via the UI in order to take
filestores in account: while it's possible to load/copy/rename/drop
databases via `psql`, that will not manage the related filestores so
the result of the operation is incomplete DBs and leftover filestores
littering the disk.

Seems like a good idea to add a CLI to perform the same
tasks. Currently the CLI calls into the corresponding service, rather
than both calling into (possibly better designed) unified APIs, but
that seems fine for an initial version.

The top-level `db` command acts as a db manager, with git-style
sub-sub-commands for the various operations:

- `load` to load a dump file into a database (with a specified name or
  not)
- `dump` to dump a local db to a zip dump (pg_dump can be created via
  the corresponding command so not a concern)
- `duplicate` and `rename`
- `drop` in order to drop both the database itself and the
  corresponding filestore

Notably, `create` is currently left out because a database can
trivially be created by invoking odoo using a dbname which doesn't
exist, so doesn't seem useful.

`list` is also left out, because `psql -l` generally does the job.

closes odoo/odoo#97365

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-26 18:41:26 +02:00

59 lines
1.9 KiB
Python

from __future__ import print_function
import logging
import sys
import os
from os.path import join as joinpath, isdir
import odoo
from odoo.modules import get_modules, get_module_path, initialize_sys_path
commands = {}
class Command:
name = None
def __init_subclass__(cls):
cls.name = cls.name or cls.__name__.lower()
commands[cls.name] = cls
class Help(Command):
"""Display the list of available commands"""
def run(self, args):
print("Available commands:\n")
names = list(commands)
padding = max([len(k) for k in names]) + 2
for k in sorted(names):
name = k.ljust(padding, ' ')
doc = (commands[k].__doc__ or '').strip()
print(" %s%s" % (name, doc))
print("\nUse '%s <command> --help' for individual command help." % sys.argv[0].split(os.path.sep)[-1])
def main():
args = sys.argv[1:]
# The only shared option is '--addons-path=' needed to discover additional
# commands from modules
if len(args) > 1 and args[0].startswith('--addons-path=') and not args[1].startswith("-"):
# parse only the addons-path, do not setup the logger...
odoo.tools.config._parse_config([args[0]])
args = args[1:]
# Default legacy command
command = "server"
# TODO: find a way to properly discover addons subcommands without importing the world
# Subcommand discovery
if len(args) and not args[0].startswith("-"):
logging.disable(logging.CRITICAL)
initialize_sys_path()
for module in get_modules():
if isdir(joinpath(get_module_path(module), 'cli')):
__import__('odoo.addons.' + module)
logging.disable(logging.NOTSET)
command = args[0]
args = args[1:]
if command in commands:
o = commands[command]()
o.run(args)
else:
sys.exit('Unknown command %r' % (command,))