annotate sat/plugins/plugin_app_manager_docker/__init__.py @ 3998:402d31527af4

plugin app manager: `start` doesn't wait anymore for actual app start: Application may be long to start (e.g. a Docker app may have to download images first, and even without the downloading, the starting could be long), which may lead to UI blocking or bridge time out. To prevent that, `start` is now returning immediately, and 2 new signals are used to indicate when the application is started, of if something wrong happened. `start` now returns initial app data, including exposed data without the computed exposed data. The computed data must be retrieved after the app has been started.
author Goffi <goffi@goffi.org>
date Sat, 04 Mar 2023 18:30:47 +0100
parents be6d91572633
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3373
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
2
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # SàT plugin to manage Docker
3479
be6d91572633 date update
Goffi <goffi@goffi.org>
parents: 3382
diff changeset
4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
3373
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
5
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
10
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
15
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
18
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
19 from pathlib import Path
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from twisted.python.procutils import which
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core.i18n import _
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from sat.core.constants import Const as C
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core import exceptions
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from sat.core.log import getLogger
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from sat.tools.common import async_process
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
26
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
27 log = getLogger(__name__)
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
28
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
29
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
30 PLUGIN_INFO = {
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
31 C.PI_NAME: "Docker Applications Manager",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
32 C.PI_IMPORT_NAME: "APP_MANAGER_DOCKER",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
33 C.PI_TYPE: C.PLUG_TYPE_MISC,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
34 C.PI_MODES: C.PLUG_MODE_BOTH,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
35 C.PI_DEPENDENCIES: ["APP_MANAGER"],
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
36 C.PI_MAIN: "AppManagerDocker",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
37 C.PI_HANDLER: "no",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
38 C.PI_DESCRIPTION: _(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
39 """Applications Manager for Docker"""),
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
40 }
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
41
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
42
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
43 class AppManagerDocker:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
44 name = "docker-compose"
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
45 discover_path = Path(__file__).parent
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
46
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
47 def __init__(self, host):
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
48 log.info(_("Docker App Manager initialization"))
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
49 try:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
50 self.docker_compose_path = which('docker-compose')[0]
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
51 except IndexError:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
52 raise exceptions.NotFound(
3382
3b08caa805e7 plugin app manager docker: typo
Goffi <goffi@goffi.org>
parents: 3373
diff changeset
53 '"docker-compose" executable not found, Docker can\'t be used with '
3373
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
54 'application manager')
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
55 self.host = host
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
56 self._am = host.plugins['APP_MANAGER']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
57 self._am.register(self)
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
58
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
59 async def start(self, app_data: dict) -> None:
3998
402d31527af4 plugin app manager: `start` doesn't wait anymore for actual app start:
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
60 await self._am.start_common(app_data)
3373
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
61 working_dir = app_data['_instance_dir_path']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
62 try:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
63 override = app_data['override']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
64 except KeyError:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
65 pass
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
66 else:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
67 log.debug("writting override file")
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
68 override_path = working_dir / "docker-compose.override.yml"
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
69 with override_path.open("w") as f:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
70 self._am.dump(override, f)
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
71 await async_process.run(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
72 self.docker_compose_path,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
73 "up",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
74 "--detach",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
75 path=str(working_dir),
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
76 )
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
77
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
78 async def stop(self, app_data: dict) -> None:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
79 working_dir = app_data['_instance_dir_path']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
80 await async_process.run(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
81 self.docker_compose_path,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
82 "down",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
83 path=str(working_dir),
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
84 )
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
85
3998
402d31527af4 plugin app manager: `start` doesn't wait anymore for actual app start:
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
86 async def compute_expose(self, app_data: dict) -> dict:
3373
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
87 working_dir = app_data['_instance_dir_path']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
88 expose = app_data['expose']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
89 ports = expose.get('ports', {})
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
90 for name, port_data in list(ports.items()):
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
91 try:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
92 service = port_data['service']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
93 private = port_data['private']
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
94 int(private)
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
95 except (KeyError, ValueError):
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
96 log.warning(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
97 f"invalid value found for {name!r} port in {app_data['_file_path']}")
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
98 continue
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
99 exposed_port = await async_process.run(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
100 self.docker_compose_path,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
101 "port",
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
102 service,
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
103 str(private),
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
104 path=str(working_dir),
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
105 )
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
106 exposed_port = exposed_port.decode().strip()
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
107 try:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
108 addr, port = exposed_port.split(':')
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
109 int(port)
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
110 except ValueError:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
111 log.warning(
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
112 f"invalid exposed port for {name}, ignoring: {exposed_port!r}")
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
113 del ports[name]
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
114 else:
f44402f8a81f plugin app managed docker: handle Docker application with App Manager
Goffi <goffi@goffi.org>
parents:
diff changeset
115 ports[name] = exposed_port