Merge lp:~larryprice/libertine/container-control-client into lp:libertine
- container-control-client
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Christopher Townsend |
Approved revision: | 421 |
Merged at revision: | 435 |
Proposed branch: | lp:~larryprice/libertine/container-control-client |
Merge into: | lp:libertine |
Prerequisite: | lp:~larryprice/libertine/always-progress |
Diff against target: |
1325 lines (+279/-217) 26 files modified
debian/python3-libertine.install (+1/-1) python/libertine/ChrootContainer.py (+2/-2) python/libertine/ContainerControlClient.py (+5/-1) python/libertine/Libertine.py (+12/-12) python/libertine/LxcContainer.py (+7/-9) python/libertine/LxdContainer.py (+12/-13) python/libertine/service/container.py (+36/-32) python/libertine/service/container_control.py (+5/-54) python/libertine/service/container_control_client.py (+75/-0) python/libertine/service/operations.py (+2/-2) python/libertine/service/task_dispatcher.py (+3/-2) python/libertine/service/tasks/__init__.py (+2/-1) python/libertine/service/tasks/base_task.py (+6/-0) python/libertine/service/tasks/create_task.py (+7/-5) python/libertine/service/tasks/destroy_task.py (+6/-5) python/libertine/service/tasks/install_task.py (+6/-5) python/libertine/service/tasks/remove_task.py (+5/-5) python/libertine/service/tasks/update_task.py (+6/-5) tests/unit/service/tasks/test_create_task.py (+21/-10) tests/unit/service/tasks/test_destroy_task.py (+4/-3) tests/unit/service/tasks/test_install_task.py (+7/-6) tests/unit/service/tasks/test_remove_task.py (+7/-6) tests/unit/service/tasks/test_update_task.py (+4/-3) tests/unit/service/test_container.py (+27/-26) tests/unit/service/test_task_dispatcher.py (+6/-5) tools/libertined (+5/-4) |
To merge this branch: | bzr merge lp:~larryprice/libertine/container-control-client |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christopher Townsend | Approve | ||
Libertine CI Bot | continuous-integration | Approve | |
Review via email: mp+319465@code.launchpad.net |
Commit message
Inject client for accessing ContainerControl within containers.
Description of the change
Inject client for accessing ContainerControl within containers. This allows us to both create a version of the client which accesses d-bus when called from libertine-
Libertine CI Bot (libertine-ci-bot) wrote : | # |
- 420. By Larry Price
-
merge
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:420
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 421. By Larry Price
-
fix install
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:421
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Christopher Townsend (townsend) wrote : | # |
Ok, code looks good and my testing didn't render any regressions.
Preview Diff
1 | === modified file 'debian/python3-libertine.install' |
2 | --- debian/python3-libertine.install 2017-02-15 21:12:37 +0000 |
3 | +++ debian/python3-libertine.install 2017-03-09 17:44:54 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -usr/lib/python*/*/libertine/Client.py |
6 | +usr/lib/python*/*/libertine/ContainerControlClient.py |
7 | usr/lib/python*/*/libertine/ContainersConfig.py |
8 | usr/lib/python*/*/libertine/HostInfo.py |
9 | usr/lib/python*/*/libertine/Libertine.py |
10 | |
11 | === modified file 'python/libertine/ChrootContainer.py' |
12 | --- python/libertine/ChrootContainer.py 2017-02-27 20:47:21 +0000 |
13 | +++ python/libertine/ChrootContainer.py 2017-03-09 17:44:54 +0000 |
14 | @@ -47,8 +47,8 @@ |
15 | A concrete container type implemented using a plain old chroot. |
16 | """ |
17 | |
18 | - def __init__(self, container_id, config): |
19 | - super().__init__(container_id, 'chroot', config) |
20 | + def __init__(self, container_id, config, service): |
21 | + super().__init__(container_id, 'chroot', config, service) |
22 | # FIXME: Disabling seccomp is a temporary measure until we fully understand why we need |
23 | # it or figure out when we need it. |
24 | os.environ['PROOT_NO_SECCOMP'] = '1' |
25 | |
26 | === renamed file 'python/libertine/Client.py' => 'python/libertine/ContainerControlClient.py' |
27 | --- python/libertine/Client.py 2017-03-07 18:38:05 +0000 |
28 | +++ python/libertine/ContainerControlClient.py 2017-03-09 17:44:54 +0000 |
29 | @@ -19,7 +19,11 @@ |
30 | from . import utils |
31 | |
32 | |
33 | -class Client(object): |
34 | +class ContainerControlClient(object): |
35 | + """ |
36 | + A client for ContainerControl using D-BUS, to be used in clients |
37 | + external to the libertine service. |
38 | + """ |
39 | def __init__(self): |
40 | self._get_manager() |
41 | |
42 | |
43 | === modified file 'python/libertine/Libertine.py' |
44 | --- python/libertine/Libertine.py 2017-03-07 21:36:57 +0000 |
45 | +++ python/libertine/Libertine.py 2017-03-09 17:44:54 +0000 |
46 | @@ -17,7 +17,7 @@ |
47 | import os |
48 | import shutil |
49 | |
50 | -from . import utils |
51 | +from . import utils, ContainerControlClient |
52 | from libertine.ContainersConfig import ContainersConfig |
53 | from libertine.HostInfo import HostInfo |
54 | |
55 | @@ -79,10 +79,11 @@ |
56 | |
57 | :param container_id: The machine-readable container name. |
58 | """ |
59 | - def __init__(self, container_id, container_type, config): |
60 | + def __init__(self, container_id, container_type, config, service): |
61 | self.container_type = container_type |
62 | self.container_id = container_id |
63 | self._config = config |
64 | + self._service = service |
65 | self._app_name = '' |
66 | self._pid = 0 |
67 | self.root_path = utils.get_libertine_container_rootfs_path(self.container_id) |
68 | @@ -332,8 +333,8 @@ |
69 | """ |
70 | A concrete mock container type. Used for unit testing. |
71 | """ |
72 | - def __init__(self, container_id, config): |
73 | - super().__init__(container_id, 'mock', config) |
74 | + def __init__(self, container_id, config, service): |
75 | + super().__init__(container_id, 'mock', config, service) |
76 | |
77 | def create_libertine_container(self, password=None, multiarch=False): |
78 | return True |
79 | @@ -386,7 +387,7 @@ |
80 | A sandbox for DEB-packaged X11-based applications. |
81 | """ |
82 | |
83 | - def __init__(self, container_id, containers_config=None): |
84 | + def __init__(self, container_id, containers_config=None, service=None): |
85 | """ |
86 | Initializes the container object. |
87 | |
88 | @@ -394,23 +395,22 @@ |
89 | """ |
90 | super().__init__() |
91 | |
92 | - if containers_config is None: |
93 | - containers_config = ContainersConfig() |
94 | - self.containers_config = containers_config |
95 | + self.containers_config = containers_config or ContainersConfig() |
96 | + service = service or ContainerControlClient.ContainerControlClient() |
97 | |
98 | container_type = self.containers_config.get_container_type(container_id) |
99 | |
100 | if container_type == "lxc": |
101 | from libertine.LxcContainer import LibertineLXC |
102 | - self.container = LibertineLXC(container_id, self.containers_config) |
103 | + self.container = LibertineLXC(container_id, self.containers_config, service) |
104 | elif container_type == "lxd": |
105 | from libertine.LxdContainer import LibertineLXD |
106 | - self.container = LibertineLXD(container_id, self.containers_config) |
107 | + self.container = LibertineLXD(container_id, self.containers_config, service) |
108 | elif container_type == "chroot": |
109 | from libertine.ChrootContainer import LibertineChroot |
110 | - self.container = LibertineChroot(container_id, self.containers_config) |
111 | + self.container = LibertineChroot(container_id, self.containers_config, service) |
112 | elif container_type == "mock": |
113 | - self.container = LibertineMock(container_id, self.containers_config) |
114 | + self.container = LibertineMock(container_id, self.containers_config, service) |
115 | else: |
116 | raise RuntimeError("Unsupported container type %s" % container_type) |
117 | |
118 | |
119 | === modified file 'python/libertine/LxcContainer.py' |
120 | --- python/libertine/LxcContainer.py 2017-03-03 15:34:16 +0000 |
121 | +++ python/libertine/LxcContainer.py 2017-03-09 17:44:54 +0000 |
122 | @@ -23,7 +23,7 @@ |
123 | import tempfile |
124 | |
125 | from .Libertine import BaseContainer |
126 | -from . import utils, HostInfo, Client |
127 | +from . import utils, HostInfo |
128 | |
129 | |
130 | home_path = os.environ['HOME'] |
131 | @@ -157,14 +157,12 @@ |
132 | A concrete container type implemented using an LXC container. |
133 | """ |
134 | |
135 | - def __init__(self, container_id, config): |
136 | - super().__init__(container_id, 'lxc', config) |
137 | + def __init__(self, container_id, config, service): |
138 | + super().__init__(container_id, 'lxc', config, service) |
139 | self.container = lxc_container(container_id) |
140 | self.host_info = HostInfo.HostInfo() |
141 | self._freeze_on_stop = config.get_freeze_on_stop(self.container_id) |
142 | |
143 | - self._manager = Client.Client() |
144 | - |
145 | def _setup_pulse(self): |
146 | pulse_socket_path = os.path.join(utils.get_libertine_runtime_dir(), 'pulse_socket') |
147 | |
148 | @@ -213,7 +211,7 @@ |
149 | return fd.read().strip('\n') != self.host_info.get_host_timezone() |
150 | |
151 | def start_container(self): |
152 | - if not self._manager.container_operation_start(self.container_id): |
153 | + if not self._service.container_operation_start(self.container_id): |
154 | return False |
155 | |
156 | if self.container.state == 'RUNNING': |
157 | @@ -236,11 +234,11 @@ |
158 | stopped = False |
159 | self._config.refresh_database() |
160 | |
161 | - if self._manager.container_operation_finished(self.container_id, self._app_name, self._pid): |
162 | + if self._service.container_operation_finished(self.container_id, self._app_name, self._pid): |
163 | self._config.update_container_install_status(self.container_id, self._get_stop_type_string(self._freeze_on_stop)) |
164 | |
165 | if lxc_stop(self.container, self._freeze_on_stop): |
166 | - stopped = self._manager.container_stopped(self.container_id) |
167 | + stopped = self._service.container_stopped(self.container_id) |
168 | |
169 | self._config.update_container_install_status(self.container_id, self.container.state.lower()) |
170 | |
171 | @@ -397,7 +395,7 @@ |
172 | os.environ.update(environ) |
173 | |
174 | if not self.start_container(): |
175 | - self._manager.container_stopped(self.container_id) |
176 | + self._service.container_stopped(self.container_id) |
177 | return |
178 | |
179 | self._app_name = app_exec_line[0] |
180 | |
181 | === modified file 'python/libertine/LxdContainer.py' |
182 | --- python/libertine/LxdContainer.py 2017-03-03 15:34:16 +0000 |
183 | +++ python/libertine/LxdContainer.py 2017-03-09 17:44:54 +0000 |
184 | @@ -22,7 +22,7 @@ |
185 | import subprocess |
186 | import time |
187 | |
188 | -from . import Libertine, utils, HostInfo, Client |
189 | +from . import Libertine, utils, HostInfo |
190 | |
191 | |
192 | def _get_devices_map(): |
193 | @@ -383,8 +383,8 @@ |
194 | |
195 | |
196 | class LibertineLXD(Libertine.BaseContainer): |
197 | - def __init__(self, name, config): |
198 | - super().__init__(name, 'lxd', config) |
199 | + def __init__(self, name, config, service): |
200 | + super().__init__(name, 'lxd', config, service) |
201 | self._host_info = HostInfo.HostInfo() |
202 | self._container = None |
203 | self._freeze_on_stop = config.get_freeze_on_stop(self.container_id) |
204 | @@ -392,15 +392,14 @@ |
205 | if not _setup_lxd(): |
206 | raise Exception("Failed to setup lxd.") |
207 | |
208 | - self._client = pylxd.Client() |
209 | - self._manager = Client.Client() |
210 | + self._lxd_client = pylxd.Client() |
211 | |
212 | def create_libertine_container(self, password=None, multiarch=False): |
213 | if self._try_get_container(): |
214 | utils.get_logger().error("Container already exists") |
215 | return False |
216 | |
217 | - update_libertine_profile(self._client) |
218 | + update_libertine_profile(self._lxd_client) |
219 | |
220 | utils.get_logger().info("Creating container '%s' with distro '%s'" % (self.container_id, self.installed_release)) |
221 | create = subprocess.Popen(shlex.split('lxc launch ubuntu-daily:{distro} {id} --profile ' |
222 | @@ -504,7 +503,7 @@ |
223 | if not self._try_get_container(): |
224 | return False |
225 | |
226 | - if not self._manager.container_operation_start(self.container_id): |
227 | + if not self._service.container_operation_start(self.container_id): |
228 | return False |
229 | |
230 | if self._container.status == 'Running': |
231 | @@ -513,12 +512,12 @@ |
232 | requires_remount = self._container.status == 'Stopped' |
233 | |
234 | if requires_remount: |
235 | - update_libertine_profile(self._client) |
236 | + update_libertine_profile(self._lxd_client) |
237 | update_bind_mounts(self._container, self._config, home) |
238 | |
239 | self._config.update_container_install_status(self.container_id, "starting") |
240 | if not lxd_start(self._container): |
241 | - self._manager.container_stopped() |
242 | + self._service.container_stopped() |
243 | self._config.update_container_install_status(self.container_id, self._container.status.lower()) |
244 | return False |
245 | |
246 | @@ -539,11 +538,11 @@ |
247 | stopped = False |
248 | self._config.refresh_database() |
249 | |
250 | - if self._manager.container_operation_finished(self.container_id, self._app_name, self._pid): |
251 | + if self._service.container_operation_finished(self.container_id, self._app_name, self._pid): |
252 | self._config.update_container_install_status(self.container_id, self._get_stop_type_string(self._freeze_on_stop)) |
253 | - |
254 | + |
255 | if lxd_stop(self._container, freeze_on_stop=self._freeze_on_stop): |
256 | - stopped = self._manager.container_stopped(self.container_id) |
257 | + stopped = self._service.container_stopped(self.container_id) |
258 | |
259 | self._config.update_container_install_status(self.container_id, self._container.status.lower()) |
260 | |
261 | @@ -598,6 +597,6 @@ |
262 | |
263 | def _try_get_container(self): |
264 | if self._container is None: |
265 | - self._container = lxd_container(self._client, self.container_id) |
266 | + self._container = lxd_container(self._lxd_client, self.container_id) |
267 | |
268 | return self._container is not None |
269 | |
270 | === modified file 'python/libertine/service/container.py' |
271 | --- python/libertine/service/container.py 2017-03-07 18:38:05 +0000 |
272 | +++ python/libertine/service/container.py 2017-03-09 17:44:54 +0000 |
273 | @@ -22,11 +22,13 @@ |
274 | |
275 | |
276 | class Container(object): |
277 | - def __init__(self, container_id, config, monitor, callback): |
278 | + def __init__(self, container_id, config, monitor, client, callback): |
279 | self._id = container_id |
280 | + self._config = config |
281 | self._monitor = monitor |
282 | + self._client = client |
283 | self._callback = callback |
284 | - self._config = config |
285 | + |
286 | self._lock = Lock() |
287 | self._tasks = [] |
288 | |
289 | @@ -53,31 +55,6 @@ |
290 | def tasks(self): |
291 | return [task.id for task in self._tasks if task.running] |
292 | |
293 | - def search(self, query): |
294 | - utils.get_logger().debug("search container '%s' for package '%s'" % (self.id, query)) |
295 | - |
296 | - if utils.is_snap_environment(): |
297 | - raise Exception("This operation is not currently supported within the snap") |
298 | - |
299 | - task = SearchTask(self.id, self._cache, query, self._monitor, self._cleanup_task) |
300 | - self._tasks.append(task) |
301 | - task.start() |
302 | - |
303 | - return task.id |
304 | - |
305 | - def app_info(self, package_name): |
306 | - utils.get_logger().debug("get info for package '%s' in container '%s'" % (package_name, self.id)) |
307 | - |
308 | - if utils.is_snap_environment(): |
309 | - raise Exception("This operation is not currently supported within the snap") |
310 | - |
311 | - related_task_ids = [t.id for t in self._tasks if t.package == package_name and t.running] |
312 | - task = AppInfoTask(self.id, self._cache, package_name, related_task_ids, self._config, self._monitor, self._cleanup_task) |
313 | - |
314 | - self._tasks.append(task) |
315 | - task.start() |
316 | - return task.id |
317 | - |
318 | def install(self, package_name): |
319 | utils.get_logger().debug("Install package '%s' from container '%s'" % (package_name, self.id)) |
320 | |
321 | @@ -86,7 +63,7 @@ |
322 | utils.get_logger().debug("Install already in progress for '%s':'%s'" % (package_name, self.id)) |
323 | return tasks[0].id |
324 | |
325 | - task = InstallTask(package_name, self.id, self._config, self._lock, self._monitor, self._cleanup_task) |
326 | + task = InstallTask(package_name, self.id, self._config, self._lock, self._monitor, self._client, self._cleanup_task) |
327 | self._tasks.append(task) |
328 | task.start() |
329 | return task.id |
330 | @@ -99,7 +76,7 @@ |
331 | utils.get_logger().debug("Remove already in progress for '%s':'%s'" % (package_name, self.id)) |
332 | return tasks[0].id |
333 | |
334 | - task = RemoveTask(package_name, self.id, self._config, self._lock, self._monitor, self._cleanup_task) |
335 | + task = RemoveTask(package_name, self.id, self._config, self._lock, self._monitor, self._client, self._cleanup_task) |
336 | self._tasks.append(task) |
337 | task.start() |
338 | return task.id |
339 | @@ -113,7 +90,7 @@ |
340 | return tasks[0].id |
341 | |
342 | task = CreateTask(self.id, container_name, distro, container_type, enable_multiarch, |
343 | - self._config, self._lock, self._monitor, self._cleanup_task) |
344 | + self._config, self._lock, self._monitor, self._client, self._cleanup_task) |
345 | self._tasks.append(task) |
346 | task.start() |
347 | return task.id |
348 | @@ -126,7 +103,7 @@ |
349 | utils.get_logger().debug("Destroy already in progress for '%s'" % self.id) |
350 | return tasks[0].id |
351 | |
352 | - task = DestroyTask(self.id, self._config, self._lock, self._monitor, self._cleanup_task) |
353 | + task = DestroyTask(self.id, self._config, self._lock, self._monitor, self._client, self._cleanup_task) |
354 | self._tasks.append(task) |
355 | task.start() |
356 | return task.id |
357 | @@ -139,11 +116,13 @@ |
358 | utils.get_logger().debug("Update already in progress for '%s'" % self.id) |
359 | return tasks[0].id |
360 | |
361 | - task = UpdateTask(self.id, self._config, self._lock, self._monitor, self._cleanup_task) |
362 | + task = UpdateTask(self.id, self._config, self._lock, self._monitor, self._client, self._cleanup_task) |
363 | self._tasks.append(task) |
364 | task.start() |
365 | return task.id |
366 | |
367 | + # Tasks which don't require starting/stopping the container |
368 | + |
369 | def list_app_ids(self): |
370 | utils.get_logger().debug("List all app ids in container '%s'" % self.id) |
371 | |
372 | @@ -152,3 +131,28 @@ |
373 | self._tasks.append(task) |
374 | task.start() |
375 | return task.id |
376 | + |
377 | + def search(self, query): |
378 | + utils.get_logger().debug("search container '%s' for package '%s'" % (self.id, query)) |
379 | + |
380 | + if utils.is_snap_environment(): |
381 | + raise Exception("This operation is not currently supported within the snap") |
382 | + |
383 | + task = SearchTask(self.id, self._cache, query, self._monitor, self._cleanup_task) |
384 | + self._tasks.append(task) |
385 | + task.start() |
386 | + |
387 | + return task.id |
388 | + |
389 | + def app_info(self, package_name): |
390 | + utils.get_logger().debug("get info for package '%s' in container '%s'" % (package_name, self.id)) |
391 | + |
392 | + if utils.is_snap_environment(): |
393 | + raise Exception("This operation is not currently supported within the snap") |
394 | + |
395 | + related_task_ids = [t.id for t in self._tasks if t.package == package_name and t.running] |
396 | + task = AppInfoTask(self.id, self._cache, package_name, related_task_ids, self._config, self._monitor, self._cleanup_task) |
397 | + |
398 | + self._tasks.append(task) |
399 | + task.start() |
400 | + return task.id |
401 | |
402 | === modified file 'python/libertine/service/container_control.py' |
403 | --- python/libertine/service/container_control.py 2017-03-06 19:50:12 +0000 |
404 | +++ python/libertine/service/container_control.py 2017-03-09 17:44:54 +0000 |
405 | @@ -14,82 +14,33 @@ |
406 | |
407 | |
408 | import dbus |
409 | -import libertine.ContainersConfig |
410 | -import psutil |
411 | |
412 | from . import constants |
413 | -from collections import Counter |
414 | from libertine import utils |
415 | |
416 | |
417 | class ContainerControl(dbus.service.Object): |
418 | - def __init__(self, connection): |
419 | - self._get_running_apps_per_container() |
420 | - |
421 | + def __init__(self, connection, client): |
422 | dbus.service.Object.__init__(self, conn=connection, object_path=constants.CONTAINER_CONTROL_OBJECT) |
423 | - |
424 | - def _get_running_apps_per_container(self): |
425 | - self._invalid_apps = dict() |
426 | - self._operations = Counter() |
427 | - config = libertine.ContainersConfig.ContainersConfig() |
428 | - |
429 | - for container in config.get_containers(): |
430 | - running_apps = config.get_running_apps(container).copy() |
431 | - |
432 | - for app in running_apps: |
433 | - try: |
434 | - proc = psutil.Process(app['pid']) |
435 | - if app['appExecName'] in proc.cmdline(): |
436 | - self._operations[container] += 1 |
437 | - else: |
438 | - raise |
439 | - except: |
440 | - utils.get_logger().error("Container app {} is not valid.".format(app['appExecName'])) |
441 | - if container not in self._invalid_apps: |
442 | - self._invalid_apps[container] = [{app['appExecName'], app['pid']}] |
443 | - else: |
444 | - self._invalid_apps[container].append({app['appExecName'], app['pid']}) |
445 | - config.delete_running_app(container, app) |
446 | - continue |
447 | - |
448 | + self._client = client |
449 | |
450 | @dbus.service.method(constants.CONTAINER_CONTROL_INTERFACE, |
451 | in_signature='s', |
452 | out_signature='b') |
453 | def start(self, container): |
454 | utils.get_logger().debug("start({})".format(container)) |
455 | - if self._operations[container] == -1: |
456 | - return False |
457 | - |
458 | - self._operations[container] += 1 |
459 | - |
460 | - return True |
461 | - |
462 | + return self._client.container_operation_start(container) |
463 | |
464 | @dbus.service.method(constants.CONTAINER_CONTROL_INTERFACE, |
465 | in_signature='ssi', |
466 | out_signature='b') |
467 | def finished(self, container, app_name, pid): |
468 | utils.get_logger().debug("finished({})".format(container)) |
469 | - |
470 | - if container in self._invalid_apps and {app_name, pid} in self._invalid_apps[container]: |
471 | - self._invalid_apps[container].remove({app_name, pid}) |
472 | - if not self._invalid_apps[container]: |
473 | - del self._invalid_apps[container] |
474 | - else: |
475 | - self._operations[container] -= 1 |
476 | - |
477 | - if self._operations[container] == 0: |
478 | - self._operations[container] = -1 |
479 | - return True |
480 | - |
481 | - return False |
482 | + return self._client.container_operation_finished(container, app_name, pid) |
483 | |
484 | @dbus.service.method(constants.CONTAINER_CONTROL_INTERFACE, |
485 | in_signature='s', |
486 | out_signature='b') |
487 | def stopped(self, container): |
488 | utils.get_logger().debug("stopped({})".format(container)) |
489 | - |
490 | - del self._operations[container] |
491 | - return True |
492 | + return self._client.container_operation_stopped(container) |
493 | |
494 | === added file 'python/libertine/service/container_control_client.py' |
495 | --- python/libertine/service/container_control_client.py 1970-01-01 00:00:00 +0000 |
496 | +++ python/libertine/service/container_control_client.py 2017-03-09 17:44:54 +0000 |
497 | @@ -0,0 +1,75 @@ |
498 | +# Copyright 2017 Canonical Ltd. |
499 | +# |
500 | +# This program is free software: you can redistribute it and/or modify |
501 | +# it under the terms of the GNU General Public License as published by |
502 | +# the Free Software Foundation; version 3 of the License. |
503 | +# |
504 | +# This program is distributed in the hope that it will be useful, |
505 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
506 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
507 | +# GNU General Public License for more details. |
508 | +# |
509 | +# You should have received a copy of the GNU General Public License |
510 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
511 | + |
512 | + |
513 | +import libertine.ContainersConfig |
514 | +import psutil |
515 | + |
516 | +from collections import Counter |
517 | +from libertine import utils |
518 | + |
519 | + |
520 | +class ContainerControlClient(object): |
521 | + def __init__(self): |
522 | + self._get_running_apps_per_container() |
523 | + |
524 | + def _get_running_apps_per_container(self): |
525 | + self._invalid_apps = dict() |
526 | + self._operations = Counter() |
527 | + config = libertine.ContainersConfig.ContainersConfig() |
528 | + |
529 | + for container in config.get_containers(): |
530 | + running_apps = config.get_running_apps(container).copy() |
531 | + |
532 | + for app in running_apps: |
533 | + try: |
534 | + proc = psutil.Process(app['pid']) |
535 | + if app['appExecName'] in proc.cmdline(): |
536 | + self._operations[container] += 1 |
537 | + else: |
538 | + raise |
539 | + except: |
540 | + utils.get_logger().error("Container app {} is not valid.".format(app['appExecName'])) |
541 | + if container not in self._invalid_apps: |
542 | + self._invalid_apps[container] = [{app['appExecName'], app['pid']}] |
543 | + else: |
544 | + self._invalid_apps[container].append({app['appExecName'], app['pid']}) |
545 | + config.delete_running_app(container, app) |
546 | + continue |
547 | + |
548 | + def container_operation_start(self, container): |
549 | + if self._operations[container] == -1: |
550 | + return False |
551 | + |
552 | + self._operations[container] += 1 |
553 | + |
554 | + return True |
555 | + |
556 | + def container_operation_finished(self, container, app_name, pid): |
557 | + if container in self._invalid_apps and {app_name, pid} in self._invalid_apps[container]: |
558 | + self._invalid_apps[container].remove({app_name, pid}) |
559 | + if not self._invalid_apps[container]: |
560 | + del self._invalid_apps[container] |
561 | + else: |
562 | + self._operations[container] -= 1 |
563 | + |
564 | + if self._operations[container] == 0: |
565 | + self._operations[container] = -1 |
566 | + return True |
567 | + |
568 | + return False |
569 | + |
570 | + def container_stopped(self, container): |
571 | + del self._operations[container] |
572 | + return True |
573 | |
574 | === modified file 'python/libertine/service/operations.py' |
575 | --- python/libertine/service/operations.py 2017-03-07 18:38:05 +0000 |
576 | +++ python/libertine/service/operations.py 2017-03-09 17:44:54 +0000 |
577 | @@ -21,10 +21,10 @@ |
578 | |
579 | |
580 | class Operations(dbus.service.Object): |
581 | - def __init__(self, bus_name): |
582 | + def __init__(self, bus_name, client): |
583 | super().__init__(bus_name, constants.OPERATIONS_OBJECT) |
584 | |
585 | - self._dispatcher = task_dispatcher.TaskDispatcher(operations_monitor.OperationsMonitor(self.connection)) |
586 | + self._dispatcher = task_dispatcher.TaskDispatcher(operations_monitor.OperationsMonitor(self.connection), client) |
587 | |
588 | # Information |
589 | |
590 | |
591 | === modified file 'python/libertine/service/task_dispatcher.py' |
592 | --- python/libertine/service/task_dispatcher.py 2017-03-06 19:50:12 +0000 |
593 | +++ python/libertine/service/task_dispatcher.py 2017-03-09 17:44:54 +0000 |
594 | @@ -30,8 +30,9 @@ |
595 | |
596 | |
597 | class TaskDispatcher(object): |
598 | - def __init__(self, monitor): |
599 | + def __init__(self, monitor, client): |
600 | self._monitor = monitor |
601 | + self._client = client |
602 | self._config = libertine.ContainersConfig.ContainersConfig() |
603 | self._containerless_tasks = [] |
604 | self._tasks = [] |
605 | @@ -55,7 +56,7 @@ |
606 | utils.get_logger().debug("using existing container '%s'" % container_id) |
607 | return container |
608 | |
609 | - container = Container(container_id, self._config, self._monitor, self._cleanup_container) |
610 | + container = Container(container_id, self._config, self._monitor, self._client, self._cleanup_container) |
611 | self._containers.append(container) |
612 | |
613 | return container |
614 | |
615 | === modified file 'python/libertine/service/tasks/__init__.py' |
616 | --- python/libertine/service/tasks/__init__.py 2017-02-07 12:35:48 +0000 |
617 | +++ python/libertine/service/tasks/__init__.py 2017-03-09 17:44:54 +0000 |
618 | @@ -12,7 +12,7 @@ |
619 | # You should have received a copy of the GNU General Public License along |
620 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
621 | |
622 | -from .base_task import BaseTask |
623 | +from .base_task import BaseTask, ContainerBaseTask |
624 | from .app_info_task import AppInfoTask |
625 | from .container_info_task import ContainerInfoTask |
626 | from .create_task import CreateTask |
627 | @@ -27,6 +27,7 @@ |
628 | __all__ = [ |
629 | 'AppInfoTask', |
630 | 'BaseTask', |
631 | + 'ContainerBaseTask', |
632 | 'ContainerInfoTask', |
633 | 'CreateTask', |
634 | 'DestroyTask', |
635 | |
636 | === modified file 'python/libertine/service/tasks/base_task.py' |
637 | --- python/libertine/service/tasks/base_task.py 2017-03-06 19:50:12 +0000 |
638 | +++ python/libertine/service/tasks/base_task.py 2017-03-09 17:44:54 +0000 |
639 | @@ -94,3 +94,9 @@ |
640 | |
641 | def _error(self, message): |
642 | self._monitor.error(self._operation_id, message) |
643 | + |
644 | + |
645 | +class ContainerBaseTask(BaseTask): |
646 | + def __init__(self, lock, container_id, config, monitor, client, callback): |
647 | + super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
648 | + self._client = client |
649 | |
650 | === modified file 'python/libertine/service/tasks/create_task.py' |
651 | --- python/libertine/service/tasks/create_task.py 2017-03-07 18:38:05 +0000 |
652 | +++ python/libertine/service/tasks/create_task.py 2017-03-09 17:44:54 +0000 |
653 | @@ -13,14 +13,16 @@ |
654 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
655 | |
656 | |
657 | -from .base_task import BaseTask |
658 | +from .base_task import ContainerBaseTask |
659 | from libertine import LibertineContainer, utils |
660 | from libertine.HostInfo import HostInfo |
661 | |
662 | |
663 | -class CreateTask(BaseTask): |
664 | - def __init__(self, container_id, container_name, distro, container_type, enable_multiarch, config, lock, monitor, callback): |
665 | - super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
666 | +class CreateTask(ContainerBaseTask): |
667 | + def __init__(self, container_id, container_name, distro, container_type, enable_multiarch, |
668 | + config, lock, monitor, client, callback): |
669 | + super().__init__(lock=lock, container_id=container_id, config=config, |
670 | + monitor=monitor, client=client, callback=callback) |
671 | self._name = container_name |
672 | self._distro = distro |
673 | self._type = container_type |
674 | @@ -30,7 +32,7 @@ |
675 | utils.get_logger().debug("Creating container '%s'" % self._container) |
676 | |
677 | try: |
678 | - container = LibertineContainer(self._container, self._config) |
679 | + container = LibertineContainer(self._container, self._config, self._client) |
680 | |
681 | if not container.create_libertine_container(password='', multiarch=self._multiarch): |
682 | self._config.delete_container(self._container) |
683 | |
684 | === modified file 'python/libertine/service/tasks/destroy_task.py' |
685 | --- python/libertine/service/tasks/destroy_task.py 2017-03-07 18:38:05 +0000 |
686 | +++ python/libertine/service/tasks/destroy_task.py 2017-03-09 17:44:54 +0000 |
687 | @@ -13,18 +13,19 @@ |
688 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
689 | |
690 | |
691 | -from .base_task import BaseTask |
692 | +from .base_task import ContainerBaseTask |
693 | from libertine import LibertineContainer, utils |
694 | |
695 | |
696 | -class DestroyTask(BaseTask): |
697 | - def __init__(self, container_id, config, lock, monitor, callback): |
698 | - super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
699 | +class DestroyTask(ContainerBaseTask): |
700 | + def __init__(self, container_id, config, lock, monitor, client, callback): |
701 | + super().__init__(lock=lock, container_id=container_id, config=config, |
702 | + monitor=monitor, client=client, callback=callback) |
703 | |
704 | def _run(self): |
705 | utils.get_logger().debug("Destroying container '%s'" % self._container) |
706 | |
707 | - container = LibertineContainer(self._container, self._config) |
708 | + container = LibertineContainer(self._container, self._config, self._client) |
709 | if not container.destroy_libertine_container(): |
710 | self._error("Destroying container '%s' failed" % self._container) |
711 | self._config.update_container_install_status(self._container, "ready") |
712 | |
713 | === modified file 'python/libertine/service/tasks/install_task.py' |
714 | --- python/libertine/service/tasks/install_task.py 2017-03-07 18:38:05 +0000 |
715 | +++ python/libertine/service/tasks/install_task.py 2017-03-09 17:44:54 +0000 |
716 | @@ -13,13 +13,14 @@ |
717 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
718 | |
719 | |
720 | -from .base_task import BaseTask |
721 | +from .base_task import ContainerBaseTask |
722 | from libertine import LibertineContainer, utils |
723 | |
724 | |
725 | -class InstallTask(BaseTask): |
726 | - def __init__(self, package_name, container_id, config, lock, monitor, callback): |
727 | - super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
728 | +class InstallTask(ContainerBaseTask): |
729 | + def __init__(self, package_name, container_id, config, lock, monitor, client, callback): |
730 | + super().__init__(lock=lock, container_id=container_id, config=config, |
731 | + monitor=monitor, client=client, callback=callback) |
732 | self._package = package_name |
733 | |
734 | def matches(self, package, klass): |
735 | @@ -31,7 +32,7 @@ |
736 | |
737 | def _run(self): |
738 | utils.get_logger().debug("Installing package '%s'" % self._package) |
739 | - container = LibertineContainer(self._container, self._config) |
740 | + container = LibertineContainer(self._container, self._config, self._client) |
741 | if container.install_package(self._package): |
742 | self._config.update_package_install_status(self._container, self._package, "installed") |
743 | else: |
744 | |
745 | === modified file 'python/libertine/service/tasks/remove_task.py' |
746 | --- python/libertine/service/tasks/remove_task.py 2017-03-07 18:38:05 +0000 |
747 | +++ python/libertine/service/tasks/remove_task.py 2017-03-09 17:44:54 +0000 |
748 | @@ -13,13 +13,13 @@ |
749 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
750 | |
751 | |
752 | -from .base_task import BaseTask |
753 | +from .base_task import ContainerBaseTask |
754 | from libertine import LibertineContainer, utils |
755 | |
756 | |
757 | -class RemoveTask(BaseTask): |
758 | - def __init__(self, package_name, container_id, config, lock, monitor, callback): |
759 | - super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
760 | +class RemoveTask(ContainerBaseTask): |
761 | + def __init__(self, package_name, container_id, config, lock, monitor, client, callback): |
762 | + super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, client=client, callback=callback) |
763 | self._package = package_name |
764 | |
765 | def matches(self, package, klass): |
766 | @@ -31,7 +31,7 @@ |
767 | |
768 | def _run(self): |
769 | utils.get_logger().debug("Removing package '%s'" % self._package) |
770 | - container = LibertineContainer(self._container, self._config) |
771 | + container = LibertineContainer(self._container, self._config, self._client) |
772 | if container.remove_package(self._package): |
773 | self._config.delete_package(self._container, self._package) |
774 | else: |
775 | |
776 | === modified file 'python/libertine/service/tasks/update_task.py' |
777 | --- python/libertine/service/tasks/update_task.py 2017-03-07 18:38:05 +0000 |
778 | +++ python/libertine/service/tasks/update_task.py 2017-03-09 17:44:54 +0000 |
779 | @@ -13,17 +13,18 @@ |
780 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
781 | |
782 | |
783 | -from .base_task import BaseTask |
784 | +from .base_task import ContainerBaseTask |
785 | from libertine import LibertineContainer, utils |
786 | |
787 | |
788 | -class UpdateTask(BaseTask): |
789 | - def __init__(self, container_id, config, lock, monitor, callback): |
790 | - super().__init__(lock=lock, container_id=container_id, config=config, monitor=monitor, callback=callback) |
791 | +class UpdateTask(ContainerBaseTask): |
792 | + def __init__(self, container_id, config, lock, monitor, client, callback): |
793 | + super().__init__(lock=lock, container_id=container_id, config=config, |
794 | + monitor=monitor, client=client, callback=callback) |
795 | |
796 | def _run(self): |
797 | utils.get_logger().debug("Updating container '%s'" % self._container) |
798 | - container = LibertineContainer(self._container, self._config) |
799 | + container = LibertineContainer(self._container, self._config, self._client) |
800 | self._config.update_container_install_status(self._container, "updating") |
801 | if not container.update_libertine_container(): |
802 | self._error("Failed to update container '%s'" % self._container) |
803 | |
804 | === modified file 'tests/unit/service/tasks/test_create_task.py' |
805 | --- tests/unit/service/tasks/test_create_task.py 2017-03-07 19:41:49 +0000 |
806 | +++ tests/unit/service/tasks/test_create_task.py 2017-03-09 17:44:54 +0000 |
807 | @@ -23,6 +23,7 @@ |
808 | def setUp(self): |
809 | self.config = unittest.mock.create_autospec(ContainersConfig) |
810 | self.lock = unittest.mock.MagicMock() |
811 | + self.client = unittest.mock.Mock() |
812 | self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
813 | |
814 | self.monitor.new_operation.return_value = "/com/canonical/libertine/Service/Download/123456" |
815 | @@ -34,7 +35,8 @@ |
816 | def test_success_creates_lxc_container(self): |
817 | self.config.container_exists.return_value = False |
818 | self.monitor.done.return_value = False |
819 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
820 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, |
821 | + self.config, self.lock, self.monitor, self.client, self.callback) |
822 | task._instant_callback = True |
823 | |
824 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
825 | @@ -56,7 +58,8 @@ |
826 | def test_success_creates_chroot_container(self): |
827 | self.config.container_exists.return_value = False |
828 | self.monitor.done.return_value = False |
829 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'chroot', False, self.config, self.lock, self.monitor, self.callback) |
830 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'chroot', False, |
831 | + self.config, self.lock, self.monitor, self.client, self.callback) |
832 | task._instant_callback = True |
833 | |
834 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
835 | @@ -76,7 +79,8 @@ |
836 | |
837 | def test_container_runtime_error_sends_error(self): |
838 | self.config.container_exists.return_value = False |
839 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
840 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, |
841 | + self.config, self.lock, self.monitor, self.client, self.callback) |
842 | task._instant_callback = True |
843 | |
844 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
845 | @@ -97,7 +101,8 @@ |
846 | |
847 | def test_failed_container_exists_sends_error(self): |
848 | self.config.container_exists.return_value = True |
849 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
850 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, |
851 | + self.config, self.lock, self.monitor, self.client, self.callback) |
852 | task._instant_callback = True |
853 | task.start().join() |
854 | |
855 | @@ -108,7 +113,8 @@ |
856 | self.config.container_exists.return_value = False |
857 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
858 | MockHostInfo.return_value.is_distro_valid.return_value = False |
859 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'vesty', 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
860 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'vesty', 'lxc', False, |
861 | + self.config, self.lock, self.monitor, self.client, self.callback) |
862 | task._instant_callback = True |
863 | task.start().join() |
864 | |
865 | @@ -120,7 +126,8 @@ |
866 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
867 | MockHostInfo.return_value.is_distro_valid.return_value = True |
868 | MockHostInfo.return_value.has_lxc_support.return_value = False |
869 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
870 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'lxc', False, |
871 | + self.config, self.lock, self.monitor, self.client, self.callback) |
872 | task._instant_callback = True |
873 | task.start().join() |
874 | |
875 | @@ -131,7 +138,8 @@ |
876 | def test_sets_generic_name_when_empty(self): |
877 | self.config.container_exists.return_value = False |
878 | self.monitor.done.return_value = False |
879 | - task = tasks.CreateTask('palpatine', None, 'zesty', 'chroot', False, self.config, self.lock, self.monitor, self.callback) |
880 | + task = tasks.CreateTask('palpatine', None, 'zesty', 'chroot', False, self.config, |
881 | + self.lock, self.monitor, self.client, self.callback) |
882 | task._instant_callback = True |
883 | |
884 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
885 | @@ -153,7 +161,8 @@ |
886 | def test_sets_multiarch(self): |
887 | self.config.container_exists.return_value = False |
888 | self.monitor.done.return_value = False |
889 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'chroot', True, self.config, self.lock, self.monitor, self.callback) |
890 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', 'chroot', True, |
891 | + self.config, self.lock, self.monitor, self.client, self.callback) |
892 | task._instant_callback = True |
893 | |
894 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
895 | @@ -175,7 +184,8 @@ |
896 | def test_sets_default_type(self): |
897 | self.config.container_exists.return_value = False |
898 | self.monitor.done.return_value = False |
899 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', None, False, self.config, self.lock, self.monitor, self.callback) |
900 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', 'zesty', None, False, |
901 | + self.config, self.lock, self.monitor, self.client, self.callback) |
902 | task._instant_callback = True |
903 | |
904 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
905 | @@ -197,7 +207,8 @@ |
906 | def test_sets_default_distro(self): |
907 | self.config.container_exists.return_value = False |
908 | self.monitor.done.return_value = False |
909 | - task = tasks.CreateTask('palpatine', 'Emperor Palpatine', None, 'lxc', False, self.config, self.lock, self.monitor, self.callback) |
910 | + task = tasks.CreateTask('palpatine', 'Emperor Palpatine', None, 'lxc', False, |
911 | + self.config, self.lock, self.monitor, self.client, self.callback) |
912 | task._instant_callback = True |
913 | |
914 | with unittest.mock.patch('libertine.service.tasks.create_task.HostInfo') as MockHostInfo: |
915 | |
916 | === modified file 'tests/unit/service/tasks/test_destroy_task.py' |
917 | --- tests/unit/service/tasks/test_destroy_task.py 2017-03-07 19:41:49 +0000 |
918 | +++ tests/unit/service/tasks/test_destroy_task.py 2017-03-09 17:44:54 +0000 |
919 | @@ -23,6 +23,7 @@ |
920 | def setUp(self): |
921 | self.config = unittest.mock.create_autospec(ContainersConfig) |
922 | self.lock = unittest.mock.MagicMock() |
923 | + self.client = unittest.mock.Mock() |
924 | self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
925 | |
926 | self.monitor.new_operation.return_value = "/com/canonical/libertine/Service/Download/123456" |
927 | @@ -34,7 +35,7 @@ |
928 | def test_sends_error_on_non_ready_container(self): |
929 | self.config._get_value_by_key.return_value = '' |
930 | self.monitor.done.return_value = False |
931 | - task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
932 | + task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
933 | task._instant_callback = True |
934 | |
935 | with unittest.mock.patch('libertine.service.tasks.destroy_task.LibertineContainer') as MockContainer: |
936 | @@ -46,7 +47,7 @@ |
937 | |
938 | def test_sends_error_on_failed_destroy(self): |
939 | self.config._get_value_by_key.return_value = 'ready' |
940 | - task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
941 | + task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
942 | task._instant_callback = True |
943 | |
944 | with unittest.mock.patch('libertine.service.tasks.destroy_task.LibertineContainer') as MockContainer: |
945 | @@ -64,7 +65,7 @@ |
946 | def test_successfully_destroys(self): |
947 | self.config._get_value_by_key.return_value = 'ready' |
948 | self.monitor.done.return_value = False |
949 | - task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
950 | + task = tasks.DestroyTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
951 | task._instant_callback = True |
952 | |
953 | with unittest.mock.patch('libertine.service.tasks.destroy_task.LibertineContainer') as MockContainer: |
954 | |
955 | === modified file 'tests/unit/service/tasks/test_install_task.py' |
956 | --- tests/unit/service/tasks/test_install_task.py 2017-03-07 19:41:49 +0000 |
957 | +++ tests/unit/service/tasks/test_install_task.py 2017-03-09 17:44:54 +0000 |
958 | @@ -21,9 +21,10 @@ |
959 | |
960 | class TestInstallTask(TestCase): |
961 | def setUp(self): |
962 | - self.config = unittest.mock.create_autospec(ContainersConfig) |
963 | - self.lock = unittest.mock.MagicMock() |
964 | - self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
965 | + self.config = unittest.mock.create_autospec(ContainersConfig) |
966 | + self.lock = unittest.mock.MagicMock() |
967 | + self.client = unittest.mock.Mock() |
968 | + self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
969 | |
970 | self.monitor.new_operation.return_value = "/com/canonical/libertine/Service/Download/123456" |
971 | self.called_with = None |
972 | @@ -33,7 +34,7 @@ |
973 | |
974 | def test_sends_error_on_existing_package(self): |
975 | self.config.package_exists.return_value = True |
976 | - task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
977 | + task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
978 | task._instant_callback = True |
979 | task.start().join() |
980 | |
981 | @@ -42,7 +43,7 @@ |
982 | |
983 | def test_sends_error_on_failed_install(self): |
984 | self.config.package_exists.return_value = False |
985 | - task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
986 | + task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
987 | task._instant_callback = True |
988 | |
989 | with unittest.mock.patch('libertine.service.tasks.install_task.LibertineContainer') as MockContainer: |
990 | @@ -57,7 +58,7 @@ |
991 | def test_successfully_install(self): |
992 | self.config.package_exists.return_value = False |
993 | self.monitor.done.return_value = False |
994 | - task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
995 | + task = tasks.InstallTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
996 | task._instant_callback = True |
997 | |
998 | with unittest.mock.patch('libertine.service.tasks.install_task.LibertineContainer') as MockContainer: |
999 | |
1000 | === modified file 'tests/unit/service/tasks/test_remove_task.py' |
1001 | --- tests/unit/service/tasks/test_remove_task.py 2017-03-07 19:41:49 +0000 |
1002 | +++ tests/unit/service/tasks/test_remove_task.py 2017-03-09 17:44:54 +0000 |
1003 | @@ -21,9 +21,10 @@ |
1004 | |
1005 | class TestRemoveTask(TestCase): |
1006 | def setUp(self): |
1007 | - self.config = unittest.mock.create_autospec(ContainersConfig) |
1008 | - self.lock = unittest.mock.MagicMock() |
1009 | - self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
1010 | + self.config = unittest.mock.create_autospec(ContainersConfig) |
1011 | + self.lock = unittest.mock.MagicMock() |
1012 | + self.client = unittest.mock.Mock() |
1013 | + self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
1014 | |
1015 | self.monitor.new_operation.return_value = "/com/canonical/libertine/Service/Download/123456" |
1016 | self.called_with = None |
1017 | @@ -33,7 +34,7 @@ |
1018 | |
1019 | def test_sends_error_on_non_installed_package(self): |
1020 | self.config.get_package_install_status.return_value = 'installing' |
1021 | - task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
1022 | + task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1023 | task._instant_callback = True |
1024 | task.start().join() |
1025 | |
1026 | @@ -42,7 +43,7 @@ |
1027 | |
1028 | def test_sends_error_on_failed_install(self): |
1029 | self.config.get_package_install_status.return_value = 'installed' |
1030 | - task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
1031 | + task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1032 | task._instant_callback = True |
1033 | |
1034 | with unittest.mock.patch('libertine.service.tasks.remove_task.LibertineContainer') as MockContainer: |
1035 | @@ -59,7 +60,7 @@ |
1036 | def test_successfully_install(self): |
1037 | self.config.get_package_install_status.return_value = 'installed' |
1038 | self.monitor.done.return_value = False |
1039 | - task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.callback) |
1040 | + task = tasks.RemoveTask('darkside-common', 'palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1041 | task._instant_callback = True |
1042 | |
1043 | with unittest.mock.patch('libertine.service.tasks.remove_task.LibertineContainer') as MockContainer: |
1044 | |
1045 | === modified file 'tests/unit/service/tasks/test_update_task.py' |
1046 | --- tests/unit/service/tasks/test_update_task.py 2017-03-07 19:41:49 +0000 |
1047 | +++ tests/unit/service/tasks/test_update_task.py 2017-03-09 17:44:54 +0000 |
1048 | @@ -23,6 +23,7 @@ |
1049 | def setUp(self): |
1050 | self.config = unittest.mock.create_autospec(ContainersConfig) |
1051 | self.lock = unittest.mock.MagicMock() |
1052 | + self.client = unittest.mock.Mock() |
1053 | self.monitor = unittest.mock.create_autospec(operations_monitor.OperationsMonitor) |
1054 | |
1055 | self.monitor.new_operation.return_value = "/com/canonical/libertine/Service/Download/123456" |
1056 | @@ -33,7 +34,7 @@ |
1057 | |
1058 | def test_sends_error_on_non_existent_container(self): |
1059 | self.config.container_exists.return_value = False |
1060 | - task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
1061 | + task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1062 | task._instant_callback = True |
1063 | |
1064 | with unittest.mock.patch('libertine.service.tasks.update_task.LibertineContainer') as MockContainer: |
1065 | @@ -45,7 +46,7 @@ |
1066 | |
1067 | def test_sends_error_on_failed_update(self): |
1068 | self.config.container_exists.return_value = True |
1069 | - task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
1070 | + task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1071 | task._instant_callback = True |
1072 | |
1073 | with unittest.mock.patch('libertine.service.tasks.update_task.LibertineContainer') as MockContainer: |
1074 | @@ -63,7 +64,7 @@ |
1075 | def test_successfully_updates(self): |
1076 | self.config.container_exists.return_value = True |
1077 | self.monitor.done.return_value = False |
1078 | - task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.callback) |
1079 | + task = tasks.UpdateTask('palpatine', self.config, self.lock, self.monitor, self.client, self.callback) |
1080 | task._instant_callback = True |
1081 | |
1082 | with unittest.mock.patch('libertine.service.tasks.update_task.LibertineContainer') as MockContainer: |
1083 | |
1084 | === modified file 'tests/unit/service/test_container.py' |
1085 | --- tests/unit/service/test_container.py 2017-03-07 20:45:30 +0000 |
1086 | +++ tests/unit/service/test_container.py 2017-03-09 17:44:54 +0000 |
1087 | @@ -22,11 +22,12 @@ |
1088 | def setUp(self): |
1089 | self._monitor = unittest.mock.Mock() |
1090 | self._config = unittest.mock.Mock() |
1091 | + self._client = unittest.mock.Mock() |
1092 | |
1093 | def test_search_creates_search_task(self): |
1094 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1095 | cache = MockCache.return_value |
1096 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1097 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1098 | with unittest.mock.patch('libertine.service.container.SearchTask') as MockSearchTask: |
1099 | c.search('darkseid') |
1100 | MockSearchTask.assert_called_once_with('palpatine', cache, 'darkseid', self._monitor, unittest.mock.ANY) |
1101 | @@ -35,7 +36,7 @@ |
1102 | def test_app_info_creates_app_info_task(self): |
1103 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1104 | cache = MockCache.return_value |
1105 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1106 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1107 | with unittest.mock.patch('libertine.service.container.AppInfoTask') as MockAppInfoTask: |
1108 | c.app_info('force') |
1109 | MockAppInfoTask.assert_called_once_with('palpatine', cache, 'force', [], self._config, self._monitor, unittest.mock.ANY) |
1110 | @@ -44,7 +45,7 @@ |
1111 | def test_app_info_gets_related_task_info(self): |
1112 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1113 | cache = MockCache.return_value |
1114 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1115 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1116 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
1117 | MockInstallTask.return_value.package = 'darkside' |
1118 | MockInstallTask.return_value.matches.return_value = False |
1119 | @@ -59,99 +60,99 @@ |
1120 | |
1121 | def test_install_creates_install_task(self): |
1122 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1123 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1124 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1125 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
1126 | c.install('force') |
1127 | - MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1128 | + MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1129 | MockInstallTask.return_value.start.assert_called_once_with() |
1130 | |
1131 | def test_install_only_calls_once_when_unfinished(self): |
1132 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1133 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1134 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1135 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
1136 | c.install('darkside') |
1137 | c.install('darkside') |
1138 | c.install('darkside') |
1139 | - MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1140 | + MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1141 | MockInstallTask.return_value.start.assert_called_once_with() |
1142 | |
1143 | def test_remove_creates_remove_task(self): |
1144 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1145 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1146 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1147 | with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask: |
1148 | c.remove('force') |
1149 | - MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1150 | + MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1151 | MockRemoveTask.return_value.start.assert_called_once_with() |
1152 | |
1153 | def test_remove_only_calls_once_when_unfinished(self): |
1154 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1155 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1156 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1157 | with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask: |
1158 | c.remove('darkside') |
1159 | c.remove('darkside') |
1160 | c.remove('darkside') |
1161 | - MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1162 | + MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1163 | MockRemoveTask.return_value.start.assert_called_once_with() |
1164 | |
1165 | def test_create_creates_create_task(self): |
1166 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1167 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1168 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1169 | with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask: |
1170 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
1171 | MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False, |
1172 | - self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1173 | + self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1174 | MockCreateTask.return_value.start.assert_called_once_with() |
1175 | |
1176 | def test_create_only_calls_once_when_unfinished(self): |
1177 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1178 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1179 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1180 | with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask: |
1181 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
1182 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
1183 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
1184 | MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False, |
1185 | - self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1186 | + self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1187 | MockCreateTask.return_value.start.assert_called_once_with() |
1188 | |
1189 | def test_destroy_creates_destroy_task(self): |
1190 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1191 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1192 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1193 | with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask: |
1194 | c.destroy() |
1195 | - MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1196 | + MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1197 | MockDestroyTask.return_value.start.assert_called_once_with() |
1198 | |
1199 | def test_destroy_only_calls_once_when_unfinished(self): |
1200 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1201 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1202 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1203 | with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask: |
1204 | c.destroy() |
1205 | c.destroy() |
1206 | c.destroy() |
1207 | - MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1208 | + MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1209 | MockDestroyTask.return_value.start.assert_called_once_with() |
1210 | |
1211 | def test_update_creates_update_task(self): |
1212 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1213 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1214 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1215 | with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask: |
1216 | c.update() |
1217 | - MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1218 | + MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1219 | MockUpdateTask.return_value.start.assert_called_once_with() |
1220 | |
1221 | def test_update_only_calls_once_when_unfinished(self): |
1222 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1223 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1224 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1225 | with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask: |
1226 | c.update() |
1227 | c.update() |
1228 | c.update() |
1229 | - MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, unittest.mock.ANY) |
1230 | + MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._monitor, self._client, unittest.mock.ANY) |
1231 | MockUpdateTask.return_value.start.assert_called_once_with() |
1232 | |
1233 | def test_list_app_ids_creates_list_app_ids_task(self): |
1234 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1235 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1236 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1237 | with unittest.mock.patch('libertine.service.container.ListAppIdsTask') as MockListAppIdsTask: |
1238 | c.list_app_ids() |
1239 | MockListAppIdsTask.assert_called_once_with('palpatine', self._config, self._monitor, unittest.mock.ANY) |
1240 | @@ -159,7 +160,7 @@ |
1241 | |
1242 | def test_removes_task_during_callback(self): |
1243 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
1244 | - c = container.Container('palpatine', self._config, self._monitor, lambda task: task) |
1245 | + c = container.Container('palpatine', self._config, self._monitor, self._client, lambda task: task) |
1246 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
1247 | MockInstallTask.return_value.package = 'force' |
1248 | c.install('force') |
1249 | @@ -176,7 +177,7 @@ |
1250 | self._container_id = None |
1251 | def callback(container): |
1252 | self._container_id = container.id |
1253 | - c = container.Container('palpatine', self._config, self._monitor, callback) |
1254 | + c = container.Container('palpatine', self._config, self._monitor, self._client, callback) |
1255 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
1256 | c.install('force') |
1257 | name, args, kwargs = MockInstallTask.mock_calls[0] |
1258 | |
1259 | === modified file 'tests/unit/service/test_task_dispatcher.py' |
1260 | --- tests/unit/service/test_task_dispatcher.py 2017-02-07 12:35:48 +0000 |
1261 | +++ tests/unit/service/test_task_dispatcher.py 2017-03-09 17:44:54 +0000 |
1262 | @@ -20,9 +20,10 @@ |
1263 | class TestTaskDispatcher(TestCase): |
1264 | def setUp(self): |
1265 | self._connection = unittest.mock.Mock() |
1266 | + self._client = unittest.mock.Mock() |
1267 | self._config_patcher = unittest.mock.patch('libertine.service.task_dispatcher.libertine.ContainersConfig.ContainersConfig') |
1268 | self._config_patcher.start() |
1269 | - self._dispatcher = task_dispatcher.TaskDispatcher(self._connection) |
1270 | + self._dispatcher = task_dispatcher.TaskDispatcher(self._connection, self._client) |
1271 | |
1272 | def tearDown(self): |
1273 | self._config_patcher.stop() |
1274 | @@ -90,20 +91,20 @@ |
1275 | self._dispatcher.list_app_ids('palpatine') |
1276 | self._dispatcher.list_app_ids('palpatine') |
1277 | self._dispatcher.list_app_ids('palpatine') |
1278 | - MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
1279 | + MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, self._client, unittest.mock.ANY) |
1280 | |
1281 | def test_container_callback_removes_container(self): |
1282 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
1283 | c = MockContainer.return_value |
1284 | c.id = 'palpatine' |
1285 | self._dispatcher.list_app_ids('palpatine') |
1286 | - MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
1287 | + MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, self._client, unittest.mock.ANY) |
1288 | name, args, kwargs = MockContainer.mock_calls[0] |
1289 | args[len(args)-1](MockContainer.return_value) |
1290 | self._dispatcher.list_app_ids('palpatine') |
1291 | MockContainer.assert_has_calls([ # verify container constructed twice |
1292 | - unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY), |
1293 | - unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
1294 | + unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, self._client, unittest.mock.ANY), |
1295 | + unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, self._client, unittest.mock.ANY) |
1296 | ], any_order=True) |
1297 | |
1298 | def test_container_info_creates_container_info_task(self): |
1299 | |
1300 | === modified file 'tools/libertined' |
1301 | --- tools/libertined 2017-03-06 19:50:12 +0000 |
1302 | +++ tools/libertined 2017-03-09 17:44:54 +0000 |
1303 | @@ -25,7 +25,7 @@ |
1304 | from dbus.mainloop.glib import DBusGMainLoop |
1305 | from gi.repository import GLib |
1306 | from libertine import utils |
1307 | -from libertine.service import constants, operations, container_control |
1308 | +from libertine.service import constants, operations, container_control, container_control_client |
1309 | |
1310 | |
1311 | class OutputRedirector(object): |
1312 | @@ -151,9 +151,10 @@ |
1313 | utils.get_logger().warning("service is already running") |
1314 | raise |
1315 | |
1316 | - manager = operations.Operations(bus_name) |
1317 | - container_control.ContainerControl(manager.connection) |
1318 | - |
1319 | + client = container_control_client.ContainerControlClient() |
1320 | + manager = operations.Operations(bus_name, client) |
1321 | + container_control.ContainerControl(manager.connection, client) |
1322 | + |
1323 | try: |
1324 | loop.run() |
1325 | except KeyboardInterrupt: |
FAILED: Continuous integration, rev:419 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/454/ /jenkins. canonical. com/libertine/ job/build/ 839/console /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 849 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 841/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/841/ console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 841/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/841/ console
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/libertine/ job/lp- libertine- ci/454/ rebuild
https:/