Merge lp:~larryprice/libertine/libertined-input into lp:libertine
- libertined-input
- Merge into devel
Status: | Needs review |
---|---|
Proposed branch: | lp:~larryprice/libertine/libertined-input |
Merge into: | lp:libertine |
Prerequisite: | lp:~larryprice/libertine/libertined-output |
Diff against target: |
595 lines (+117/-75) 14 files modified
python/libertine/ChrootContainer.py (+8/-5) python/libertine/Libertine.py (+41/-12) python/libertine/LxcContainer.py (+8/-10) python/libertine/LxdContainer.py (+4/-3) python/libertine/service/download.py (+5/-1) python/libertine/service/operations_monitor.py (+2/-2) python/libertine/service/task_dispatcher_base.py (+1/-1) python/libertine/service/tasks/base_task.py (+12/-5) python/libertine/service/tasks/create_task.py (+1/-2) python/libertine/service/tasks/install_task.py (+1/-1) python/libertine/service/tasks/remove_task.py (+1/-1) python/libertine/service/tasks/update_task.py (+1/-1) tests/unit/service/test_operations_monitor.py (+12/-11) tools/libertine-container-manager (+20/-20) |
To merge this branch: | bzr merge lp:~larryprice/libertine/libertined-input |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Libertine CI Bot | continuous-integration | Needs Fixing | |
Libertine Developers | Pending | ||
Review via email:
|
Commit message
Allow sending input data to libertined during certain container operations.
Description of the change
Allow sending input data to libertined during certain container operations.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
- 465. By Larry Price
-
merge
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:465
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
- 466. By Larry Price
-
chmod
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:466
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 466. By Larry Price
-
chmod
- 465. By Larry Price
-
merge
- 464. By Larry Price
-
fixing up merge and tests
- 463. By Larry Price
-
merge
- 462. By Larry Price
-
create with password separate
- 461. By Larry Price
-
chroot and lxc
- 460. By Larry Price
-
INPUT! At least for lxd on install/remove...
- 459. By Larry Price
-
minor changes
- 458. By Larry Price
-
well these are good ideas but don't work for lxc
- 457. By Larry Price
-
at some point everything broke?
Preview Diff
1 | === modified file 'python/libertine/ChrootContainer.py' |
2 | --- python/libertine/ChrootContainer.py 2017-03-23 19:23:20 +0000 |
3 | +++ python/libertine/ChrootContainer.py 2017-04-07 17:23:06 +0000 |
4 | @@ -47,8 +47,8 @@ |
5 | A concrete container type implemented using a plain old chroot. |
6 | """ |
7 | |
8 | - def __init__(self, container_id, config, service): |
9 | - super().__init__(container_id, 'chroot', config, service) |
10 | + def __init__(self, container_id, config, service, stdin): |
11 | + super().__init__(container_id, 'chroot', config, service, stdin) |
12 | # FIXME: Disabling seccomp is a temporary measure until we fully understand why we need |
13 | # it or figure out when we need it. |
14 | os.environ['PROOT_NO_SECCOMP'] = '1' |
15 | @@ -60,13 +60,13 @@ |
16 | command_prefix = "{} fakeroot chroot {}".format( |
17 | self._build_fakechroot_command(), self.root_path) |
18 | args = shlex.split(command_prefix + ' ' + command_string) |
19 | - cmd = subprocess.Popen(args) |
20 | - return cmd.wait() |
21 | + |
22 | + return self._run_with_stdin(args) or subprocess.Popen(args).wait() |
23 | |
24 | def destroy_libertine_container(self, force): |
25 | return self._delete_rootfs() |
26 | |
27 | - def create_libertine_container(self, password=None, multiarch=False): |
28 | + def create_libertine_container(self, multiarch=False): |
29 | # Create the actual chroot |
30 | command_line = "{} fakeroot debootstrap --verbose --variant=fakechroot {} {}".format( |
31 | self._build_fakechroot_command(), self.installed_release, self.root_path) |
32 | @@ -231,6 +231,9 @@ |
33 | def finish_application(self, app): |
34 | app.wait() |
35 | |
36 | + def set_password(self, password): |
37 | + pass # No passwords in chroot containers |
38 | + |
39 | def _run_ldconfig(self): |
40 | utils.get_logger().info(utils._("Refreshing the container's dynamic linker run-time bindings...")) |
41 | |
42 | |
43 | === modified file 'python/libertine/Libertine.py' |
44 | --- python/libertine/Libertine.py 2017-04-07 17:23:05 +0000 |
45 | +++ python/libertine/Libertine.py 2017-04-07 17:23:06 +0000 |
46 | @@ -16,6 +16,8 @@ |
47 | import contextlib |
48 | import os |
49 | import shutil |
50 | +import subprocess |
51 | +import time |
52 | |
53 | from . import utils, ContainerControlClient |
54 | from libertine.ContainersConfig import ContainersConfig |
55 | @@ -79,11 +81,12 @@ |
56 | |
57 | :param container_id: The machine-readable container name. |
58 | """ |
59 | - def __init__(self, container_id, container_type, config, service): |
60 | + def __init__(self, container_id, container_type, config, service, stdin): |
61 | self.container_type = container_type |
62 | self.container_id = container_id |
63 | self._config = config |
64 | self._service = service |
65 | + self._stdin = stdin |
66 | self._app_name = '' |
67 | self._pid = 0 |
68 | self.root_path = utils.get_libertine_container_rootfs_path(self.container_id) |
69 | @@ -145,7 +148,7 @@ |
70 | for language_pack in [p.format(self.language) for p in base_language_packs]: |
71 | self.install_package(language_pack, update_cache=False) |
72 | |
73 | - def create_libertine_container(self, password=None, multiarch=False): |
74 | + def create_libertine_container(self, multiarch=False): |
75 | self.install_base_language_packs() |
76 | |
77 | def destroy_libertine_container(self, force): |
78 | @@ -204,6 +207,20 @@ |
79 | """ |
80 | pass |
81 | |
82 | + def _run_with_stdin(self, command): |
83 | + if self._stdin: |
84 | + p = subprocess.Popen(command, stdin=subprocess.PIPE) |
85 | + while p.poll() is None: |
86 | + if not self._stdin.empty(): |
87 | + p.stdin.write(self._stdin.get()) |
88 | + p.stdin.flush() |
89 | + |
90 | + time.sleep(.1) |
91 | + |
92 | + return p.returncode |
93 | + |
94 | + return None |
95 | + |
96 | def update_apt_cache(self): |
97 | """ |
98 | Updates the apt cache in the container. |
99 | @@ -270,6 +287,11 @@ |
100 | return False |
101 | return self.run_in_container(_apt_command_prefix() + "autoremove --purge") == 0 |
102 | |
103 | + def set_password(self, password): |
104 | + if password: |
105 | + import crypt |
106 | + return self.run_in_container("usermod -p {password} {username}".format(username=os.environ['USER'], password=crypt.crypt(password))) |
107 | + |
108 | def configure_multiarch(self, should_enable): |
109 | """ |
110 | Enables or disables multiarch repositories. |
111 | @@ -335,10 +357,10 @@ |
112 | """ |
113 | A concrete mock container type. Used for unit testing. |
114 | """ |
115 | - def __init__(self, container_id, config, service): |
116 | - super().__init__(container_id, 'mock', config, service) |
117 | + def __init__(self, container_id, config, service, stdin): |
118 | + super().__init__(container_id, 'mock', config, service, stdin) |
119 | |
120 | - def create_libertine_container(self, password=None, multiarch=False): |
121 | + def create_libertine_container(self, multiarch=False): |
122 | return True |
123 | |
124 | def destroy_libertine_container(self, force): |
125 | @@ -389,7 +411,7 @@ |
126 | A sandbox for DEB-packaged X11-based applications. |
127 | """ |
128 | |
129 | - def __init__(self, container_id, containers_config=None, service=None): |
130 | + def __init__(self, container_id, containers_config=None, service=None, stdin=None): |
131 | """ |
132 | Initializes the container object. |
133 | |
134 | @@ -404,15 +426,15 @@ |
135 | |
136 | if container_type == "lxc": |
137 | from libertine.LxcContainer import LibertineLXC |
138 | - self.container = LibertineLXC(container_id, self.containers_config, service) |
139 | + self.container = LibertineLXC(container_id, self.containers_config, service, stdin) |
140 | elif container_type == "lxd": |
141 | from libertine.LxdContainer import LibertineLXD |
142 | - self.container = LibertineLXD(container_id, self.containers_config, service) |
143 | + self.container = LibertineLXD(container_id, self.containers_config, service, stdin) |
144 | elif container_type == "chroot": |
145 | from libertine.ChrootContainer import LibertineChroot |
146 | - self.container = LibertineChroot(container_id, self.containers_config, service) |
147 | + self.container = LibertineChroot(container_id, self.containers_config, service, stdin) |
148 | elif container_type == "mock": |
149 | - self.container = LibertineMock(container_id, self.containers_config, service) |
150 | + self.container = LibertineMock(container_id, self.containers_config, service, stdin) |
151 | else: |
152 | raise RuntimeError(utils._("Unsupported container type '{container_type}'").format(container_type)) |
153 | |
154 | @@ -438,14 +460,14 @@ |
155 | """ |
156 | return self.container.destroy_libertine_container(force) |
157 | |
158 | - def create_libertine_container(self, password=None, multiarch=False): |
159 | + def create_libertine_container(self, multiarch=False): |
160 | """ |
161 | Creates the container. |
162 | """ |
163 | self.container.architecture = HostInfo().get_host_architecture() |
164 | self.container.installed_release = self.containers_config.get_container_distro(self.container_id) |
165 | |
166 | - return self.container.create_libertine_container(password, multiarch) |
167 | + return self.container.create_libertine_container(multiarch) |
168 | |
169 | def update_libertine_container(self, new_locale=None): |
170 | """ |
171 | @@ -589,3 +611,10 @@ |
172 | return self.container.configure_remove_archive(archive) |
173 | except RuntimeError as e: |
174 | return handle_runtime_error(e) |
175 | + |
176 | + def set_password(self, password): |
177 | + try: |
178 | + with ContainerRunning(self.container): |
179 | + return self.container.set_password(password) |
180 | + except RuntimeError as e: |
181 | + return handle_runtime_error(e) |
182 | |
183 | === modified file 'python/libertine/LxcContainer.py' |
184 | --- python/libertine/LxcContainer.py 2017-03-23 19:23:20 +0000 |
185 | +++ python/libertine/LxcContainer.py 2017-04-07 17:23:06 +0000 |
186 | @@ -157,8 +157,8 @@ |
187 | A concrete container type implemented using an LXC container. |
188 | """ |
189 | |
190 | - def __init__(self, container_id, config, service): |
191 | - super().__init__(container_id, 'lxc', config, service) |
192 | + def __init__(self, container_id, config, service, stdin): |
193 | + super().__init__(container_id, 'lxc', config, service, stdin) |
194 | self.container = lxc_container(container_id) |
195 | self.host_info = HostInfo.HostInfo() |
196 | self._freeze_on_stop = config.get_freeze_on_stop(self.container_id) |
197 | @@ -255,8 +255,10 @@ |
198 | return lxc_stop(self.container, self._freeze_on_stop) |
199 | |
200 | def run_in_container(self, command_string): |
201 | - cmd_args = shlex.split(command_string) |
202 | - return self.container.attach_wait(lxc.attach_run_command, cmd_args) |
203 | + popen_args = shlex.split("lxc-attach -P {root_path} -n {container_id} -- {command}" |
204 | + .format(root_path=utils.get_libertine_containers_dir_path(), |
205 | + container_id=self.container_id, command=command_string)) |
206 | + return self._run_with_stdin(popen_args) or self.container.attach_wait(lxc.attach_run_command, shlex.split(command_string)) |
207 | |
208 | def update_packages(self, update_locale=False): |
209 | if self.timezone_needs_update(): |
210 | @@ -282,10 +284,7 @@ |
211 | self.container.destroy() |
212 | return True |
213 | |
214 | - def create_libertine_container(self, password=None, multiarch=False): |
215 | - if password is None: |
216 | - return False |
217 | - |
218 | + def create_libertine_container(self, multiarch=False): |
219 | username = os.environ['USER'] |
220 | user_id = os.getuid() |
221 | group_id = os.getgid() |
222 | @@ -336,8 +335,7 @@ |
223 | self.update_locale() |
224 | |
225 | self.run_in_container("userdel -r ubuntu") |
226 | - self.run_in_container("useradd -u {} -p {} -G sudo {}".format( |
227 | - str(user_id), crypt.crypt(password), str(username))) |
228 | + self.run_in_container("useradd -u {} -G sudo {}".format(str(user_id), str(username))) |
229 | |
230 | if multiarch and self.architecture == 'amd64': |
231 | utils.get_logger().info(utils._("Adding i386 multiarch support...")) |
232 | |
233 | === modified file 'python/libertine/LxdContainer.py' |
234 | --- python/libertine/LxdContainer.py 2017-04-07 17:23:05 +0000 |
235 | +++ python/libertine/LxdContainer.py 2017-04-07 17:23:06 +0000 |
236 | @@ -387,8 +387,8 @@ |
237 | |
238 | |
239 | class LibertineLXD(Libertine.BaseContainer): |
240 | - def __init__(self, name, config, service): |
241 | - super().__init__(name, 'lxd', config, service) |
242 | + def __init__(self, name, config, service, stdin): |
243 | + super().__init__(name, 'lxd', config, service, stdin) |
244 | self._host_info = HostInfo.HostInfo() |
245 | self._container = None |
246 | self._freeze_on_stop = config.get_freeze_on_stop(self.container_id) |
247 | @@ -504,7 +504,8 @@ |
248 | return _lxc_args(self.container_id, command, environ) |
249 | |
250 | def run_in_container(self, command): |
251 | - return subprocess.Popen(self._lxc_args(command, os.environ.copy())).wait() |
252 | + args = self._lxc_args(command, os.environ.copy()) |
253 | + return self._run_with_stdin(args) or subprocess.Popen(args).wait() |
254 | |
255 | def start_container(self, home=env_home_path()): |
256 | if not self._try_get_container(): |
257 | |
258 | === modified file 'python/libertine/service/download.py' |
259 | --- python/libertine/service/download.py 2017-04-07 17:23:05 +0000 |
260 | +++ python/libertine/service/download.py 2017-04-07 17:23:06 +0000 |
261 | @@ -22,10 +22,11 @@ |
262 | |
263 | |
264 | class Download(dbus.service.Object): |
265 | - def __init__(self, connection, id): |
266 | + def __init__(self, connection, id, input_queue): |
267 | self._finished = multiprocessing.Event() |
268 | self._result = multiprocessing.SimpleQueue() |
269 | self._error = multiprocessing.SimpleQueue() |
270 | + self._input = input_queue |
271 | dbus.service.Object.__init__(self, conn=connection, object_path=(constants.DOWNLOAD_OBJECT % id)) |
272 | |
273 | @property |
274 | @@ -53,6 +54,9 @@ |
275 | def data(self, message): |
276 | self._result.put(message) |
277 | |
278 | + def input(self, message): |
279 | + self._input.put(message.encode('utf-8')) |
280 | + |
281 | # Signals to satisfy the download interface |
282 | |
283 | @dbus.service.signal(constants.DOWNLOAD_INTERFACE, signature='o') |
284 | |
285 | === modified file 'python/libertine/service/operations_monitor.py' |
286 | --- python/libertine/service/operations_monitor.py 2017-04-07 17:23:05 +0000 |
287 | +++ python/libertine/service/operations_monitor.py 2017-04-07 17:23:06 +0000 |
288 | @@ -27,8 +27,8 @@ |
289 | self._operations = [] |
290 | dbus.service.Object.__init__(self, conn=connection, object_path=constants.OPERATIONS_MONITOR_OBJECT) |
291 | |
292 | - def new_operation(self): |
293 | - self._operations.append(download.Download(self.connection, str(uuid.uuid4().fields[-1]))) |
294 | + def new_operation(self, input_queue): |
295 | + self._operations.append(download.Download(self.connection, str(uuid.uuid4().fields[-1]), input_queue)) |
296 | return self._operations[-1].id |
297 | |
298 | def remove_from_connection(self, path): |
299 | |
300 | === modified file 'python/libertine/service/task_dispatcher_base.py' |
301 | --- python/libertine/service/task_dispatcher_base.py 2017-04-07 17:23:05 +0000 |
302 | +++ python/libertine/service/task_dispatcher_base.py 2017-04-07 17:23:06 +0000 |
303 | @@ -33,7 +33,7 @@ |
304 | def _cleanup(self): |
305 | for task in [task for task in self._tasks if task.should_delete]: |
306 | utils.get_logger().debug("Cleaning up task '{}'".format(task.id)) |
307 | - task.thread.join() |
308 | + task.join() |
309 | self._monitor.remove_from_connection(task.id) |
310 | self._tasks.remove(task) |
311 | |
312 | |
313 | === modified file 'python/libertine/service/tasks/base_task.py' |
314 | --- python/libertine/service/tasks/base_task.py 2017-04-07 17:23:05 +0000 |
315 | +++ python/libertine/service/tasks/base_task.py 2017-04-07 17:23:06 +0000 |
316 | @@ -33,8 +33,11 @@ |
317 | self._lock = lock |
318 | self._container = container_id |
319 | self._config = config |
320 | + self._monitor = monitor |
321 | + |
322 | self._finished_at = multiprocessing.SimpleQueue() |
323 | - self._monitor = monitor |
324 | + self._stdin = multiprocessing.SimpleQueue() |
325 | + self._thread = None |
326 | self._operation_id = None |
327 | self._delete_at = None |
328 | |
329 | @@ -69,14 +72,17 @@ |
330 | |
331 | return False |
332 | |
333 | + def join(self): |
334 | + self._thread.join() |
335 | + |
336 | def _finish(self): |
337 | self._finished_at.put(time.time()) |
338 | |
339 | def start(self): |
340 | - self._operation_id = self._monitor.new_operation() |
341 | - self.thread = multiprocessing.Process(target=self.run) |
342 | - self.thread.start() |
343 | - return self.thread |
344 | + self._operation_id = self._monitor.new_operation(self._stdin) |
345 | + self._thread = multiprocessing.Process(target=self.run) |
346 | + self._thread.start() |
347 | + return self._thread |
348 | |
349 | def watch_file(self, finished, path): |
350 | with open(path, 'rb') as thefile: |
351 | @@ -99,6 +105,7 @@ |
352 | with output_redirector.OutputRedirector(self._operation_id.split("/")[-1]) as redirector: |
353 | end_watch = multiprocessing.Event() |
354 | multiprocessing.Process(target=self.watch_file, args=(end_watch, redirector.path)).start() |
355 | + |
356 | if self._lock is not None: |
357 | with self._lock: |
358 | self._refresh_database(False) |
359 | |
360 | === modified file 'python/libertine/service/tasks/create_task.py' |
361 | --- python/libertine/service/tasks/create_task.py 2017-04-07 17:23:05 +0000 |
362 | +++ python/libertine/service/tasks/create_task.py 2017-04-07 17:23:06 +0000 |
363 | @@ -32,11 +32,10 @@ |
364 | |
365 | def _run(self): |
366 | utils.get_logger().debug("Creating container '%s'" % self._container) |
367 | - |
368 | try: |
369 | container = LibertineContainer(self._container, self._config, self._client) |
370 | |
371 | - if not container.create_libertine_container(password='', multiarch=self._multiarch): |
372 | + if not container.create_libertine_container(multiarch=self._multiarch): |
373 | self._config.delete_container(self._container) |
374 | self._error("Creating container '%s' failed" % self._container) |
375 | else: |
376 | |
377 | === modified file 'python/libertine/service/tasks/install_task.py' |
378 | --- python/libertine/service/tasks/install_task.py 2017-04-07 17:23:05 +0000 |
379 | +++ python/libertine/service/tasks/install_task.py 2017-04-07 17:23:06 +0000 |
380 | @@ -36,7 +36,7 @@ |
381 | |
382 | def _run(self): |
383 | utils.get_logger().debug("Installing package '%s'" % self._package) |
384 | - container = LibertineContainer(self._container, self._config, self._client) |
385 | + container = LibertineContainer(self._container, self._config, self._client, self._stdin) |
386 | if container.install_package(self._package, update_cache=self._update_cache, no_dialog=True): |
387 | self._config.update_package_install_status(self._container, self._package_name, "installed") |
388 | utils.refresh_libertine_scope() |
389 | |
390 | === modified file 'python/libertine/service/tasks/remove_task.py' |
391 | --- python/libertine/service/tasks/remove_task.py 2017-04-07 17:23:05 +0000 |
392 | +++ python/libertine/service/tasks/remove_task.py 2017-04-07 17:23:06 +0000 |
393 | @@ -31,7 +31,7 @@ |
394 | |
395 | def _run(self): |
396 | utils.get_logger().debug("Removing package '%s'" % self._package) |
397 | - container = LibertineContainer(self._container, self._config, self._client) |
398 | + container = LibertineContainer(self._container, self._config, self._client, self._stdin) |
399 | if container.remove_package(self._package, no_dialog=True): |
400 | self._config.delete_package(self._container, self._package) |
401 | utils.refresh_libertine_scope() |
402 | |
403 | === modified file 'python/libertine/service/tasks/update_task.py' |
404 | --- python/libertine/service/tasks/update_task.py 2017-04-07 17:23:05 +0000 |
405 | +++ python/libertine/service/tasks/update_task.py 2017-04-07 17:23:06 +0000 |
406 | @@ -32,7 +32,7 @@ |
407 | |
408 | def _run(self): |
409 | utils.get_logger().debug("Updating container '%s'" % self._container) |
410 | - container = LibertineContainer(self._container, self._config, self._client) |
411 | + container = LibertineContainer(self._container, self._config, self._client, self._stdin) |
412 | self._config.update_container_install_status(self._container, "updating") |
413 | |
414 | new_locale = self._get_updated_locale() |
415 | |
416 | === modified file 'tests/unit/service/test_operations_monitor.py' |
417 | --- tests/unit/service/test_operations_monitor.py 2017-03-07 20:45:30 +0000 |
418 | +++ tests/unit/service/test_operations_monitor.py 2017-04-07 17:23:06 +0000 |
419 | @@ -20,6 +20,7 @@ |
420 | class TestOperationsMonitor(TestCase): |
421 | def setUp(self): |
422 | self._connection = unittest.mock.Mock() |
423 | + self._stdin = unittest.mock.Mock() |
424 | |
425 | def test_new_operation_returns_some_id(self): |
426 | with unittest.mock.patch('dbus.service.Object'): |
427 | @@ -27,7 +28,7 @@ |
428 | monitor._connection = self._connection |
429 | |
430 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
431 | - self.assertIsNotNone(monitor.new_operation()) |
432 | + self.assertIsNotNone(monitor.new_operation(self._stdin)) |
433 | |
434 | def test_remove_connection(self): |
435 | with unittest.mock.patch('dbus.service.Object'): |
436 | @@ -35,7 +36,7 @@ |
437 | monitor._connection = self._connection |
438 | |
439 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
440 | - monitor.remove_from_connection(monitor.new_operation()) |
441 | + monitor.remove_from_connection(monitor.new_operation(self._stdin)) |
442 | MockDownload.return_value.remove_from_connection.assert_called_once_with() |
443 | |
444 | def test_returns_done_for_operation(self): |
445 | @@ -45,10 +46,10 @@ |
446 | |
447 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
448 | MockDownload.return_value.done = True |
449 | - self.assertTrue(monitor.done(monitor.new_operation())) |
450 | + self.assertTrue(monitor.done(monitor.new_operation(self._stdin))) |
451 | |
452 | MockDownload.return_value.done = False |
453 | - self.assertFalse(monitor.done(monitor.new_operation())) |
454 | + self.assertFalse(monitor.done(monitor.new_operation(self._stdin))) |
455 | |
456 | # non-existent operation |
457 | self.assertFalse(monitor.done("123456")) |
458 | @@ -60,10 +61,10 @@ |
459 | |
460 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
461 | MockDownload.return_value.done = True |
462 | - self.assertFalse(monitor.running(monitor.new_operation())) |
463 | + self.assertFalse(monitor.running(monitor.new_operation(self._stdin))) |
464 | |
465 | MockDownload.return_value.done = False |
466 | - self.assertTrue(monitor.running(monitor.new_operation())) |
467 | + self.assertTrue(monitor.running(monitor.new_operation(self._stdin))) |
468 | |
469 | # non-existent operation |
470 | self.assertFalse(monitor.running("123456")) |
471 | @@ -75,7 +76,7 @@ |
472 | |
473 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
474 | MockDownload.return_value.result = "pokemongus" |
475 | - self.assertEqual("pokemongus", monitor.result(monitor.new_operation())) |
476 | + self.assertEqual("pokemongus", monitor.result(monitor.new_operation(self._stdin))) |
477 | |
478 | # non-existent operation |
479 | self.assertEqual("", monitor.result("123456")) |
480 | @@ -87,7 +88,7 @@ |
481 | |
482 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
483 | MockDownload.return_value.last_error = "pokemongus" |
484 | - self.assertEqual("pokemongus", monitor.last_error(monitor.new_operation())) |
485 | + self.assertEqual("pokemongus", monitor.last_error(monitor.new_operation(self._stdin))) |
486 | |
487 | # non-existent operation |
488 | self.assertEqual("", monitor.last_error("123456")) |
489 | @@ -99,7 +100,7 @@ |
490 | monitor._locations = [] |
491 | |
492 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
493 | - path = monitor.new_operation() |
494 | + path = monitor.new_operation(self._stdin) |
495 | monitor.finished(path) |
496 | MockDownload.return_value.finished.assert_called_once_with(path) |
497 | |
498 | @@ -115,7 +116,7 @@ |
499 | monitor._locations = [] |
500 | |
501 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
502 | - path = monitor.new_operation() |
503 | + path = monitor.new_operation(self._stdin) |
504 | monitor.error(path, "something messed up") |
505 | MockDownload.return_value.error.assert_called_once_with("something messed up") |
506 | |
507 | @@ -131,7 +132,7 @@ |
508 | monitor._locations = [] |
509 | |
510 | with unittest.mock.patch('libertine.service.operations_monitor.download.Download') as MockDownload: |
511 | - path = monitor.new_operation() |
512 | + path = monitor.new_operation(self._stdin) |
513 | monitor.data(path, "some of that gud data") |
514 | MockDownload.return_value.data.assert_called_once_with("some of that gud data") |
515 | |
516 | |
517 | === modified file 'tools/libertine-container-manager' |
518 | --- tools/libertine-container-manager 2017-03-23 19:23:20 +0000 |
519 | +++ tools/libertine-container-manager 2017-04-07 17:23:06 +0000 |
520 | @@ -34,7 +34,6 @@ |
521 | self.containers_config = ContainersConfig() |
522 | self.host_info = HostInfo() |
523 | |
524 | - |
525 | def _container(self, container_id): |
526 | try: |
527 | return LibertineContainer(container_id, self.containers_config) |
528 | @@ -53,7 +52,25 @@ |
529 | return host_locale |
530 | |
531 | def create(self, args): |
532 | + if not args.type: |
533 | + container_type = self.host_info.select_container_type_by_kernel() |
534 | + else: |
535 | + if (args.type == 'lxc' and not self.host_info.has_lxc_support()) or \ |
536 | + (args.type == 'lxd' and not self.host_info.has_lxd_support()): |
537 | + libertine.utils.get_logger().error(utils._("System kernel does not support {type} type containers. " |
538 | + "Please either use chroot or omit the -t option.").format(type=args.type)) |
539 | + sys.exit(1) |
540 | + container_type = args.type |
541 | + |
542 | password = None |
543 | + if container_type == "lxc" or container_type == "lxd": |
544 | + if args.password: |
545 | + password = args.password |
546 | + elif sys.stdin.isatty(): |
547 | + print(utils._("Enter password for your user in the Libertine container or leave blank for no password:")) |
548 | + password = getpass.getpass() |
549 | + else: |
550 | + password = sys.stdin.readline().rstrip() |
551 | |
552 | if args.distro and not self.host_info.is_distro_valid(args.distro, args.force): |
553 | utils.get_logger().error(utils._("Invalid distro {distro}").format(distro=args.distro)) |
554 | @@ -67,16 +84,6 @@ |
555 | "form ([a-z0-9][a-z0-9+.-]+).").format(container_id=args.id)) |
556 | sys.exit(1) |
557 | |
558 | - if not args.type: |
559 | - container_type = self.host_info.select_container_type_by_kernel() |
560 | - else: |
561 | - if (args.type == 'lxc' and not self.host_info.has_lxc_support()) or \ |
562 | - (args.type == 'lxd' and not self.host_info.has_lxd_support()): |
563 | - utils.get_logger().error(utils._("System kernel does not support {container_type} type containers. " |
564 | - "Please either use chroot or omit the -t option.").format(container_type=args.type)) |
565 | - sys.exit(1) |
566 | - container_type = args.type |
567 | - |
568 | if not args.distro: |
569 | args.distro = self.host_info.get_host_distro_release() |
570 | elif container_type == "chroot": |
571 | @@ -91,15 +98,6 @@ |
572 | if not args.name: |
573 | args.name = "Ubuntu \'" + (self.host_info.get_distro_codename(args.distro) or args.distro) + "\'" |
574 | |
575 | - if container_type == "lxc" or container_type == "lxd": |
576 | - if args.password: |
577 | - password = args.password |
578 | - elif sys.stdin.isatty(): |
579 | - print(utils._("Enter password for your user in the Libertine container or leave blank for no password:")) |
580 | - password = getpass.getpass() |
581 | - else: |
582 | - password = sys.stdin.readline().rstrip() |
583 | - |
584 | self.containers_config.add_new_container(args.id, args.name, container_type, args.distro) |
585 | |
586 | multiarch = 'disabled' |
587 | @@ -125,6 +123,8 @@ |
588 | self.containers_config.delete_container(args.id) |
589 | sys.exit(1) |
590 | |
591 | + container.set_password(password) |
592 | + |
593 | self.containers_config.update_container_install_status(args.id, "ready") |
594 | |
595 | utils.refresh_libertine_scope() |
PASSED: Continuous integration, rev:464 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/505/ /jenkins. canonical. com/libertine/ job/build/ 910 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=amd64, release= xenial+ overlay, testname= default/ 746 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=amd64, release= zesty,testname= default/ 746 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=i386, release= xenial+ overlay, testname= default/ 746 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=i386, release= zesty,testname= default/ 746 /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 921 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 910 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 910/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/910 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/910/ artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 910 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 910/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/910 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/910/ artifact/ output/ *zip*/output. zip
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: /jenkins. canonical. com/libertine/ job/lp- libertine- ci/505/ rebuild
https:/