Skip to content

Commit a3209c4

Browse files
committed
Merge remote-tracking branch 'origin/dev'
2 parents 09bba96 + f3e60f6 commit a3209c4

17 files changed

+176
-149
lines changed

API.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ Output is the raw Docker log.
303303

304304
- POST `/homeassistant/restart`
305305
- POST `/homeassistant/options`
306+
- POST `/homeassistant/check`
306307

307308
```json
308309
{

hassio/addons/addon.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ async def update(self, version=None):
496496

497497
# restore state
498498
if last_state == STATE_STARTED:
499-
return await self.docker.run()
499+
await self.docker.run()
500500
return True
501501

502502
@check_installed

hassio/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ def register_homeassistant(self, dock_homeassistant):
6868
api_hass = APIHomeAssistant(self.config, self.loop, dock_homeassistant)
6969

7070
self.webapp.router.add_get('/homeassistant/info', api_hass.info)
71+
self.webapp.router.add_get('/homeassistant/logs', api_hass.logs)
7172
self.webapp.router.add_post('/homeassistant/options', api_hass.options)
7273
self.webapp.router.add_post('/homeassistant/update', api_hass.update)
7374
self.webapp.router.add_post('/homeassistant/restart', api_hass.restart)
74-
self.webapp.router.add_get('/homeassistant/logs', api_hass.logs)
75+
self.webapp.router.add_post('/homeassistant/check', api_hass.check)
7576

7677
def register_addons(self, addons):
7778
"""Register homeassistant function."""

hassio/api/addons.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -170,19 +170,13 @@ async def install(self, request):
170170

171171
@api_process
172172
def uninstall(self, request):
173-
"""Uninstall addon.
174-
175-
Return a coroutine.
176-
"""
173+
"""Uninstall addon."""
177174
addon = self._extract_addon(request)
178175
return asyncio.shield(addon.uninstall(), loop=self.loop)
179176

180177
@api_process
181178
def start(self, request):
182-
"""Start addon.
183-
184-
Return a coroutine.
185-
"""
179+
"""Start addon."""
186180
addon = self._extract_addon(request)
187181

188182
# check options
@@ -196,10 +190,7 @@ def start(self, request):
196190

197191
@api_process
198192
def stop(self, request):
199-
"""Stop addon.
200-
201-
Return a coroutine.
202-
"""
193+
"""Stop addon."""
203194
addon = self._extract_addon(request)
204195
return asyncio.shield(addon.stop(), loop=self.loop)
205196

@@ -218,19 +209,13 @@ async def update(self, request):
218209

219210
@api_process
220211
def restart(self, request):
221-
"""Restart addon.
222-
223-
Return a coroutine.
224-
"""
212+
"""Restart addon."""
225213
addon = self._extract_addon(request)
226214
return asyncio.shield(addon.restart(), loop=self.loop)
227215

228216
@api_process_raw(CONTENT_TYPE_BINARY)
229217
def logs(self, request):
230-
"""Return logs from addon.
231-
232-
Return a coroutine.
233-
"""
218+
"""Return logs from addon."""
234219
addon = self._extract_addon(request)
235220
return addon.logs()
236221

hassio/api/homeassistant.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,19 @@ async def update(self, request):
7373

7474
@api_process
7575
def restart(self, request):
76-
"""Restart homeassistant.
77-
78-
Return a coroutine.
79-
"""
76+
"""Restart homeassistant."""
8077
return asyncio.shield(self.homeassistant.restart(), loop=self.loop)
8178

8279
@api_process_raw(CONTENT_TYPE_BINARY)
8380
def logs(self, request):
84-
"""Return homeassistant docker logs.
85-
86-
Return a coroutine.
87-
"""
81+
"""Return homeassistant docker logs."""
8882
return self.homeassistant.logs()
83+
84+
@api_process
85+
async def check(self, request):
86+
"""Check config of homeassistant."""
87+
code, message = await self.homeassistant.check_config()
88+
if not code:
89+
raise RuntimeError(message)
90+
91+
return True

hassio/api/host.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,12 @@ async def options(self, request):
5959

6060
@api_process_hostcontrol
6161
def reboot(self, request):
62-
"""Reboot host.
63-
64-
Return a coroutine.
65-
"""
62+
"""Reboot host."""
6663
return self.host_control.reboot()
6764

6865
@api_process_hostcontrol
6966
def shutdown(self, request):
70-
"""Poweroff host.
71-
72-
Return a coroutine.
73-
"""
67+
"""Poweroff host."""
7468
return self.host_control.shutdown()
7569

7670
@api_process_hostcontrol

hassio/api/snapshots.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,7 @@ async def snapshot_partial(self, request):
112112

113113
@api_process
114114
def restore_full(self, request):
115-
"""Full-Restore a snapshot.
116-
117-
Return a coroutine.
118-
"""
115+
"""Full-Restore a snapshot."""
119116
snapshot = self._extract_snapshot(request)
120117
return asyncio.shield(
121118
self.snapshots.do_restore_full(snapshot), loop=self.loop)

hassio/api/supervisor.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,5 @@ async def reload(self, request):
121121

122122
@api_process_raw(CONTENT_TYPE_BINARY)
123123
def logs(self, request):
124-
"""Return supervisor docker logs.
125-
126-
Return a coroutine.
127-
"""
124+
"""Return supervisor docker logs."""
128125
return self.supervisor.logs()

hassio/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Const file for HassIO."""
22
from pathlib import Path
33

4-
HASSIO_VERSION = '0.54'
4+
HASSIO_VERSION = '0.55'
55

66
URL_HASSIO_VERSION = ('https://raw.githubusercontent.com/home-assistant/'
77
'hassio/{}/version.json')

hassio/dock/__init__.py

Lines changed: 49 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import docker
77

8+
from .util import docker_process
89
from ..const import LABEL_VERSION, LABEL_ARCH
910

1011
_LOGGER = logging.getLogger(__name__)
@@ -52,14 +53,10 @@ def process_metadata(self, metadata, force=False):
5253
if need_arch and LABEL_ARCH in metadata['Config']['Labels']:
5354
self.arch = metadata['Config']['Labels'][LABEL_ARCH]
5455

55-
async def install(self, tag):
56+
@docker_process
57+
def install(self, tag):
5658
"""Pull docker image."""
57-
if self._lock.locked():
58-
_LOGGER.error("Can't excute install while a task is in progress")
59-
return False
60-
61-
async with self._lock:
62-
return await self.loop.run_in_executor(None, self._install, tag)
59+
return self.loop.run_in_executor(None, self._install, tag)
6360

6461
def _install(self, tag):
6562
"""Pull docker image.
@@ -80,10 +77,7 @@ def _install(self, tag):
8077
return True
8178

8279
def exists(self):
83-
"""Return True if docker image exists in local repo.
84-
85-
Return a Future.
86-
"""
80+
"""Return True if docker image exists in local repo."""
8781
return self.loop.run_in_executor(None, self._exists)
8882

8983
def _exists(self):
@@ -126,14 +120,10 @@ def _is_running(self):
126120

127121
return True
128122

129-
async def attach(self):
123+
@docker_process
124+
def attach(self):
130125
"""Attach to running docker container."""
131-
if self._lock.locked():
132-
_LOGGER.error("Can't excute attach while a task is in progress")
133-
return False
134-
135-
async with self._lock:
136-
return await self.loop.run_in_executor(None, self._attach)
126+
return self.loop.run_in_executor(None, self._attach)
137127

138128
def _attach(self):
139129
"""Attach to running docker container.
@@ -154,14 +144,10 @@ def _attach(self):
154144

155145
return True
156146

157-
async def run(self):
147+
@docker_process
148+
def run(self):
158149
"""Run docker image."""
159-
if self._lock.locked():
160-
_LOGGER.error("Can't excute run while a task is in progress")
161-
return False
162-
163-
async with self._lock:
164-
return await self.loop.run_in_executor(None, self._run)
150+
return self.loop.run_in_executor(None, self._run)
165151

166152
def _run(self):
167153
"""Run docker image.
@@ -170,15 +156,10 @@ def _run(self):
170156
"""
171157
raise NotImplementedError()
172158

173-
async def stop(self):
159+
@docker_process
160+
def stop(self):
174161
"""Stop/remove docker container."""
175-
if self._lock.locked():
176-
_LOGGER.error("Can't excute stop while a task is in progress")
177-
return False
178-
179-
async with self._lock:
180-
await self.loop.run_in_executor(None, self._stop)
181-
return True
162+
return self.loop.run_in_executor(None, self._stop)
182163

183164
def _stop(self):
184165
"""Stop/remove and remove docker container.
@@ -188,7 +169,7 @@ def _stop(self):
188169
try:
189170
container = self.dock.containers.get(self.name)
190171
except docker.errors.DockerException:
191-
return
172+
return False
192173

193174
if container.status == 'running':
194175
_LOGGER.info("Stop %s docker application", self.image)
@@ -199,14 +180,12 @@ def _stop(self):
199180
_LOGGER.info("Clean %s docker application", self.image)
200181
container.remove(force=True)
201182

202-
async def remove(self):
203-
"""Remove docker images."""
204-
if self._lock.locked():
205-
_LOGGER.error("Can't excute remove while a task is in progress")
206-
return False
183+
return True
207184

208-
async with self._lock:
209-
return await self.loop.run_in_executor(None, self._remove)
185+
@docker_process
186+
def remove(self):
187+
"""Remove docker images."""
188+
return self.loop.run_in_executor(None, self._remove)
210189

211190
def _remove(self):
212191
"""remove docker images.
@@ -235,16 +214,13 @@ def _remove(self):
235214
# clean metadata
236215
self.version = None
237216
self.arch = None
217+
238218
return True
239219

240-
async def update(self, tag):
220+
@docker_process
221+
def update(self, tag):
241222
"""Update a docker image."""
242-
if self._lock.locked():
243-
_LOGGER.error("Can't excute update while a task is in progress")
244-
return False
245-
246-
async with self._lock:
247-
return await self.loop.run_in_executor(None, self._update, tag)
223+
return self.loop.run_in_executor(None, self._update, tag)
248224

249225
def _update(self, tag):
250226
"""Update a docker image.
@@ -258,22 +234,16 @@ def _update(self, tag):
258234
if not self._install(tag):
259235
return False
260236

261-
# container
237+
# stop container & cleanup
262238
self._stop()
263-
264-
# cleanup images
265239
self._cleanup()
266240

267241
return True
268242

269-
async def logs(self):
243+
@docker_process
244+
def logs(self):
270245
"""Return docker logs of container."""
271-
if self._lock.locked():
272-
_LOGGER.error("Can't excute logs while a task is in progress")
273-
return b""
274-
275-
async with self._lock:
276-
return await self.loop.run_in_executor(None, self._logs)
246+
return self.loop.run_in_executor(None, self._logs)
277247

278248
def _logs(self):
279249
"""Return docker logs of container.
@@ -290,14 +260,10 @@ def _logs(self):
290260
except docker.errors.DockerException as err:
291261
_LOGGER.warning("Can't grap logs from %s -> %s", self.image, err)
292262

293-
async def restart(self):
263+
@docker_process
264+
def restart(self):
294265
"""Restart docker container."""
295-
if self._lock.locked():
296-
_LOGGER.error("Can't excute restart while a task is in progress")
297-
return False
298-
299-
async with self._lock:
300-
return await self.loop.run_in_executor(None, self._restart)
266+
return self.loop.run_in_executor(None, self._restart)
301267

302268
def _restart(self):
303269
"""Restart docker container.
@@ -319,14 +285,10 @@ def _restart(self):
319285

320286
return True
321287

322-
async def cleanup(self):
288+
@docker_process
289+
def cleanup(self):
323290
"""Check if old version exists and cleanup."""
324-
if self._lock.locked():
325-
_LOGGER.error("Can't excute cleanup while a task is in progress")
326-
return False
327-
328-
async with self._lock:
329-
await self.loop.run_in_executor(None, self._cleanup)
291+
return self.loop.run_in_executor(None, self._cleanup)
330292

331293
def _cleanup(self):
332294
"""Check if old version exists and cleanup.
@@ -337,7 +299,7 @@ def _cleanup(self):
337299
latest = self.dock.images.get(self.image)
338300
except docker.errors.DockerException:
339301
_LOGGER.warning("Can't find %s for cleanup", self.image)
340-
return
302+
return False
341303

342304
for image in self.dock.images.list(name=self.image):
343305
if latest.id == image.id:
@@ -346,3 +308,17 @@ def _cleanup(self):
346308
with suppress(docker.errors.DockerException):
347309
_LOGGER.info("Cleanup docker images: %s", image.tags)
348310
self.dock.images.remove(image.id, force=True)
311+
312+
return True
313+
314+
@docker_process
315+
def execute_command(self, command):
316+
"""Create a temporary container and run command."""
317+
return self.loop.run_in_executor(None, self._execute_command, command)
318+
319+
def _execute_command(self, command):
320+
"""Create a temporary container and run command.
321+
322+
Need run inside executor.
323+
"""
324+
raise NotImplementedError()

0 commit comments

Comments
 (0)