Тьюториал docker-compose из python
Есть ли возможность запустить из python docker-compose, без запуска дополнительного процесса?
Ответы (1 шт):
В тестах CLI docker-compose можно найти TopLevelCommand, который и является классом для запуска docker-compose.
Немного детальнее. Создадим несколько функций, который мы получили из вышеуказанного репозитория.
from compose.cli.command import get_project
from compose.cli.utils import get_version_info
from compose.cli.main import TopLevelCommand, setup_logging, setup_console_handler, console_handler, \
set_no_color_if_clicolor, setup_parallel_logger, perform_command
from compose.cli import errors
from compose.cli.docopt_command import DocoptDispatcher
import functools
setup_logging()
dispatcher = DocoptDispatcher(
TopLevelCommand,
{'options_first': True, 'version': get_version_info('compose')})
options, handler, command_options = dispatcher.parse(sys.argv[1:])
setup_console_handler(console_handler,
options.get('--verbose'),
set_no_color_if_clicolor(options.get('--no-ansi')),
options.get("--log-level"))
setup_parallel_logger(set_no_color_if_clicolor(options.get('--no-ansi')))
if options.get('--no-ansi'):
command_options['--no-color'] = True
cmd = functools.partial(perform_command, options, handler, command_options)
cmd()
Далее, можно сжать код до следующего:
from compose.cli.command import get_project
from compose.cli.utils import get_version_info
from compose.cli.main import TopLevelCommand
from compose.cli import errors
from compose.cli.docopt_command import DocoptDispatcher
import functools
def perform_command(options, handler, command_options):
project_dir = '.'
project = get_project(project_dir, options.get('--file'))
command = TopLevelCommand(project, options=options)
with errors.handle_connection_errors(project.client):
handler(command, command_options)
def run(src_path=None):
if src_path is None:
src_path = './'
dispatcher = DocoptDispatcher(
TopLevelCommand,
{'options_first': True, 'version': get_version_info('compose')},
)
cli_command = ['-f', 'docker-compose.yml', 'up', '-d']
options, handler, command_options = dispatcher.parse(cli_command)
command = functools.partial(perform_command, options, handler, command_options)
command()
Этот кусок кода запускает docker-compose из файла, основываясь на cli интерфейсе.
Теперь, если заглянуть внутрь TopLevelCommand, в частности, внутрь up, то легко увидеть, что код сводится к следующему:
from compose.cli.command import get_project
from compose.cli.docopt_command import DocoptDispatcher
def run(src_path=None):
if src_path is None:
src_path = './'
dispatcher = DocoptDispatcher(
TopLevelCommand,
{'options_first': True, 'version': get_version_info('compose')},
)
cli_command = ['-f', f'{src_path}docker-compose.yml', 'up', '-d']
options, handler, command_options = dispatcher.parse(cli_command)
project_dir = '.'
project = get_project(project_dir, options.get('--file')).up()
print(project)
И, затем, к следующему:
from compose.cli.command import get_project
def run(file_path, project_dir):
servies = get_project(project_dir, [file_path]).up()
return servies
где, в project хранится список запущенных сервисов.
Таким образом, если Вам требуется сократить число команд и вызывать docker-compose на уровне языка, следует выполнить команду, как написано в первом блоке, а затем проследить, какие конструкции языка используются.