Merge lp:~larryprice/libertine/liblibertine-plus-libertined into lp:libertine
- liblibertine-plus-libertined
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Larry Price |
Approved revision: | 370 |
Merged at revision: | 388 |
Proposed branch: | lp:~larryprice/libertine/liblibertine-plus-libertined |
Merge into: | lp:libertine |
Diff against target: |
2613 lines (+717/-723) 49 files modified
CMakeLists.txt (+1/-1) cmake/FindGObjectIntrospection.cmake (+0/-61) cmake/ListOperations.cmake (+0/-18) cmake/UseGObjectIntrospection.cmake (+0/-102) common/LibertineConfig.cpp (+1/-9) data/CMakeLists.txt (+1/-1) data/com.canonical.libertine.Service.service (+1/-1) debian/changelog (+7/-0) debian/control (+23/-17) debian/gir1.2-libertine.install (+0/-2) debian/libertine-tools.install (+0/-2) debian/libertined.install (+3/-0) debian/python3-libertine.install (+0/-1) debian/rules (+1/-1) liblibertine/CMakeLists.txt (+3/-30) liblibertine/libertine.cpp (+20/-164) liblibertine/libertine.h (+4/-4) liblibertine/libertined.cpp (+199/-0) liblibertine/libertined.h (+25/-0) python/libertine/ChrootContainer.py (+6/-7) python/libertine/ContainersConfig.py (+9/-0) python/libertine/Libertine.py (+43/-21) python/libertine/LxcContainer.py (+4/-5) python/libertine/LxdContainer.py (+13/-13) python/libertine/service/apt.py (+2/-6) python/libertine/service/container.py (+29/-5) python/libertine/service/manager.py (+8/-1) python/libertine/service/progress.py (+3/-3) python/libertine/service/task_dispatcher.py (+8/-5) python/libertine/service/tasks/__init__.py (+4/-2) python/libertine/service/tasks/base_task.py (+2/-4) python/libertine/service/tasks/container_info_task.py (+21/-5) python/libertine/service/tasks/list_app_ids_task.py (+35/-0) python/libertine/service/tasks/list_apps_task.py (+8/-4) python/libertine/service/tasks/list_task.py (+6/-4) python/libertine/utils.py (+15/-36) snapcraft.yaml (+13/-1) tests/integration/test_libertine_service.py (+26/-16) tests/unit/service/tasks/CMakeLists.txt (+1/-0) tests/unit/service/tasks/test_container_info_task.py (+14/-2) tests/unit/service/tasks/test_list_app_ids_task.py (+59/-0) tests/unit/service/tasks/test_list_task.py (+8/-6) tests/unit/service/test_apt.py (+37/-45) tests/unit/service/test_container.py (+36/-42) tests/unit/service/test_task_dispatcher.py (+14/-7) tests/unit/test_libertine_container.py (+2/-1) tests/unit/test_libertine_gir.py (+0/-65) tools/libertine-container-manager (+1/-2) tools/libertine-lxc-manager (+1/-1) |
To merge this branch: | bzr merge lp:~larryprice/libertine/liblibertine-plus-libertined |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Libertine CI Bot | continuous-integration | Approve | |
Christopher Townsend | Approve | ||
Review via email: mp+315495@code.launchpad.net |
Commit message
Refactor liblibertine as a client wrapper for libertined.
Description of the change
Refactor liblibertine as a client wrapper for libertined.
Libertine CI Bot (libertine-ci-bot) wrote : | # |
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:359
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:360
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:361
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:362
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:363
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:364
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:365
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:366
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:366
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:367
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, this looks good. +1
When we land this in the next release, we'll need to get python3-libertine promoted to main and libertined will be in main.
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:369
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:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
https:/
Executed test runs:
FAILURE: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
FAILURE: https:/
SUCCESS: https:/
deb: https:/
- 370. By Larry Price
-
add a try-except to the dbus session var method
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:370
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:/
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2017-01-13 20:11:25 +0000 |
3 | +++ CMakeLists.txt 2017-01-27 18:57:35 +0000 |
4 | @@ -7,7 +7,6 @@ |
5 | set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}") |
6 | |
7 | find_package(PkgConfig REQUIRED) |
8 | -find_package(GObjectIntrospection REQUIRED) |
9 | include(GNUInstallDirs) |
10 | include(CheckIncludeFile) |
11 | include(CheckFunctionExists) |
12 | @@ -17,6 +16,7 @@ |
13 | include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) |
14 | |
15 | find_package(Qt5Core REQUIRED) |
16 | +find_package(Qt5DBus REQUIRED) |
17 | find_package(Qt5Gui REQUIRED) |
18 | find_package(Qt5Quick REQUIRED) |
19 | find_package(Qt5Widgets REQUIRED) |
20 | |
21 | === removed directory 'cmake' |
22 | === removed file 'cmake/FindGObjectIntrospection.cmake' |
23 | --- cmake/FindGObjectIntrospection.cmake 2015-08-17 20:42:31 +0000 |
24 | +++ cmake/FindGObjectIntrospection.cmake 1970-01-01 00:00:00 +0000 |
25 | @@ -1,61 +0,0 @@ |
26 | -# - try to find gobject-introspection |
27 | -# |
28 | -# Once done this will define |
29 | -# |
30 | -# INTROSPECTION_FOUND - system has gobject-introspection |
31 | -# INTROSPECTION_SCANNER - the gobject-introspection scanner, g-ir-scanner |
32 | -# INTROSPECTION_COMPILER - the gobject-introspection compiler, g-ir-compiler |
33 | -# INTROSPECTION_GENERATE - the gobject-introspection generate, g-ir-generate |
34 | -# INTROSPECTION_GIRDIR |
35 | -# INTROSPECTION_TYPELIBDIR |
36 | -# INTROSPECTION_CFLAGS |
37 | -# INTROSPECTION_LIBS |
38 | -# |
39 | -# Copyright (C) 2010, Pino Toscano, <pino@kde.org> |
40 | -# |
41 | -# Redistribution and use is allowed according to the terms of the BSD license. |
42 | -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. |
43 | - |
44 | -macro(_GIR_GET_PKGCONFIG_VAR _outvar _varname) |
45 | - execute_process( |
46 | - COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=${_varname} gobject-introspection-1.0 |
47 | - OUTPUT_VARIABLE _result |
48 | - RESULT_VARIABLE _null |
49 | - ) |
50 | - |
51 | - if (_null) |
52 | - else() |
53 | - string(REGEX REPLACE "[\r\n]" " " _result "${_result}") |
54 | - string(REGEX REPLACE " +$" "" _result "${_result}") |
55 | - separate_arguments(_result) |
56 | - set(${_outvar} ${_result} CACHE INTERNAL "") |
57 | - endif() |
58 | -endmacro(_GIR_GET_PKGCONFIG_VAR) |
59 | - |
60 | -find_package(PkgConfig) |
61 | -if(PKG_CONFIG_FOUND) |
62 | - if(PACKAGE_FIND_VERSION_COUNT GREATER 0) |
63 | - set(_gir_version_cmp ">=${PACKAGE_FIND_VERSION}") |
64 | - endif() |
65 | - pkg_check_modules(_pc_gir gobject-introspection-1.0${_gir_version_cmp}) |
66 | - if(_pc_gir_FOUND) |
67 | - set(INTROSPECTION_FOUND TRUE) |
68 | - _gir_get_pkgconfig_var(INTROSPECTION_SCANNER "g_ir_scanner") |
69 | - _gir_get_pkgconfig_var(INTROSPECTION_COMPILER "g_ir_compiler") |
70 | - _gir_get_pkgconfig_var(INTROSPECTION_GENERATE "g_ir_generate") |
71 | - _gir_get_pkgconfig_var(INTROSPECTION_GIRDIR "girdir") |
72 | - _gir_get_pkgconfig_var(INTROSPECTION_TYPELIBDIR "typelibdir") |
73 | - set(INTROSPECTION_CFLAGS "${_pc_gir_CFLAGS}") |
74 | - set(INTROSPECTION_LIBS "${_pc_gir_LIBS}") |
75 | - endif() |
76 | -endif() |
77 | - |
78 | -mark_as_advanced( |
79 | - INTROSPECTION_SCANNER |
80 | - INTROSPECTION_COMPILER |
81 | - INTROSPECTION_GENERATE |
82 | - INTROSPECTION_GIRDIR |
83 | - INTROSPECTION_TYPELIBDIR |
84 | - INTROSPECTION_CFLAGS |
85 | - INTROSPECTION_LIBS |
86 | -) |
87 | |
88 | === removed file 'cmake/ListOperations.cmake' |
89 | --- cmake/ListOperations.cmake 2015-08-17 20:42:31 +0000 |
90 | +++ cmake/ListOperations.cmake 1970-01-01 00:00:00 +0000 |
91 | @@ -1,18 +0,0 @@ |
92 | - |
93 | -macro(list_prefix _outvar _listvar _prefix) |
94 | - set(${_outvar}) |
95 | - foreach(_item IN LISTS ${_listvar}) |
96 | - list(APPEND ${_outvar} ${_prefix}${_item}) |
97 | - endforeach() |
98 | -endmacro(list_prefix) |
99 | - |
100 | -macro(list_make_absolute _outvar _listvar _prefix) |
101 | - set(${_outvar}) |
102 | - foreach(_item IN LISTS ${_listvar}) |
103 | - if(IS_ABSOLUTE ${_item}) |
104 | - list(APPEND ${_outvar} ${_item}) |
105 | - else() |
106 | - list(APPEND ${_outvar} ${_prefix}${_item}) |
107 | - endif() |
108 | - endforeach() |
109 | -endmacro(list_make_absolute) |
110 | |
111 | === removed file 'cmake/UseGObjectIntrospection.cmake' |
112 | --- cmake/UseGObjectIntrospection.cmake 2015-08-17 20:42:31 +0000 |
113 | +++ cmake/UseGObjectIntrospection.cmake 1970-01-01 00:00:00 +0000 |
114 | @@ -1,102 +0,0 @@ |
115 | -# Copyright (C) 2010, Pino Toscano, <pino@kde.org> |
116 | -# |
117 | -# Redistribution and use is allowed according to the terms of the BSD license. |
118 | -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. |
119 | - |
120 | -include(ListOperations) |
121 | - |
122 | -macro(_gir_list_prefix _outvar _listvar _prefix) |
123 | - set(${_outvar}) |
124 | - foreach(_item IN LISTS ${_listvar}) |
125 | - list(APPEND ${_outvar} ${_prefix}${_item}) |
126 | - endforeach() |
127 | -endmacro(_gir_list_prefix) |
128 | - |
129 | -macro(gir_add_introspections introspections_girs) |
130 | - |
131 | - foreach(gir IN LISTS ${introspections_girs}) |
132 | - |
133 | - set(_gir_name "${gir}") |
134 | - |
135 | - ## Transform the gir filename to something which can reference through a variable |
136 | - ## without automake/make complaining, eg Gtk-2.0.gir -> Gtk_2_0_gir |
137 | - string(REPLACE "-" "_" _gir_name "${_gir_name}") |
138 | - string(REPLACE "." "_" _gir_name "${_gir_name}") |
139 | - |
140 | - # Namespace and Version is either fetched from the gir filename |
141 | - # or the _NAMESPACE/_VERSION variable combo |
142 | - set(_gir_namespace "${${_gir_name}_NAMESPACE}") |
143 | - if (_gir_namespace STREQUAL "") |
144 | - string(REGEX REPLACE "([^-]+)-.*" "\\1" _gir_namespace "${gir}") |
145 | - endif () |
146 | - set(_gir_version "${${_gir_name}_VERSION}") |
147 | - if (_gir_version STREQUAL "") |
148 | - string(REGEX REPLACE ".*-([^-]+).gir" "\\1" _gir_version "${gir}") |
149 | - endif () |
150 | - |
151 | - # _PROGRAM is an optional variable which needs it's own --program argument |
152 | - set(_gir_program "${${_gir_name}_PROGRAM}") |
153 | - if (NOT _gir_program STREQUAL "") |
154 | - set(_gir_program "--program=${_gir_program}") |
155 | - endif () |
156 | - |
157 | - # Variables which provides a list of things |
158 | - _gir_list_prefix(_gir_libraries ${_gir_name}_LIBS "--library=") |
159 | - _gir_list_prefix(_gir_packages ${_gir_name}_PACKAGES "--pkg=") |
160 | - _gir_list_prefix(_gir_includes ${_gir_name}_INCLUDES "--include=") |
161 | - _gir_list_prefix(_gir_export_packages ${_gir_name}_EXPORT_PACKAGES "--pkg-export=") |
162 | - |
163 | - # Reuse the LIBTOOL variable from by automake if it's set |
164 | - set(_gir_libtool "--no-libtool") |
165 | - |
166 | - add_custom_command( |
167 | - COMMAND ${INTROSPECTION_SCANNER} |
168 | - ${INTROSPECTION_SCANNER_ARGS} |
169 | - --quiet |
170 | - --warn-all |
171 | - --namespace=${_gir_namespace} |
172 | - --nsversion=${_gir_version} |
173 | - ${_gir_libtool} |
174 | - ${_gir_program} |
175 | - ${_gir_libraries} |
176 | - ${_gir_packages} |
177 | - ${_gir_includes} |
178 | - ${_gir_export_packages} |
179 | - ${${_gir_name}_SCANNERFLAGS} |
180 | - ${${_gir_name}_CFLAGS} |
181 | - ${${_gir_name}_FILES} |
182 | - --output ${CMAKE_CURRENT_BINARY_DIR}/${gir} |
183 | - DEPENDS ${${_gir_name}_FILES} |
184 | - ${${_gir_name}_LIBS} |
185 | - OUTPUT ${gir} |
186 | - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} |
187 | - VERBATIM |
188 | - ) |
189 | - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${gir} DESTINATION share/gir-1.0) |
190 | - |
191 | - string(REPLACE ".gir" ".typelib" _typelib "${gir}") |
192 | - add_custom_command( |
193 | - COMMAND ${INTROSPECTION_COMPILER} |
194 | - ${INTROSPECTION_COMPILER_ARGS} |
195 | - --includedir=. |
196 | - ${CMAKE_CURRENT_BINARY_DIR}/${gir} |
197 | - -o ${CMAKE_CURRENT_BINARY_DIR}/${_typelib} |
198 | - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir} |
199 | - OUTPUT ${_typelib} |
200 | - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
201 | - ) |
202 | - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_typelib} DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0) |
203 | - |
204 | - add_custom_target(gir-${gir} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${gir}) |
205 | - add_custom_target(gir-typelibs-${_typelib} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_typelib}) |
206 | - endforeach() |
207 | - |
208 | -endmacro(gir_add_introspections) |
209 | - |
210 | -macro(gir_get_cflags _output) |
211 | - get_directory_property(_tmp_includes INCLUDE_DIRECTORIES) |
212 | - list_prefix(_includes _tmp_includes "-I") |
213 | - get_directory_property(_tmp_compile_definitions COMPILE_DEFINITIONS) |
214 | - list_prefix(_compile_definitions _tmp_compile_definitions "-D") |
215 | - set(${_output} ${_includes} ${_compile_definitions}) |
216 | -endmacro(gir_get_cflags) |
217 | |
218 | === modified file 'common/LibertineConfig.cpp' |
219 | --- common/LibertineConfig.cpp 2017-01-18 15:43:03 +0000 |
220 | +++ common/LibertineConfig.cpp 2017-01-27 18:57:35 +0000 |
221 | @@ -3,7 +3,7 @@ |
222 | * @brief Libertine Manager application-wide configuration module |
223 | */ |
224 | /* |
225 | - * Copyright 2015 Canonical Ltd |
226 | + * Copyright 2015-2017 Canonical Ltd |
227 | * |
228 | * Libertine is free software: you can redistribute it and/or modify it under |
229 | * the terms of the GNU General Public License, version 3, as published by the |
230 | @@ -36,14 +36,6 @@ |
231 | path.replace(std::getenv("HOME"), snap_common); |
232 | } |
233 | |
234 | - // if libertine is installed as a snap but caller is not; |
235 | - // workaround until ContainersConfig is only discovered from one location |
236 | - if (QString(std::getenv("IGNORE_SNAP")) != "1" && QFile::exists("/snap/bin/libertine.libertine-launch")) |
237 | - { |
238 | - auto home = std::getenv("HOME"); |
239 | - path.replace(home, QString(home) + "/snap/libertine/common"); |
240 | - } |
241 | - |
242 | QDir dir(path); |
243 | |
244 | if (!dir.exists()) |
245 | |
246 | === modified file 'data/CMakeLists.txt' |
247 | --- data/CMakeLists.txt 2016-12-21 20:57:15 +0000 |
248 | +++ data/CMakeLists.txt 2017-01-27 18:57:35 +0000 |
249 | @@ -8,7 +8,7 @@ |
250 | DESTINATION ${CMAKE_INSTALL_DATADIR}/upstart/sessions) |
251 | install(FILES libertine-lxc-sudo libertine-lxd-sudo |
252 | DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/sudoers.d) |
253 | -install(FILES com.canonical.libertine.ContainerManager.service |
254 | +install(FILES com.canonical.libertine.Service.service |
255 | com.canonical.libertine.LxcManager.service |
256 | com.canonical.libertine.LxdManager.service |
257 | DESTINATION ${CMAKE_INSTALL_DATADIR}/dbus-1/services) |
258 | |
259 | === renamed file 'data/com.canonical.libertine.ContainerManager.service' => 'data/com.canonical.libertine.Service.service' |
260 | --- data/com.canonical.libertine.ContainerManager.service 2016-11-01 20:10:58 +0000 |
261 | +++ data/com.canonical.libertine.Service.service 2017-01-27 18:57:35 +0000 |
262 | @@ -1,3 +1,3 @@ |
263 | [D-BUS Service] |
264 | -Name=com.canonical.libertine.ContainerManager |
265 | +Name=com.canonical.libertine.Service |
266 | Exec=/usr/bin/libertined --cache-output |
267 | |
268 | === modified file 'debian/changelog' |
269 | --- debian/changelog 2017-01-18 14:50:33 +0000 |
270 | +++ debian/changelog 2017-01-27 18:57:35 +0000 |
271 | @@ -1,3 +1,10 @@ |
272 | +libertine (1.5.2-0ubuntu1) UNRELEASED; urgency=medium |
273 | + |
274 | + [ Larry Price ] |
275 | + * Bump version to 1.5.2. |
276 | + |
277 | + -- Larry Price <larry.price@canonical.com> Thu, 26 Jan 2017 10:39:10 -0500 |
278 | + |
279 | libertine (1.5.1+17.04.20170118-0ubuntu1) zesty; urgency=medium |
280 | |
281 | [ Chris Townsend ] |
282 | |
283 | === modified file 'debian/control' |
284 | --- debian/control 2016-12-07 17:45:28 +0000 |
285 | +++ debian/control 2017-01-27 18:57:35 +0000 |
286 | @@ -84,7 +84,6 @@ |
287 | Architecture: any |
288 | Depends: libglib2.0-bin, |
289 | lsb-release, |
290 | - python3-apt, |
291 | python3-dbus, |
292 | python3-distro-info, |
293 | python3-libertine, |
294 | @@ -115,15 +114,33 @@ |
295 | Helper applications for using and interacting with Xmir such as launching |
296 | Xmir and allowing copy and paste. |
297 | |
298 | +Package: libertined |
299 | +Architecture: any |
300 | +Multi-Arch: same |
301 | +Depends: python3-libertine, |
302 | + python3-apt, |
303 | + python3-dbus, |
304 | + python3-gi, |
305 | + ${misc:Depends}, |
306 | + ${shlibs:Depends}, |
307 | + ${python3:Depends} |
308 | +Breaks: libertine-tools (<< 1.5.2) |
309 | +Replaces: libertine-tools (<< 1.5.2) |
310 | +Description: d-bus service for managing libertine containers |
311 | + D-Bus service for asynchronously discovering and managing classic applications |
312 | + using libertine containers. Allows installation and removal of deb-packaged |
313 | + X11 apps within an isolated sandbox. |
314 | + |
315 | Package: liblibertine1 |
316 | Architecture: any |
317 | Multi-Arch: same |
318 | -Depends: ${misc:Depends}, |
319 | +Depends: libertined, |
320 | + ${misc:Depends}, |
321 | ${shlibs:Depends} |
322 | Description: runtime for running deb-packaged X11 apps on Ubuntu Personal |
323 | Runtime library for creating and using the Ubuntu Personal sandbox for legacy |
324 | Deb-packaged X11 applicatons. This library is used by the Libertine tools |
325 | - and other software interacting wit hthe Libertine container, such as scopes |
326 | + and other software interacting with the Libertine container, such as scopes |
327 | or application launchers. |
328 | |
329 | Package: liblibertine-dev |
330 | @@ -137,24 +154,11 @@ |
331 | Headers and shared libraries used to create the tools for creating and using |
332 | the Ubuntu Personal sandbox for legacy Deb-packaged X11 applicatons. |
333 | |
334 | -Package: gir1.2-libertine |
335 | -Architecture: any |
336 | -Multi-Arch: same |
337 | -Depends: liblibertine1 (= ${binary:Version}), |
338 | - ${gir:Depends}, |
339 | - ${misc:Depends} |
340 | -Description: GObject introspection files for the Libertine application sandbox |
341 | - The GObject introspection description files for the Libertine application |
342 | - sandbox runtime. This package allows the Libertine API to be used from |
343 | - GIR-compliant languages such as Python. |
344 | - |
345 | Package: python3-libertine |
346 | Architecture: any |
347 | Section: python |
348 | Multi-Arch: allowed |
349 | -Depends: gir1.2-libertine, |
350 | - python3-gi, |
351 | - python3-psutil, |
352 | +Depends: python3-psutil, |
353 | python3-xdg, |
354 | xdg-user-dirs, |
355 | ${misc:Depends}, |
356 | @@ -173,6 +177,7 @@ |
357 | python3-libertine, |
358 | python3-lxc, |
359 | uidmap, |
360 | + python3-gi, |
361 | ${misc:Depends}, |
362 | ${python3:Depends} |
363 | Replaces: libertine-tools (<< 1.3) |
364 | @@ -190,6 +195,7 @@ |
365 | python3-libertine, |
366 | python3-pexpect, |
367 | python3-pylxd, |
368 | + python3-gi, |
369 | ${misc:Depends}, |
370 | ${python3:Depends} |
371 | Description: Python3 scripts for the Libertine application sandbox |
372 | |
373 | === removed file 'debian/gir1.2-libertine.install' |
374 | --- debian/gir1.2-libertine.install 2015-08-24 16:54:54 +0000 |
375 | +++ debian/gir1.2-libertine.install 1970-01-01 00:00:00 +0000 |
376 | @@ -1,2 +0,0 @@ |
377 | -usr/lib/*/girepository-1.0/Libertine-1.typelib |
378 | -usr/share/gir-1.0/Libertine-1.gir |
379 | |
380 | === modified file 'debian/libertine-tools.install' |
381 | --- debian/libertine-tools.install 2016-11-01 20:10:58 +0000 |
382 | +++ debian/libertine-tools.install 2017-01-27 18:57:35 +0000 |
383 | @@ -1,6 +1,4 @@ |
384 | usr/bin/libertine-container-manager |
385 | usr/bin/libertine-launch |
386 | -usr/bin/libertined |
387 | -usr/share/dbus-1/services/com.canonical.libertine.ContainerManager.service |
388 | usr/share/bash-completion/completions/libertine-container-manager |
389 | usr/share/man |
390 | |
391 | === added file 'debian/libertined.install' |
392 | --- debian/libertined.install 1970-01-01 00:00:00 +0000 |
393 | +++ debian/libertined.install 2017-01-27 18:57:35 +0000 |
394 | @@ -0,0 +1,3 @@ |
395 | +usr/bin/libertined |
396 | +usr/lib/python*/*/libertine/service |
397 | +usr/share/dbus-1/services/com.canonical.libertine.Service.service |
398 | |
399 | === modified file 'debian/python3-libertine.install' |
400 | --- debian/python3-libertine.install 2016-12-21 18:07:07 +0000 |
401 | +++ debian/python3-libertine.install 2017-01-27 18:57:35 +0000 |
402 | @@ -5,5 +5,4 @@ |
403 | usr/lib/python*/*/libertine/__init__.py |
404 | usr/lib/python*/*/libertine/launcher |
405 | usr/lib/python*/*/libertine/lifecycle |
406 | -usr/lib/python*/*/libertine/service |
407 | usr/lib/python*/*/libertine/utils.py |
408 | |
409 | === modified file 'debian/rules' |
410 | --- debian/rules 2016-12-06 20:52:55 +0000 |
411 | +++ debian/rules 2017-01-27 18:57:35 +0000 |
412 | @@ -1,7 +1,7 @@ |
413 | #!/usr/bin/make -f |
414 | |
415 | %: |
416 | - dh $@ --with python3,gir |
417 | + dh $@ --with python3 |
418 | |
419 | override_dh_auto_test: |
420 | dbus-run-session -- dh_auto_test |
421 | |
422 | === modified file 'liblibertine/CMakeLists.txt' |
423 | --- liblibertine/CMakeLists.txt 2016-11-03 19:19:40 +0000 |
424 | +++ liblibertine/CMakeLists.txt 2017-01-27 18:57:35 +0000 |
425 | @@ -1,15 +1,12 @@ |
426 | set(API_VERSION 1) |
427 | set(ABI_VERSION 1) |
428 | |
429 | -set(COMMON_DIR ${CMAKE_SOURCE_DIR}/common) |
430 | - |
431 | add_library( |
432 | ${LIBERTINE_CORE} SHARED |
433 | libertine.cpp |
434 | |
435 | - ${COMMON_DIR}/ContainerConfig.cpp |
436 | - ${COMMON_DIR}/ContainerConfigList.cpp |
437 | - ${COMMON_DIR}/LibertineConfig.cpp |
438 | + # libertined client |
439 | + libertined.cpp |
440 | ) |
441 | |
442 | set_target_properties(${LIBERTINE_CORE} PROPERTIES |
443 | @@ -22,6 +19,7 @@ |
444 | ${GLIB2_LIBRARIES} |
445 | ${PYTHON3_LIBRARIES} |
446 | Qt5::Core |
447 | + Qt5::DBus |
448 | ) |
449 | |
450 | # "liblibertine_headers_path" is used in libertine.pc.in |
451 | @@ -32,28 +30,3 @@ |
452 | configure_file(libertine.pc.in ${CMAKE_BINARY_DIR}/libertine.pc @ONLY) |
453 | install(FILES ${CMAKE_BINARY_DIR}/libertine.pc |
454 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) |
455 | - |
456 | -########################## |
457 | -# Introspection |
458 | -########################## |
459 | - |
460 | -include(UseGObjectIntrospection) |
461 | - |
462 | -set(INTROSPECTION_GIRS) |
463 | -set(_introspection_files libertine.h) |
464 | -set(Libertine_1_gir "libertine") |
465 | -set(Libertine_1_gir_INCLUDES GObject-2.0) |
466 | - |
467 | -gir_get_cflags(_cflags) |
468 | -set(Libertine_1_gir_CFLAGS ${c_flags}) |
469 | -set(Libertine_1_gir_LIBS libertine) |
470 | - |
471 | -list_make_absolute(_abs_introspection_files _introspection_files "${CMAKE_CURRENT_SOURCE_DIR}/") |
472 | -set(Libertine_1_gir_FILES ${_abs_introspection_files}) |
473 | -set(Libertine_1_gir_SCANNERFLAGS --c-include "libertine.h") |
474 | -set(Libertine_1_gir_EXPORT_PACKAGES "libertine-${API_VERSION}") |
475 | - |
476 | -list(APPEND INTROSPECTION_GIRS Libertine-1.gir) |
477 | -gir_add_introspections(INTROSPECTION_GIRS) |
478 | - |
479 | -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Libertine-1.typelib" DESTINATION "${CMAKE_INSTALL_LIBDIR}/girepository-1.0") |
480 | |
481 | === modified file 'liblibertine/libertine.cpp' |
482 | --- liblibertine/libertine.cpp 2017-01-18 15:43:03 +0000 |
483 | +++ liblibertine/libertine.cpp 2017-01-27 18:57:35 +0000 |
484 | @@ -1,9 +1,9 @@ |
485 | /** |
486 | - * @file libertine_common.cpp |
487 | + * @file libertine.cpp |
488 | * @brief The Libertine Common shared library |
489 | */ |
490 | /* |
491 | - * Copyright 2015 Canonical Ltd. |
492 | + * Copyright 2015-2017 Canonical Ltd. |
493 | * |
494 | * This program is free software: you can redistribute it and/or modify it under |
495 | * the terms of the GNU General Public License, version 3, as published by the |
496 | @@ -17,121 +17,21 @@ |
497 | * You should have received a copy of the GNU General Public License |
498 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
499 | */ |
500 | + |
501 | #include "liblibertine/libertine.h" |
502 | - |
503 | -#include "common/ContainerConfigList.h" |
504 | -#include "common/LibertineConfig.h" |
505 | - |
506 | - |
507 | -namespace |
508 | -{ |
509 | -constexpr auto DESKTOP_EXTENSION = ".desktop"; |
510 | -constexpr auto GLOBAL_APPLICATIONS = "usr/share/applications"; |
511 | -constexpr auto LOCAL_APPLICATIONS = ".local/share/applications"; |
512 | - |
513 | - |
514 | -GError* |
515 | -list_apps_from_path(gchar* path, const gchar* container_id, GArray* apps) |
516 | -{ |
517 | - GError* error = nullptr; |
518 | - GDir* dir = g_dir_open(path, 0, &error); |
519 | - if (error != nullptr) |
520 | - { |
521 | - return error; |
522 | - } |
523 | - |
524 | - const gchar * files; |
525 | - while ((files = g_dir_read_name(dir)) != nullptr) |
526 | - { |
527 | - gchar *file = g_build_filename(path, files, nullptr); |
528 | - if (g_file_test(file, G_FILE_TEST_IS_REGULAR) && g_str_has_suffix(files, DESKTOP_EXTENSION)) |
529 | - { |
530 | - auto name = g_strdup(files); |
531 | - name[strlen(name)-strlen(DESKTOP_EXTENSION)] = 0; // truncate the file extension |
532 | - |
533 | - gchar * app_id = g_strjoin("_", g_strdup(container_id), name, "0.0", nullptr); |
534 | - g_array_append_val(apps, app_id); |
535 | - g_free(name); |
536 | - } |
537 | - else if (g_file_test(file, G_FILE_TEST_IS_DIR)) |
538 | - { |
539 | - error = list_apps_from_path(file, container_id, apps); |
540 | - if (error != nullptr) |
541 | - { |
542 | - return error; |
543 | - } |
544 | - } |
545 | - g_free(file); |
546 | - } |
547 | - |
548 | - g_dir_close(dir); |
549 | - return nullptr; |
550 | -} |
551 | - |
552 | - |
553 | -gchar* |
554 | -id_from_list_index(const ContainerConfigList& container_list, guint index) |
555 | -{ |
556 | - return (gchar*)container_list.data(container_list.index(index, 0), |
557 | - (int)ContainerConfigList::DataRole::ContainerId) |
558 | - .toString().toStdString().c_str(); |
559 | -} |
560 | - |
561 | - |
562 | -bool |
563 | -running_snapped_libertine() |
564 | -{ |
565 | - if (g_strcmp0(std::getenv("IGNORE_SNAP"), "1") == 0) |
566 | - { |
567 | - return false; |
568 | - } |
569 | - |
570 | - auto libertine_launch_path = g_build_filename("/", "snap", "bin", |
571 | - "libertine.libertine-launch", |
572 | - nullptr); |
573 | - bool out = g_file_test(libertine_launch_path, G_FILE_TEST_EXISTS); |
574 | - |
575 | - g_free(libertine_launch_path); |
576 | - return out; |
577 | -} |
578 | -} |
579 | +#include "liblibertine/libertined.h" |
580 | + |
581 | |
582 | gchar** |
583 | libertine_list_apps_for_container(const gchar* container_id) |
584 | { |
585 | g_return_val_if_fail(container_id != nullptr, nullptr); |
586 | - gchar* path = libertine_container_path(container_id); |
587 | - GError* error = nullptr; |
588 | GArray* apps = g_array_new(TRUE, TRUE, sizeof(gchar*)); |
589 | - |
590 | - if (path != nullptr) |
591 | - { |
592 | - auto global_path = g_build_filename("/", g_strdup(path), GLOBAL_APPLICATIONS, nullptr); |
593 | - error = list_apps_from_path(global_path, container_id, apps); |
594 | - if (error != nullptr) |
595 | - { |
596 | - g_free(global_path); |
597 | - g_free(path); |
598 | - g_error_free(error); |
599 | - return (gchar**)g_array_free(apps, FALSE); |
600 | - } |
601 | - g_free(global_path); |
602 | - } |
603 | - g_free(path); |
604 | - |
605 | - auto home_path = libertine_container_home_path(container_id); |
606 | - if (home_path != nullptr) |
607 | - { |
608 | - auto local_path = g_build_filename(home_path, LOCAL_APPLICATIONS, nullptr); |
609 | - |
610 | - error = list_apps_from_path(local_path, container_id, apps); |
611 | - if (error != nullptr) |
612 | - { |
613 | - g_error_free(error); // free error, but return previously found apps |
614 | - } |
615 | - g_free(local_path); |
616 | - } |
617 | - g_free(home_path); |
618 | + for (auto const& app: libertined_list_app_ids(container_id)) |
619 | + { |
620 | + auto app_id = g_strdup((gchar *)app.toString().toStdString().c_str()); |
621 | + g_array_append_val(apps, app_id); |
622 | + } |
623 | |
624 | return (gchar**)g_array_free(apps, FALSE); |
625 | } |
626 | @@ -140,22 +40,12 @@ |
627 | gchar ** |
628 | libertine_list_containers(void) |
629 | { |
630 | - guint container_count; |
631 | - guint i; |
632 | - LibertineConfig config; |
633 | - ContainerConfigList container_list(&config); |
634 | - GArray * containers = g_array_new(TRUE, TRUE, sizeof(gchar *)); |
635 | - QVariant id; |
636 | - |
637 | - container_count = (guint)container_list.size(); |
638 | - |
639 | - for (i = 0; i < container_count; ++i) |
640 | + auto containers = g_array_new(TRUE, TRUE, sizeof(gchar *)); |
641 | + for (auto const& container: libertined_list()) |
642 | { |
643 | - id = container_list.data(container_list.index(i, 0), (int)ContainerConfigList::DataRole::ContainerId); |
644 | - gchar * container_id = g_strdup((gchar *)id.toString().toStdString().c_str()); |
645 | + auto container_id = g_strdup((gchar *)container.toString().toStdString().c_str()); |
646 | g_array_append_val(containers, container_id); |
647 | } |
648 | - |
649 | return (gchar **)g_array_free(containers, FALSE); |
650 | } |
651 | |
652 | @@ -164,19 +54,8 @@ |
653 | libertine_container_path(const gchar * container_id) |
654 | { |
655 | g_return_val_if_fail(container_id != nullptr, nullptr); |
656 | - LibertineConfig config; |
657 | - ContainerConfigList container_list(&config); |
658 | - gchar* path = g_build_filename(g_get_user_cache_dir(), "libertine-container", container_id, "rootfs", nullptr); |
659 | - |
660 | - // temporary solution for discovering applications in unity8 until libertined |
661 | - // has been updated to access location data |
662 | - if (running_snapped_libertine()) |
663 | - { |
664 | - g_free(path); |
665 | - path = g_build_filename("/", "home", g_get_user_name(), "snap", "libertine", "common", ".cache", "libertine-container", container_id, "rootfs", nullptr); |
666 | - } |
667 | - |
668 | - |
669 | + |
670 | + gchar* path = g_strdup((gchar *)libertined_container_path(container_id).toStdString().c_str()); |
671 | if (g_file_test(path, G_FILE_TEST_EXISTS)) |
672 | { |
673 | return path; |
674 | @@ -191,18 +70,8 @@ |
675 | libertine_container_home_path(const gchar * container_id) |
676 | { |
677 | g_return_val_if_fail(container_id != nullptr, nullptr); |
678 | - LibertineConfig config; |
679 | - ContainerConfigList container_list(&config); |
680 | - gchar * path = g_build_filename(g_get_user_data_dir(), "libertine-container", "user-data", container_id, nullptr); |
681 | - |
682 | - // temporary solution for discovering applications in unity8 until libertined |
683 | - // has been updated to access location data |
684 | - if (running_snapped_libertine()) |
685 | - { |
686 | - g_free(path); |
687 | - path = g_build_filename("/", "home", g_get_user_name(), "snap", "libertine", "common", ".local", "libertine-container", "user-data", container_id, nullptr); |
688 | - } |
689 | - |
690 | + |
691 | + gchar* path = g_strdup((gchar *)libertined_container_home_path(container_id).toStdString().c_str()); |
692 | if (g_file_test(path, G_FILE_TEST_EXISTS)) |
693 | { |
694 | return path; |
695 | @@ -216,20 +85,7 @@ |
696 | gchar * |
697 | libertine_container_name(const gchar * container_id) |
698 | { |
699 | - gchar * container_name = nullptr; |
700 | - LibertineConfig config; |
701 | - ContainerConfigList container_list(&config); |
702 | - guint container_count = (guint)container_list.size(); |
703 | - |
704 | - for (guint i = 0; i < container_count; ++i) |
705 | - { |
706 | - if (g_strcmp0(id_from_list_index(container_list, i), container_id) == 0) |
707 | - { |
708 | - QVariant name = container_list.data(container_list.index(i, 0), (int)ContainerConfigList::DataRole::ContainerName); |
709 | - container_name = g_strdup(name.toString().toStdString().c_str()); |
710 | - break; |
711 | - } |
712 | - } |
713 | - |
714 | - return container_name; |
715 | + g_return_val_if_fail(container_id != nullptr, nullptr); |
716 | + |
717 | + return g_strdup((gchar *)libertined_container_name(container_id).toStdString().c_str()); |
718 | } |
719 | |
720 | === modified file 'liblibertine/libertine.h' |
721 | --- liblibertine/libertine.h 2016-09-06 12:36:47 +0000 |
722 | +++ liblibertine/libertine.h 2017-01-27 18:57:35 +0000 |
723 | @@ -1,5 +1,5 @@ |
724 | /* |
725 | - * Copyright 2015 Canonical Ltd. |
726 | + * Copyright 2015-2017 Canonical Ltd. |
727 | * |
728 | * This program is free software: you can redistribute it and/or modify it under |
729 | * the terms of the GNU General Public License, version 3, as published by the |
730 | @@ -15,8 +15,8 @@ |
731 | */ |
732 | #include <glib.h> |
733 | |
734 | -#ifndef _LIBERTINE_COMMON_H_ |
735 | -#define _LIBERTINE_COMMON_H_ |
736 | +#ifndef _LIBLIBERTINE_H_ |
737 | +#define _LIBLIBERTINE_H_ |
738 | |
739 | #ifdef __cplusplus |
740 | extern "C" { |
741 | @@ -80,4 +80,4 @@ |
742 | } |
743 | #endif |
744 | |
745 | -#endif /* _LIBERTINE_COMMON_H_ */ |
746 | +#endif /* _LIBLIBERTINE_H_ */ |
747 | |
748 | === added file 'liblibertine/libertined.cpp' |
749 | --- liblibertine/libertined.cpp 1970-01-01 00:00:00 +0000 |
750 | +++ liblibertine/libertined.cpp 2017-01-27 18:57:35 +0000 |
751 | @@ -0,0 +1,199 @@ |
752 | +/* |
753 | + * Copyright 2017 Canonical Ltd |
754 | + * |
755 | + * Libertine is free software: you can redistribute it and/or modify it under |
756 | + * the terms of the GNU General Public License, version 3, as published by the |
757 | + * Free Software Foundation. |
758 | + * |
759 | + * Libertine is distributed in the hope that it will be useful, but WITHOUT ANY |
760 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
761 | + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
762 | + * |
763 | + * You should have received a copy of the GNU General Public License |
764 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
765 | + */ |
766 | + |
767 | + |
768 | +#include "libertined.h" |
769 | + |
770 | +#include <QDBusMessage> |
771 | +#include <QDBusInterface> |
772 | +#include <QDebug> |
773 | +#include <thread> |
774 | +#include <chrono> |
775 | +#include <QJsonDocument> |
776 | +#include <QJsonArray> |
777 | +#include <QJsonObject> |
778 | + |
779 | +namespace |
780 | +{ |
781 | +static const auto SERVICE_INTERFACE = "com.canonical.libertine.Service"; |
782 | +static const auto PROGRESS_INTERFACE = "com.canonical.libertine.Service.Progress"; |
783 | + |
784 | +static QVariantList |
785 | +dbusCall(QDBusConnection const& bus, QString const& iface, QString const& path, |
786 | + QString const& method, QVariantList const& args = QVariantList()) |
787 | +{ |
788 | + auto message = QDBusMessage::createMethodCall(SERVICE_INTERFACE, path, iface, method); |
789 | + message.setArguments(args); |
790 | + auto response = bus.call(message); |
791 | + if (response.type() == QDBusMessage::ErrorMessage) |
792 | + { |
793 | + qWarning() << "error calling result" << response.errorMessage(); |
794 | + return QVariantList(); |
795 | + } |
796 | + |
797 | + return response.arguments(); |
798 | +} |
799 | + |
800 | +static bool |
801 | +isRunning(QDBusConnection const& bus, QString const& path) |
802 | +{ |
803 | + auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "running", QVariantList()); |
804 | + |
805 | + if (args.isEmpty()) |
806 | + { |
807 | + qWarning() << "lastError - no arguments?"; |
808 | + return false; |
809 | + } |
810 | + |
811 | + return args.first().toBool(); |
812 | +} |
813 | + |
814 | +static QString |
815 | +result(QDBusConnection const& bus, QString const& path) |
816 | +{ |
817 | + auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "result"); |
818 | + |
819 | + if (args.isEmpty()) |
820 | + { |
821 | + qWarning() << "lastError - no arguments?"; |
822 | + return ""; |
823 | + } |
824 | + |
825 | + return args.first().toString(); |
826 | +} |
827 | + |
828 | +static QString |
829 | +lastError(QDBusConnection const& bus, QString const& path) |
830 | +{ |
831 | + auto args = dbusCall(bus, PROGRESS_INTERFACE, path, "last_error"); |
832 | + |
833 | + if (args.isEmpty()) |
834 | + { |
835 | + qWarning() << "lastError - no arguments?"; |
836 | + return ""; |
837 | + } |
838 | + |
839 | + return args.first().toString(); |
840 | +} |
841 | + |
842 | +static QString |
843 | +call(QDBusConnection const& bus, QString const& method, QVariantList const& args) |
844 | +{ |
845 | + auto results = dbusCall(bus, SERVICE_INTERFACE, "/Manager", method, args); |
846 | + |
847 | + if (results.isEmpty()) |
848 | + { |
849 | + return QString(); |
850 | + } |
851 | + |
852 | + return qvariant_cast<QDBusObjectPath>(results.first()).path(); |
853 | +} |
854 | + |
855 | +static bool |
856 | +waitForFinish(QDBusConnection const& bus, QString const& path) |
857 | +{ |
858 | + std::chrono::microseconds wait(500); |
859 | + for (auto i = 0; i < 2000; ++i) |
860 | + { |
861 | + if (!isRunning(bus, path)) |
862 | + { |
863 | + return true; |
864 | + } |
865 | + std::this_thread::sleep_for(wait); |
866 | + } |
867 | + return !isRunning(bus, path); |
868 | +} |
869 | + |
870 | +QString |
871 | +container_info(char const* container_id, QString const& key) |
872 | +{ |
873 | + auto bus = QDBusConnection::sessionBus(); |
874 | + auto path = call(bus, "container_info", QVariantList{QVariant(container_id)}); |
875 | + |
876 | + if (!waitForFinish(bus, path)) |
877 | + { |
878 | + return QString(); |
879 | + } |
880 | + |
881 | + auto error = lastError(bus, path); |
882 | + if (!error.isEmpty()) |
883 | + { |
884 | + qWarning() << "error:" << error; |
885 | + return QString(); |
886 | + } |
887 | + |
888 | + return QJsonDocument::fromJson(result(bus, path).toLatin1()).object().value(key).toString(); |
889 | +} |
890 | +} |
891 | + |
892 | +QJsonArray |
893 | +libertined_list() |
894 | +{ |
895 | + auto bus = QDBusConnection::sessionBus(); |
896 | + auto path = call(bus, "list", QVariantList()); |
897 | + |
898 | + if (!waitForFinish(bus, path)) |
899 | + { |
900 | + return QJsonArray(); |
901 | + } |
902 | + |
903 | + auto error = lastError(bus, path); |
904 | + if (!error.isEmpty()) |
905 | + { |
906 | + qWarning() << "error:" << error; |
907 | + return QJsonArray(); |
908 | + } |
909 | + |
910 | + return QJsonDocument::fromJson(result(bus, path).toLatin1()).array(); |
911 | +} |
912 | + |
913 | +QJsonArray |
914 | +libertined_list_app_ids(char const* container_id) |
915 | +{ |
916 | + auto bus = QDBusConnection::sessionBus(); |
917 | + auto path = call(bus, "list_app_ids", QVariantList{QVariant(container_id)}); |
918 | + |
919 | + if (!waitForFinish(bus, path)) |
920 | + { |
921 | + return QJsonArray(); |
922 | + } |
923 | + |
924 | + auto error = lastError(bus, path); |
925 | + if (!error.isEmpty()) |
926 | + { |
927 | + qWarning() << "error:" << error; |
928 | + return QJsonArray(); |
929 | + } |
930 | + |
931 | + return QJsonDocument::fromJson(result(bus, path).toLatin1()).array(); |
932 | +} |
933 | + |
934 | +QString |
935 | +libertined_container_path(char const* container_id) |
936 | +{ |
937 | + return container_info(container_id, "root"); |
938 | +} |
939 | + |
940 | +QString |
941 | +libertined_container_home_path(char const* container_id) |
942 | +{ |
943 | + return container_info(container_id, "home"); |
944 | +} |
945 | + |
946 | +QString |
947 | +libertined_container_name(char const* container_id) |
948 | +{ |
949 | + return container_info(container_id, "name"); |
950 | +} |
951 | |
952 | === added file 'liblibertine/libertined.h' |
953 | --- liblibertine/libertined.h 1970-01-01 00:00:00 +0000 |
954 | +++ liblibertine/libertined.h 2017-01-27 18:57:35 +0000 |
955 | @@ -0,0 +1,25 @@ |
956 | +/* |
957 | + * Copyright 2017 Canonical Ltd |
958 | + * |
959 | + * Libertine is free software: you can redistribute it and/or modify it under |
960 | + * the terms of the GNU General Public License, version 3, as published by the |
961 | + * Free Software Foundation. |
962 | + * |
963 | + * Libertine is distributed in the hope that it will be useful, but WITHOUT ANY |
964 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR |
965 | + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
966 | + * |
967 | + * You should have received a copy of the GNU General Public License |
968 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
969 | + */ |
970 | + |
971 | +#pragma once |
972 | + |
973 | +#include <QDBusConnection> |
974 | +#include <QJsonArray> |
975 | + |
976 | +QJsonArray libertined_list(); |
977 | +QString libertined_container_path(char const* container_id); |
978 | +QString libertined_container_home_path(char const* container_id); |
979 | +QString libertined_container_name(char const* container_id); |
980 | +QJsonArray libertined_list_app_ids(char const* container_id); |
981 | |
982 | === modified file 'python/libertine/ChrootContainer.py' |
983 | --- python/libertine/ChrootContainer.py 2017-01-17 20:19:30 +0000 |
984 | +++ python/libertine/ChrootContainer.py 2017-01-27 18:57:35 +0000 |
985 | @@ -1,4 +1,4 @@ |
986 | -# Copyright 2015-2016 Canonical Ltd. |
987 | +# Copyright 2015-2017 Canonical Ltd. |
988 | # |
989 | # This program is free software: you can redistribute it and/or modify it |
990 | # under the terms of the GNU General Public License version 3, as published |
991 | @@ -47,9 +47,8 @@ |
992 | A concrete container type implemented using a plain old chroot. |
993 | """ |
994 | |
995 | - def __init__(self, container_id): |
996 | - super().__init__(container_id) |
997 | - self.container_type = "chroot" |
998 | + def __init__(self, container_id, config): |
999 | + super().__init__(container_id, 'chroot', config) |
1000 | self._window_manager = None |
1001 | # FIXME: Disabling seccomp is a temporary measure until we fully understand why we need |
1002 | # it or figure out when we need it. |
1003 | @@ -112,7 +111,7 @@ |
1004 | fd.write(archive + self.installed_release + " multiverse\n") |
1005 | fd.write(archive + self.installed_release + "-updates multiverse\n") |
1006 | |
1007 | - utils.create_libertine_user_data_dir(self.container_id) |
1008 | + self._create_libertine_user_data_dir() |
1009 | |
1010 | self.update_locale() |
1011 | |
1012 | @@ -140,7 +139,7 @@ |
1013 | self.update_packages() |
1014 | |
1015 | # Check if the container was created as root and chown the user directories as necessary |
1016 | - chown_recursive_dirs(utils.get_libertine_container_userdata_dir_path(self.container_id)) |
1017 | + chown_recursive_dirs(utils.get_libertine_container_home_dir(self.container_id)) |
1018 | |
1019 | super().create_libertine_container() |
1020 | |
1021 | @@ -186,7 +185,7 @@ |
1022 | # Bind-mount common XDG direcotries |
1023 | bind_mounts = ( |
1024 | " -b %s:%s" |
1025 | - % (utils.get_libertine_container_userdata_dir_path(self.container_id), home_path) |
1026 | + % (utils.get_libertine_container_home_dir(self.container_id), home_path) |
1027 | ) |
1028 | |
1029 | mounts = self._sanitize_bind_mounts(utils.get_common_xdg_user_directories() + \ |
1030 | |
1031 | === modified file 'python/libertine/ContainersConfig.py' |
1032 | --- python/libertine/ContainersConfig.py 2017-01-24 20:21:16 +0000 |
1033 | +++ python/libertine/ContainersConfig.py 2017-01-27 18:57:35 +0000 |
1034 | @@ -242,6 +242,9 @@ |
1035 | if write_json: |
1036 | write_container_config_file(self.container_list) |
1037 | |
1038 | + def get_containers(self): |
1039 | + return [c["id"] for c in self.container_list.get('containerList', [])] |
1040 | + |
1041 | """ |
1042 | Operations for the container itself. |
1043 | """ |
1044 | @@ -303,6 +306,12 @@ |
1045 | def get_container_locale(self, container_id): |
1046 | return self._get_value_by_key(container_id, 'locale') |
1047 | |
1048 | + def get_container_name(self, container_id): |
1049 | + return self._get_value_by_key(container_id, 'name') |
1050 | + |
1051 | + def get_container_install_status(self, container_id): |
1052 | + return self._get_value_by_key(container_id, 'installStatus') |
1053 | + |
1054 | """ |
1055 | Operations for archive (PPA) maintenance in a Libertine container. |
1056 | """ |
1057 | |
1058 | === modified file 'python/libertine/Libertine.py' |
1059 | --- python/libertine/Libertine.py 2017-01-24 15:31:01 +0000 |
1060 | +++ python/libertine/Libertine.py 2017-01-27 18:57:35 +0000 |
1061 | @@ -1,4 +1,4 @@ |
1062 | -# Copyright 2015-2016 Canonical Ltd. |
1063 | +# Copyright 2015-2017 Canonical Ltd. |
1064 | # |
1065 | # This program is free software: you can redistribute it and/or modify it |
1066 | # under the terms of the GNU General Public License version 3, as published |
1067 | @@ -13,7 +13,6 @@ |
1068 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1069 | |
1070 | from .AppDiscovery import AppLauncherCache |
1071 | -from gi.repository import Libertine |
1072 | import abc |
1073 | import contextlib |
1074 | import os |
1075 | @@ -81,14 +80,12 @@ |
1076 | |
1077 | :param container_id: The machine-readable container name. |
1078 | """ |
1079 | - def __init__(self, container_id, containers_config=None): |
1080 | - if containers_config is None: |
1081 | - containers_config = ContainersConfig() |
1082 | - |
1083 | - self.container_type = 'unknown' |
1084 | + def __init__(self, container_id, container_type, config): |
1085 | + self.container_type = container_type |
1086 | self.container_id = container_id |
1087 | + self._config = config |
1088 | self.root_path = utils.get_libertine_container_rootfs_path(self.container_id) |
1089 | - self.locale = containers_config.get_container_locale(container_id) |
1090 | + self.locale = self._config.get_container_locale(container_id) |
1091 | self.language = self._get_language_from_locale() |
1092 | self.default_packages = ['matchbox-window-manager', |
1093 | 'libnss-extrausers', |
1094 | @@ -247,10 +244,10 @@ |
1095 | self.delete_file_in_container(dest) |
1096 | |
1097 | return ret |
1098 | - else: |
1099 | - if no_dialog: |
1100 | - os.environ['DEBIAN_FRONTEND'] = 'teletype' |
1101 | - ret = self.run_in_container(_apt_command_prefix() + " install '" + package_name + "'") == 0 |
1102 | + |
1103 | + if no_dialog: |
1104 | + os.environ['DEBIAN_FRONTEND'] = 'teletype' |
1105 | + ret = self.run_in_container(_apt_command_prefix() + " install '" + package_name + "'") == 0 |
1106 | |
1107 | self.check_language_support() |
1108 | |
1109 | @@ -313,19 +310,26 @@ |
1110 | """ |
1111 | The human-readable name of the container. |
1112 | """ |
1113 | - name = Libertine.container_name(self.container_id) |
1114 | - if not name: |
1115 | - name = 'Unknown' |
1116 | - return name |
1117 | + return self._config.get_container_name(self.container_id) or 'Unknown' |
1118 | + |
1119 | + def _create_libertine_user_data_dir(self): |
1120 | + user_data = utils.get_libertine_container_home_dir(self.container_id) |
1121 | + |
1122 | + if not os.path.exists(user_data): |
1123 | + os.makedirs(user_data) |
1124 | + |
1125 | + config_path = os.path.join(user_data, ".config", "dconf") |
1126 | + |
1127 | + if not os.path.exists(config_path): |
1128 | + os.makedirs(config_path) |
1129 | |
1130 | |
1131 | class LibertineMock(BaseContainer): |
1132 | """ |
1133 | A concrete mock container type. Used for unit testing. |
1134 | """ |
1135 | - def __init__(self, container_id, containers_config=None): |
1136 | - super().__init__(container_id, containers_config) |
1137 | - self.container_type = "mock" |
1138 | + def __init__(self, container_id, config): |
1139 | + super().__init__(container_id, 'mock', config) |
1140 | |
1141 | def create_libertine_container(self, password=None, multiarch=False): |
1142 | return True |
1143 | @@ -395,7 +399,7 @@ |
1144 | self.container = LibertineLXD(container_id, self.containers_config) |
1145 | elif container_type == "chroot": |
1146 | from libertine.ChrootContainer import LibertineChroot |
1147 | - self.container = LibertineChroot(container_id) |
1148 | + self.container = LibertineChroot(container_id, self.containers_config) |
1149 | elif container_type == "mock": |
1150 | self.container = LibertineMock(container_id, self.containers_config) |
1151 | else: |
1152 | @@ -514,7 +518,7 @@ |
1153 | Enumerates all application launchers (based on .desktop files) available |
1154 | in the container. |
1155 | |
1156 | - :param use_json: Indicates the returned string should be i JSON format. |
1157 | + :param use_json: Indicates the returned string should be in JSON format. |
1158 | The default format is some human-readble format. |
1159 | :rtype: A printable string containing a list of application launchers |
1160 | available in the container. |
1161 | @@ -526,6 +530,24 @@ |
1162 | return str(AppLauncherCache(self.container.name, |
1163 | self.container.root_path)) |
1164 | |
1165 | + def list_app_ids(self): |
1166 | + """ |
1167 | + Finds application ids (based on .desktop files) available in the |
1168 | + container. |
1169 | + |
1170 | + :rtype: A list of app ids consumable by tools such as ubuntu-app-launch |
1171 | + """ |
1172 | + home = utils.get_libertine_container_home_dir(self.container_id) |
1173 | + app_ids = [] |
1174 | + for apps_dir in ["{}/usr/share/applications".format(self.root_path), |
1175 | + "{}/usr/local/share/applications".format(self.root_path), |
1176 | + "{}/.local/share/applications".format(home)]: |
1177 | + if os.path.exists(apps_dir): |
1178 | + for root, dirs, files in os.walk(apps_dir): |
1179 | + app_ids.extend(["{}_{}_0.0".format(self.container_id, f[:-8]) for f in files if f.endswith(".desktop")]) |
1180 | + |
1181 | + return app_ids |
1182 | + |
1183 | def exec_command(self, exec_line): |
1184 | """ |
1185 | Runs an arbitrary application in the container. Mainly used for status |
1186 | |
1187 | === modified file 'python/libertine/LxcContainer.py' |
1188 | --- python/libertine/LxcContainer.py 2017-01-24 20:21:16 +0000 |
1189 | +++ python/libertine/LxcContainer.py 2017-01-27 18:57:35 +0000 |
1190 | @@ -158,9 +158,8 @@ |
1191 | A concrete container type implemented using an LXC container. |
1192 | """ |
1193 | |
1194 | - def __init__(self, container_id, config=None): |
1195 | - super().__init__(container_id) |
1196 | - self.container_type = "lxc" |
1197 | + def __init__(self, container_id, config): |
1198 | + super().__init__(container_id, 'lxc', config) |
1199 | self.container = lxc_container(container_id) |
1200 | self.lxc_manager_interface = None |
1201 | self.window_manager = None |
1202 | @@ -247,7 +246,7 @@ |
1203 | |
1204 | self.container.load_config(config_file) |
1205 | |
1206 | - utils.create_libertine_user_data_dir(self.container_id) |
1207 | + self._create_libertine_user_data_dir() |
1208 | |
1209 | with EnvLxcSettings(): |
1210 | lxc_logfile = get_logfile(self.container) |
1211 | @@ -299,7 +298,7 @@ |
1212 | user_id = os.getuid() |
1213 | home_entry = ( |
1214 | "%s %s none bind,create=dir" |
1215 | - % (utils.get_libertine_container_userdata_dir_path(self.container_id), |
1216 | + % (utils.get_libertine_container_home_dir(self.container_id), |
1217 | home_path.strip('/')) |
1218 | ) |
1219 | |
1220 | |
1221 | === modified file 'python/libertine/LxdContainer.py' |
1222 | --- python/libertine/LxdContainer.py 2017-01-25 16:27:15 +0000 |
1223 | +++ python/libertine/LxdContainer.py 2017-01-27 18:57:35 +0000 |
1224 | @@ -226,7 +226,7 @@ |
1225 | |
1226 | |
1227 | def update_bind_mounts(container, config, home_path): |
1228 | - userdata_dir = utils.get_libertine_container_userdata_dir_path(container.name) |
1229 | + userdata_dir = utils.get_libertine_container_home_dir(container.name) |
1230 | |
1231 | container.devices.clear() |
1232 | container.devices['root'] = {'type': 'disk', 'path': '/'} |
1233 | @@ -251,7 +251,7 @@ |
1234 | |
1235 | mounts = config.get_container_bind_mounts(container.name) |
1236 | if utils.is_snap_environment(): |
1237 | - mounts += ["{}{}".format(home_path, d) for d in ["Documents", "Downloads", "Music", "Videos", "Pictures"]] |
1238 | + mounts += [os.path.join(home_path, d) for d in ["Documents", "Downloads", "Music", "Videos", "Pictures"]] |
1239 | else: |
1240 | mounts += utils.get_common_xdg_user_directories() |
1241 | |
1242 | @@ -301,8 +301,7 @@ |
1243 | |
1244 | class LibertineLXD(Libertine.BaseContainer): |
1245 | def __init__(self, name, config): |
1246 | - super().__init__(name, config) |
1247 | - self._config = config |
1248 | + super().__init__(name, 'lxd', config) |
1249 | self._host_info = HostInfo.HostInfo() |
1250 | self._container = None |
1251 | self._matchbox_pid = None |
1252 | @@ -315,14 +314,15 @@ |
1253 | self._client = pylxd.Client() |
1254 | self._window_manager = None |
1255 | |
1256 | - try: |
1257 | - if utils.set_session_dbus_env_var(): |
1258 | - bus = dbus.SessionBus() |
1259 | - self._manager = bus.get_object(get_lxd_manager_dbus_name(), get_lxd_manager_dbus_path()) |
1260 | - except PermissionError as e: |
1261 | - utils.get_logger().warning("Failed to set dbus session env var") |
1262 | - except dbus.exceptions.DBusException: |
1263 | - utils.get_logger().warning("D-Bus Service not found.") |
1264 | + if not utils.is_snap_environment(): |
1265 | + try: |
1266 | + if utils.set_session_dbus_env_var(): |
1267 | + bus = dbus.SessionBus() |
1268 | + self._manager = bus.get_object(get_lxd_manager_dbus_name(), get_lxd_manager_dbus_path()) |
1269 | + except PermissionError as e: |
1270 | + utils.get_logger().warning("Failed to set dbus session env var") |
1271 | + except dbus.exceptions.DBusException: |
1272 | + utils.get_logger().warning("D-Bus Service not found.") |
1273 | |
1274 | def create_libertine_container(self, password=None, multiarch=False): |
1275 | if self._try_get_container(): |
1276 | @@ -353,7 +353,7 @@ |
1277 | self.run_in_container("mkdir -p /home/{}".format(username)) |
1278 | self.run_in_container("chown {0}:{0} /home/{0}".format(username)) |
1279 | |
1280 | - utils.create_libertine_user_data_dir(self.container_id) |
1281 | + self._create_libertine_user_data_dir() |
1282 | |
1283 | _setup_bind_mount_service(self._container, uid, username) |
1284 | |
1285 | |
1286 | === modified file 'python/libertine/service/apt.py' |
1287 | --- python/libertine/service/apt.py 2016-11-08 15:37:58 +0000 |
1288 | +++ python/libertine/service/apt.py 2017-01-27 18:57:35 +0000 |
1289 | @@ -1,4 +1,4 @@ |
1290 | -# Copyright 2016 Canonical Ltd. |
1291 | +# Copyright 2016-2017 Canonical Ltd. |
1292 | # |
1293 | # This program is free software: you can redistribute it and/or modify |
1294 | # it under the terms of the GNU General Public License as published by |
1295 | @@ -15,10 +15,6 @@ |
1296 | import apt |
1297 | import re |
1298 | |
1299 | -import gi |
1300 | -gi.require_version('Libertine', '1') |
1301 | -from gi.repository import Libertine |
1302 | - |
1303 | from libertine import utils |
1304 | from os import path |
1305 | from threading import Lock |
1306 | @@ -67,7 +63,7 @@ |
1307 | if self._cache is None: |
1308 | try: |
1309 | utils.get_logger().debug("Trying aptcache for container %s" % self._container) |
1310 | - container_path = Libertine.container_path(self._container) |
1311 | + container_path = utils.get_libertine_container_rootfs_path(self._container) |
1312 | if not container_path or not path.exists(container_path): |
1313 | raise PermissionError |
1314 | |
1315 | |
1316 | === modified file 'python/libertine/service/container.py' |
1317 | --- python/libertine/service/container.py 2016-11-08 15:37:58 +0000 |
1318 | +++ python/libertine/service/container.py 2017-01-27 18:57:35 +0000 |
1319 | @@ -1,4 +1,4 @@ |
1320 | -# Copyright 2016 Canonical Ltd. |
1321 | +# Copyright 2016-2017 Canonical Ltd. |
1322 | # |
1323 | # This program is free software: you can redistribute it and/or modify |
1324 | # it under the terms of the GNU General Public License as published by |
1325 | @@ -14,18 +14,27 @@ |
1326 | |
1327 | from libertine.service.tasks import * |
1328 | from libertine import utils |
1329 | -from libertine.service import apt |
1330 | +from threading import Lock |
1331 | + |
1332 | + |
1333 | +if not utils.is_snap_environment(): |
1334 | + from libertine.service import apt |
1335 | |
1336 | |
1337 | class Container(object): |
1338 | - def __init__(self, container_id, config, lock, connection, callback): |
1339 | + def __init__(self, container_id, config, connection, callback): |
1340 | self._id = container_id |
1341 | self._connection = connection |
1342 | self._callback = callback |
1343 | self._config = config |
1344 | - self._lock = lock |
1345 | + self._lock = Lock() |
1346 | self._tasks = [] |
1347 | - self._cache = apt.AptCache(self.id) |
1348 | + |
1349 | + if utils.is_snap_environment(): |
1350 | + utils.get_logger().warning("Using AptCache not currently supported in snap environment") |
1351 | + self._cache = None |
1352 | + else: |
1353 | + self._cache = apt.AptCache(self.id) |
1354 | |
1355 | def _cleanup_task(self, task): |
1356 | utils.get_logger().debug("cleaning up tasks for container '%s'" % self.id) |
1357 | @@ -47,6 +56,9 @@ |
1358 | def search(self, query): |
1359 | utils.get_logger().debug("search container '%s' for package '%s'" % (self.id, query)) |
1360 | |
1361 | + if utils.is_snap_environment(): |
1362 | + raise Exception("This operation is not currently supported within the snap") |
1363 | + |
1364 | task = SearchTask(self.id, self._cache, query, self._connection, self._cleanup_task) |
1365 | self._tasks.append(task) |
1366 | task.start() |
1367 | @@ -56,6 +68,9 @@ |
1368 | def app_info(self, package_name): |
1369 | utils.get_logger().debug("get info for package '%s' in container '%s'" % (package_name, self.id)) |
1370 | |
1371 | + if utils.is_snap_environment(): |
1372 | + raise Exception("This operation is not currently supported within the snap") |
1373 | + |
1374 | related_task_ids = [t.id for t in self._tasks if t.package == package_name and t.running] |
1375 | task = AppInfoTask(self.id, self._cache, package_name, related_task_ids, self._config, self._connection, self._cleanup_task) |
1376 | |
1377 | @@ -137,3 +152,12 @@ |
1378 | self._tasks.append(task) |
1379 | task.start() |
1380 | return task.id |
1381 | + |
1382 | + def list_app_ids(self): |
1383 | + utils.get_logger().debug("List all app ids in container '%s'" % self.id) |
1384 | + |
1385 | + task = ListAppIdsTask(self.id, self._config, self._connection, self._cleanup_task) |
1386 | + |
1387 | + self._tasks.append(task) |
1388 | + task.start() |
1389 | + return task.id |
1390 | |
1391 | === modified file 'python/libertine/service/manager.py' |
1392 | --- python/libertine/service/manager.py 2016-10-31 18:31:00 +0000 |
1393 | +++ python/libertine/service/manager.py 2017-01-27 18:57:35 +0000 |
1394 | @@ -1,4 +1,4 @@ |
1395 | -# Copyright 2016 Canonical Ltd. |
1396 | +# Copyright 2016-2017 Canonical Ltd. |
1397 | # |
1398 | # This program is free software: you can redistribute it and/or modify |
1399 | # it under the terms of the GNU General Public License as published by |
1400 | @@ -72,6 +72,13 @@ |
1401 | return self._dispatcher.list_apps(container_id) |
1402 | |
1403 | @dbus.service.method(LIBERTINE_MANAGER_INTERFACE, |
1404 | + in_signature='s', |
1405 | + out_signature='o') |
1406 | + def list_app_ids(self, container_id): |
1407 | + utils.get_logger().debug("list_app_ids('{}')".format(container_id)) |
1408 | + return self._dispatcher.list_app_ids(container_id) |
1409 | + |
1410 | + @dbus.service.method(LIBERTINE_MANAGER_INTERFACE, |
1411 | out_signature='o') |
1412 | def list(self): |
1413 | utils.get_logger().debug("list()") |
1414 | |
1415 | === modified file 'python/libertine/service/progress.py' |
1416 | --- python/libertine/service/progress.py 2016-11-29 17:38:38 +0000 |
1417 | +++ python/libertine/service/progress.py 2017-01-27 18:57:35 +0000 |
1418 | @@ -1,4 +1,4 @@ |
1419 | -# Copyright 2016 Canonical Ltd. |
1420 | +# Copyright 2016-2017 Canonical Ltd. |
1421 | # |
1422 | # This program is free software: you can redistribute it and/or modify |
1423 | # it under the terms of the GNU General Public License as published by |
1424 | @@ -18,7 +18,7 @@ |
1425 | from time import time |
1426 | |
1427 | DOWNLOAD_INTERFACE = "com.canonical.applications.Download" |
1428 | -PROGRESS_INTERFACE = "com.canonical.libertine.Progress" |
1429 | +PROGRESS_INTERFACE = "com.canonical.libertine.Service.Progress" |
1430 | |
1431 | class Progress(dbus.service.Object): |
1432 | def __init__(self, connection): |
1433 | @@ -28,7 +28,7 @@ |
1434 | self._error = '' |
1435 | dbus.service.Object.__init__(self, conn=connection, object_path=("/Progress/%s" % hex(int(time()*10000000))[2:])) |
1436 | |
1437 | - self.emit_processing() |
1438 | + # self.emit_processing() # Disabled until something requires the Download interface |
1439 | |
1440 | @property |
1441 | def id(self): |
1442 | |
1443 | === modified file 'python/libertine/service/task_dispatcher.py' |
1444 | --- python/libertine/service/task_dispatcher.py 2016-11-01 18:50:32 +0000 |
1445 | +++ python/libertine/service/task_dispatcher.py 2017-01-27 18:57:35 +0000 |
1446 | @@ -1,4 +1,4 @@ |
1447 | -# Copyright 2016 Canonical Ltd. |
1448 | +# Copyright 2016-2017 Canonical Ltd. |
1449 | # |
1450 | # This program is free software: you can redistribute it and/or modify |
1451 | # it under the terms of the GNU General Public License as published by |
1452 | @@ -24,7 +24,6 @@ |
1453 | def __init__(self, connection): |
1454 | self._connection = connection |
1455 | self._config = libertine.ContainersConfig.ContainersConfig() |
1456 | - self._lock = Lock() |
1457 | self._containerless_tasks = [] |
1458 | self._tasks = [] |
1459 | self._containers = [] |
1460 | @@ -35,7 +34,7 @@ |
1461 | self._tasks.remove(task) |
1462 | |
1463 | def _cleanup_container(self, container): |
1464 | - utils.get_logger().debug("cleaning up container '%s'" % container) |
1465 | + utils.get_logger().debug("cleaning up container '%s'" % container.id) |
1466 | if container in self._containers: |
1467 | self._containers.remove(container) |
1468 | |
1469 | @@ -45,7 +44,7 @@ |
1470 | if container is not None: |
1471 | utils.get_logger().debug("using existing container '%s'" % container_id) |
1472 | return container |
1473 | - container = Container(container_id, self._config, self._lock, self._connection, self._cleanup_container) |
1474 | + container = Container(container_id, self._config, self._connection, self._cleanup_container) |
1475 | self._containers.append(container) |
1476 | |
1477 | return container |
1478 | @@ -89,6 +88,10 @@ |
1479 | utils.get_logger().debug("dispatching list all apps in container '%s'" % container_id) |
1480 | return self._find_or_create_container(container_id).list_apps() |
1481 | |
1482 | + def list_app_ids(self, container_id): |
1483 | + utils.get_logger().debug("dispatching list apps ids in container '%s'" % container_id) |
1484 | + return self._find_or_create_container(container_id).list_app_ids() |
1485 | + |
1486 | # Containerless Tasks |
1487 | |
1488 | def container_info(self, container_id): |
1489 | @@ -107,7 +110,7 @@ |
1490 | def list(self): |
1491 | utils.get_logger().debug("dispatching list all containers") |
1492 | |
1493 | - task = ListTask(self._connection, self._cleanup_task) |
1494 | + task = ListTask(self._config, self._connection, self._cleanup_task) |
1495 | self._tasks.append(task) |
1496 | task.start() |
1497 | |
1498 | |
1499 | === modified file 'python/libertine/service/tasks/__init__.py' |
1500 | --- python/libertine/service/tasks/__init__.py 2016-11-01 17:38:38 +0000 |
1501 | +++ python/libertine/service/tasks/__init__.py 2017-01-27 18:57:35 +0000 |
1502 | @@ -1,4 +1,4 @@ |
1503 | -# Copyright 2016 Canonical Ltd. |
1504 | +# Copyright 2016-2017 Canonical Ltd. |
1505 | # |
1506 | # This program is free software: you can redistribute it and/or modify it |
1507 | # under the terms of the GNU General Public License version 3, as published |
1508 | @@ -23,6 +23,7 @@ |
1509 | from .update_task import UpdateTask |
1510 | from .list_task import ListTask |
1511 | from .list_apps_task import ListAppsTask |
1512 | +from .list_app_ids_task import ListAppIdsTask |
1513 | |
1514 | __all__ = [ |
1515 | 'AppInfoTask', |
1516 | @@ -35,5 +36,6 @@ |
1517 | 'SearchTask', |
1518 | 'UpdateTask', |
1519 | 'ListTask', |
1520 | - 'ListAppsTask' |
1521 | + 'ListAppsTask', |
1522 | + 'ListAppIdsTask' |
1523 | ] |
1524 | |
1525 | === modified file 'python/libertine/service/tasks/base_task.py' |
1526 | --- python/libertine/service/tasks/base_task.py 2016-11-07 20:37:54 +0000 |
1527 | +++ python/libertine/service/tasks/base_task.py 2017-01-27 18:57:35 +0000 |
1528 | @@ -1,4 +1,4 @@ |
1529 | -# Copyright 2016 Canonical Ltd. |
1530 | +# Copyright 2016-2017 Canonical Ltd. |
1531 | # |
1532 | # This program is free software: you can redistribute it and/or modify |
1533 | # it under the terms of the GNU General Public License as published by |
1534 | @@ -15,7 +15,6 @@ |
1535 | import libertine.service.progress |
1536 | import threading |
1537 | from abc import ABCMeta, abstractmethod |
1538 | -from libertine import utils |
1539 | |
1540 | |
1541 | class BaseTask(metaclass=ABCMeta): |
1542 | @@ -60,7 +59,7 @@ |
1543 | if self._instant_callback: |
1544 | self._callback(self) |
1545 | else: |
1546 | - threading.Timer(30, lambda: self._callback(self)).start() |
1547 | + threading.Timer(10, lambda: self._callback(self)).start() |
1548 | |
1549 | def start(self): |
1550 | self._progress = libertine.service.progress.Progress(self._connection) |
1551 | @@ -82,7 +81,6 @@ |
1552 | |
1553 | if self.running: |
1554 | self._progress.finished(self.container) |
1555 | - utils.refresh_libertine_scope() |
1556 | |
1557 | self._delayed_callback() |
1558 | |
1559 | |
1560 | === modified file 'python/libertine/service/tasks/container_info_task.py' |
1561 | --- python/libertine/service/tasks/container_info_task.py 2016-11-01 17:38:38 +0000 |
1562 | +++ python/libertine/service/tasks/container_info_task.py 2017-01-27 18:57:35 +0000 |
1563 | @@ -1,4 +1,4 @@ |
1564 | -# Copyright 2016 Canonical Ltd. |
1565 | +# Copyright 2016-2017 Canonical Ltd. |
1566 | # |
1567 | # This program is free software: you can redistribute it and/or modify |
1568 | # it under the terms of the GNU General Public License as published by |
1569 | @@ -13,6 +13,8 @@ |
1570 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1571 | |
1572 | |
1573 | +import json |
1574 | + |
1575 | from .base_task import BaseTask |
1576 | from libertine import utils |
1577 | |
1578 | @@ -23,7 +25,21 @@ |
1579 | self._tasks = tasks |
1580 | |
1581 | def _run(self): |
1582 | - container = {'id': str(self._container)} |
1583 | - container['status'] = self._config._get_value_by_key(self._container, 'installStatus') or '' |
1584 | - container['task_ids'] = self._tasks |
1585 | - self._progress.data(str(container)) |
1586 | + utils.get_logger().debug("Gathering info for container '{}'".format(self._container)) |
1587 | + container = {'id': str(self._container), 'task_ids': self._tasks} |
1588 | + |
1589 | + container['status'] = self._config.get_container_install_status(self._container) or '' |
1590 | + container['name'] = self._config.get_container_name(self._container) or '' |
1591 | + |
1592 | + container_type = self._config.get_container_type(self._container) |
1593 | + container['root'] = utils.get_libertine_container_rootfs_path(self._container) |
1594 | + container['home'] = utils.get_libertine_container_home_dir(self._container) |
1595 | + |
1596 | + self._progress.data(json.dumps(container)) |
1597 | + |
1598 | + def _before(self): |
1599 | + if not self._config.container_exists(self._container): |
1600 | + self._progress.error("Container '%s' does not exist, ignoring info request" % self._container) |
1601 | + return False |
1602 | + |
1603 | + return True |
1604 | |
1605 | === added file 'python/libertine/service/tasks/list_app_ids_task.py' |
1606 | --- python/libertine/service/tasks/list_app_ids_task.py 1970-01-01 00:00:00 +0000 |
1607 | +++ python/libertine/service/tasks/list_app_ids_task.py 2017-01-27 18:57:35 +0000 |
1608 | @@ -0,0 +1,35 @@ |
1609 | +# Copyright 2017 Canonical Ltd. |
1610 | +# |
1611 | +# This program is free software: you can redistribute it and/or modify |
1612 | +# it under the terms of the GNU General Public License as published by |
1613 | +# the Free Software Foundation; version 3 of the License. |
1614 | +# |
1615 | +# This program is distributed in the hope that it will be useful, |
1616 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1617 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1618 | +# GNU General Public License for more details. |
1619 | +# |
1620 | +# You should have received a copy of the GNU General Public License |
1621 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1622 | + |
1623 | + |
1624 | +import json |
1625 | +from .base_task import BaseTask |
1626 | +from libertine import LibertineContainer, utils |
1627 | +import time |
1628 | + |
1629 | + |
1630 | +class ListAppIdsTask(BaseTask): |
1631 | + def __init__(self, container_id, config, connection, callback): |
1632 | + super().__init__(lock=None, container_id=container_id, config=config, connection=connection, callback=callback) |
1633 | + |
1634 | + def _run(self): |
1635 | + utils.get_logger().debug("Listing app ids from container '%s'" % self._container) |
1636 | + self._progress.data(json.dumps(LibertineContainer(self._container, self._config).list_app_ids())) |
1637 | + |
1638 | + def _before(self): |
1639 | + if not self._config.container_exists(self._container): |
1640 | + self._progress.error("Container '%s' does not exist, skipping list" % self._container) |
1641 | + return False |
1642 | + |
1643 | + return True |
1644 | |
1645 | === modified file 'python/libertine/service/tasks/list_apps_task.py' |
1646 | --- python/libertine/service/tasks/list_apps_task.py 2016-11-01 17:38:38 +0000 |
1647 | +++ python/libertine/service/tasks/list_apps_task.py 2017-01-27 18:57:35 +0000 |
1648 | @@ -1,4 +1,4 @@ |
1649 | -# Copyright 2016 Canonical Ltd. |
1650 | +# Copyright 2016-2017 Canonical Ltd. |
1651 | # |
1652 | # This program is free software: you can redistribute it and/or modify |
1653 | # it under the terms of the GNU General Public License as published by |
1654 | @@ -23,8 +23,12 @@ |
1655 | |
1656 | def _run(self): |
1657 | utils.get_logger().debug("Listing apps in container '%s'" % self._container) |
1658 | + container = LibertineContainer(self._container, self._config) |
1659 | + self._progress.data(str(container.list_app_launchers(use_json=True))) |
1660 | + |
1661 | + def _before(self): |
1662 | if not self._config.container_exists(self._container): |
1663 | self._progress.error("Container '%s' does not exist, skipping list" % self._container) |
1664 | - else: |
1665 | - container = LibertineContainer(self._container, self._config) |
1666 | - self._progress.data(str(container.list_app_launchers(use_json=True))) |
1667 | + return False |
1668 | + |
1669 | + return True |
1670 | |
1671 | === modified file 'python/libertine/service/tasks/list_task.py' |
1672 | --- python/libertine/service/tasks/list_task.py 2016-11-01 18:50:32 +0000 |
1673 | +++ python/libertine/service/tasks/list_task.py 2017-01-27 18:57:35 +0000 |
1674 | @@ -1,4 +1,4 @@ |
1675 | -# Copyright 2016 Canonical Ltd. |
1676 | +# Copyright 2016-2017 Canonical Ltd. |
1677 | # |
1678 | # This program is free software: you can redistribute it and/or modify |
1679 | # it under the terms of the GNU General Public License as published by |
1680 | @@ -13,13 +13,15 @@ |
1681 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1682 | |
1683 | |
1684 | +import json |
1685 | + |
1686 | from .base_task import BaseTask |
1687 | from libertine import utils |
1688 | |
1689 | |
1690 | class ListTask(BaseTask): |
1691 | - def __init__(self, connection, callback): |
1692 | - super().__init__(lock=None, container_id=None, config=None, connection=connection, callback=callback) |
1693 | + def __init__(self, config, connection, callback): |
1694 | + super().__init__(lock=None, container_id=None, config=config, connection=connection, callback=callback) |
1695 | |
1696 | def _run(self): |
1697 | - self._progress.data(str(utils.Libertine.list_containers())) |
1698 | + self._progress.data(json.dumps(self._config.get_containers())) |
1699 | |
1700 | === modified file 'python/libertine/utils.py' |
1701 | --- python/libertine/utils.py 2017-01-18 21:07:39 +0000 |
1702 | +++ python/libertine/utils.py 2017-01-27 18:57:35 +0000 |
1703 | @@ -1,6 +1,6 @@ |
1704 | # -*- coding: utf-8 -*- |
1705 | |
1706 | -# Copyright (C) 2015-2016 Canonical Ltd. |
1707 | +# Copyright (C) 2015-2017 Canonical Ltd. |
1708 | # Author: Christopher Townsend <christopher.townsend@canonical.com> |
1709 | |
1710 | # This program is free software: you can redistribute it and/or modify |
1711 | @@ -22,10 +22,6 @@ |
1712 | import subprocess |
1713 | import xdg.BaseDirectory as basedir |
1714 | |
1715 | -from gi import require_version |
1716 | -require_version('Libertine', '1') |
1717 | -from gi.repository import Libertine |
1718 | - |
1719 | |
1720 | def get_logger(): |
1721 | logger = logging.getLogger('__libertine_logger__') |
1722 | @@ -64,12 +60,7 @@ |
1723 | |
1724 | |
1725 | def get_libertine_container_rootfs_path(container_id): |
1726 | - path = Libertine.container_path(container_id) |
1727 | - |
1728 | - if path is None: |
1729 | - path = os.path.join(get_libertine_containers_dir_path(), container_id, 'rootfs') |
1730 | - |
1731 | - return path |
1732 | + return os.path.join(get_libertine_containers_dir_path(), container_id, 'rootfs') |
1733 | |
1734 | |
1735 | def get_libertine_containers_dir_path(): |
1736 | @@ -100,11 +91,8 @@ |
1737 | return os.path.join(get_libertine_database_dir_path(), 'ContainersConfig.json') |
1738 | |
1739 | |
1740 | -def get_libertine_container_userdata_dir_path(container_id): |
1741 | - path = Libertine.container_home_path(container_id) |
1742 | - |
1743 | - if path is None: |
1744 | - path = os.path.join(basedir.xdg_data_home, 'libertine-container', 'user-data', container_id) |
1745 | +def get_libertine_container_home_dir(container_id): |
1746 | + path = os.path.join(basedir.xdg_data_home, 'libertine-container', 'user-data', container_id) |
1747 | |
1748 | if is_snap_environment(): |
1749 | path = path.replace(os.environ['HOME'], os.getenv('SNAP_USER_COMMON')) |
1750 | @@ -153,18 +141,6 @@ |
1751 | return dirs |
1752 | |
1753 | |
1754 | -def create_libertine_user_data_dir(container_id): |
1755 | - user_data = get_libertine_container_userdata_dir_path(container_id) |
1756 | - |
1757 | - if not os.path.exists(user_data): |
1758 | - os.makedirs(user_data) |
1759 | - |
1760 | - config_path = os.path.join(user_data, ".config", "dconf") |
1761 | - |
1762 | - if not os.path.exists(config_path): |
1763 | - os.makedirs(config_path) |
1764 | - |
1765 | - |
1766 | def get_libertine_lxc_pulse_socket_path(): |
1767 | return os.path.join(get_libertine_runtime_dir(), 'pulse_socket') |
1768 | |
1769 | @@ -194,14 +170,17 @@ |
1770 | |
1771 | if not dbus_session_set: |
1772 | for p in psutil.process_iter(): |
1773 | - if p.name() == 'unity8' or p.name() == 'compiz': |
1774 | - p_environ = subprocess.check_output(["cat", "/proc/{}/environ".format(p.pid)]) |
1775 | - for line in p_environ.decode().split('\0'): |
1776 | - if line.startswith('DBUS_SESSION_BUS_ADDRESS'): |
1777 | - os.environ['DBUS_SESSION_BUS_ADDRESS'] = line.partition('DBUS_SESSION_BUS_ADDRESS=')[2].rstrip('\n') |
1778 | - dbus_session_set = True |
1779 | - break |
1780 | - break |
1781 | + try: |
1782 | + if p.name() == 'unity8' or p.name() == 'compiz': |
1783 | + p_environ = subprocess.check_output(["cat", "/proc/{}/environ".format(p.pid)]) |
1784 | + for line in p_environ.decode().split('\0'): |
1785 | + if line.startswith('DBUS_SESSION_BUS_ADDRESS'): |
1786 | + os.environ['DBUS_SESSION_BUS_ADDRESS'] = line.partition('DBUS_SESSION_BUS_ADDRESS=')[2].rstrip('\n') |
1787 | + dbus_session_set = True |
1788 | + break |
1789 | + break |
1790 | + except psutil.NoSuchProcess as e: |
1791 | + get_logger().warning(str(e)) |
1792 | |
1793 | return dbus_session_set |
1794 | |
1795 | |
1796 | === modified file 'snapcraft.yaml' |
1797 | --- snapcraft.yaml 2017-01-23 15:21:46 +0000 |
1798 | +++ snapcraft.yaml 2017-01-27 18:57:35 +0000 |
1799 | @@ -3,9 +3,15 @@ |
1800 | summary: Libertine suite |
1801 | description: | |
1802 | Suite for maintaining deb-based applications in a non-deb environment |
1803 | -confinement: devmode # TODO: update to 'strict' |
1804 | +confinement: strict # devmode # TODO: update to 'strict' |
1805 | grade: devel |
1806 | |
1807 | +slots: |
1808 | + libertined: |
1809 | + interface: dbus |
1810 | + name: com.canonical.libertine.Service |
1811 | + bus: session |
1812 | + |
1813 | apps: |
1814 | launch: |
1815 | command: usr/bin/snap-runner.wrapper libertine-launch |
1816 | @@ -22,6 +28,12 @@ |
1817 | - opengl |
1818 | - pulseaudio |
1819 | - alsa |
1820 | + libertined: |
1821 | + command: usr/bin/snap-runner.wrapper libertined |
1822 | + plugs: |
1823 | + - lxd |
1824 | + - network-bind |
1825 | + # daemon: simple # Waiting on LP:1613420 |
1826 | container-manager: |
1827 | command: usr/bin/snap-runner.wrapper libertine-container-manager |
1828 | aliases: |
1829 | |
1830 | === modified file 'tests/integration/test_libertine_service.py' |
1831 | --- tests/integration/test_libertine_service.py 2016-11-29 17:38:38 +0000 |
1832 | +++ tests/integration/test_libertine_service.py 2017-01-27 18:57:35 +0000 |
1833 | @@ -1,4 +1,4 @@ |
1834 | -# Copyright 2016 Canonical Ltd. |
1835 | +# Copyright 2016-2017 Canonical Ltd. |
1836 | # |
1837 | # This program is free software: you can redistribute it and/or modify it |
1838 | # under the terms of the GNU General Public License version 3, as published |
1839 | @@ -12,20 +12,24 @@ |
1840 | # You should have received a copy of the GNU General Public License along |
1841 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1842 | |
1843 | + |
1844 | +import ast |
1845 | import dbus |
1846 | import dbus.mainloop.glib |
1847 | +import os |
1848 | +import tempfile |
1849 | +import threading |
1850 | +import time |
1851 | import unittest.mock |
1852 | -from unittest import TestCase |
1853 | + |
1854 | +from gi.repository import GLib |
1855 | +from gi.repository import GObject |
1856 | +from libertine import utils |
1857 | from libertine.service import tasks, apt |
1858 | from libertine.ContainersConfig import ContainersConfig |
1859 | from subprocess import Popen, PIPE |
1860 | -import time |
1861 | -from gi.repository import GLib |
1862 | -from gi.repository import GObject |
1863 | -import os |
1864 | -import tempfile |
1865 | -import threading |
1866 | -import ast |
1867 | +from unittest import TestCase |
1868 | + |
1869 | |
1870 | class TestLibertineService(TestCase): |
1871 | _process = None |
1872 | @@ -39,6 +43,7 @@ |
1873 | |
1874 | environ = os.environ.copy() |
1875 | environ['XDG_DATA_HOME'] = cls._tempdir.name |
1876 | + |
1877 | cls._process = Popen(['libertined', '--debug'], stdout=PIPE, stderr=PIPE, env=environ) |
1878 | dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) |
1879 | cls._loop = GObject.MainLoop() |
1880 | @@ -91,7 +96,7 @@ |
1881 | signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._finished_handler, |
1882 | dbus_interface='com.canonical.applications.Download', signal_name='finished')) |
1883 | signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._data_handler, |
1884 | - dbus_interface='com.canonical.libertine.Progress', signal_name='data')) |
1885 | + dbus_interface='com.canonical.libertine.Service.Progress', signal_name='data')) |
1886 | signals.append(self._bus.add_signal_receiver(path=obj_path, handler_function=self._error_handler, |
1887 | dbus_interface='com.canonical.applications.Download', signal_name='error')) |
1888 | |
1889 | @@ -110,20 +115,25 @@ |
1890 | |
1891 | def test_container_management(self): |
1892 | try: |
1893 | - self.assertEqual('[]', self._send(lambda: self._libertined.list())) |
1894 | + self.assertEqual([], ast.literal_eval(self._send(lambda: self._libertined.list()))) |
1895 | self._send(lambda: self._libertined.create('rey', 'Rey', 'xenial', 'mock')) |
1896 | - self.assertEqual('[\'rey\']', self._send(lambda: self._libertined.list())) |
1897 | + self.assertEqual(['rey'], ast.literal_eval(self._send(lambda: self._libertined.list()))) |
1898 | |
1899 | self._send(lambda: self._libertined.create('kylo', 'Kylo Ren', 'xenial', 'mock')) |
1900 | - self.assertEqual('[\'rey\', \'kylo\']', self._send(lambda: self._libertined.list())) |
1901 | + self.assertEqual(['rey', 'kylo'], ast.literal_eval(self._send(lambda: self._libertined.list()))) |
1902 | |
1903 | self._send(lambda: self._libertined.update('kylo')) |
1904 | |
1905 | - self.assertEqual({'id': 'rey', 'status': 'ready', 'task_ids': []}, |
1906 | - ast.literal_eval(self._send(lambda: self._libertined.container_info('rey')))) |
1907 | + self.assertEqual({'id': 'rey', |
1908 | + 'status': 'ready', |
1909 | + 'name': 'Rey', |
1910 | + 'task_ids': [], |
1911 | + 'root': utils.get_libertine_container_rootfs_path('rey'), |
1912 | + 'home': '{}/libertine-container/user-data/rey'.format(TestLibertineService._tempdir.name) |
1913 | + }, ast.literal_eval(self._send(lambda: self._libertined.container_info('rey')))) |
1914 | |
1915 | self._send(lambda: self._libertined.destroy('kylo')) |
1916 | - self.assertEqual('[\'rey\']', self._send(lambda: self._libertined.list())) |
1917 | + self.assertEqual(['rey'], ast.literal_eval(self._send(lambda: self._libertined.list()))) |
1918 | except AssertionError as e: |
1919 | raise |
1920 | except Exception as e: |
1921 | |
1922 | === added directory 'tests/unit/service/containerroot/libertine-container' |
1923 | === added directory 'tests/unit/service/containerroot/libertine-container/palpatine' |
1924 | === added directory 'tests/unit/service/containerroot/libertine-container/palpatine/rootfs' |
1925 | === modified file 'tests/unit/service/tasks/CMakeLists.txt' |
1926 | --- tests/unit/service/tasks/CMakeLists.txt 2016-11-01 19:49:32 +0000 |
1927 | +++ tests/unit/service/tasks/CMakeLists.txt 2017-01-27 18:57:35 +0000 |
1928 | @@ -5,6 +5,7 @@ |
1929 | create_service_unit_test(test_install_task) |
1930 | create_service_unit_test(test_list_task) |
1931 | create_service_unit_test(test_list_apps_task) |
1932 | +create_service_unit_test(test_list_app_ids_task) |
1933 | create_service_unit_test(test_remove_task) |
1934 | create_service_unit_test(test_search_task) |
1935 | create_service_unit_test(test_update_task) |
1936 | |
1937 | === modified file 'tests/unit/service/tasks/test_container_info_task.py' |
1938 | --- tests/unit/service/tasks/test_container_info_task.py 2016-11-07 18:51:17 +0000 |
1939 | +++ tests/unit/service/tasks/test_container_info_task.py 2017-01-27 18:57:35 +0000 |
1940 | @@ -13,8 +13,10 @@ |
1941 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1942 | |
1943 | |
1944 | +import ast |
1945 | import unittest.mock |
1946 | from unittest import TestCase |
1947 | +from libertine import utils |
1948 | from libertine.service import tasks |
1949 | from libertine.ContainersConfig import ContainersConfig |
1950 | |
1951 | @@ -33,12 +35,22 @@ |
1952 | progress = MockProgress.return_value |
1953 | progress.done = False |
1954 | |
1955 | - self.config._get_value_by_key.return_value = 'ready' |
1956 | + self.config.get_container_install_status.return_value = 'ready' |
1957 | + self.config.get_container_name.return_value = 'Palpatine' |
1958 | task = tasks.ContainerInfoTask('palpatine', [1, 2, 3], self.config, self.connection, callback) |
1959 | task._instant_callback = True |
1960 | task.start().join() |
1961 | |
1962 | - progress.data.assert_called_once_with(str({'id': 'palpatine', 'status': 'ready', 'task_ids': [1, 2, 3]})) |
1963 | + progress.data.assert_called_once_with(unittest.mock.ANY) |
1964 | + args, kwargs = progress.data.call_args |
1965 | + self.assertEqual({'id': 'palpatine', |
1966 | + 'status': 'ready', |
1967 | + 'task_ids': [1, 2, 3], |
1968 | + 'name': 'Palpatine', |
1969 | + 'root': utils.get_libertine_container_rootfs_path('palpatine'), |
1970 | + 'home': utils.get_libertine_container_home_dir('palpatine')}, |
1971 | + ast.literal_eval(args[0])) |
1972 | + |
1973 | progress.finished.assert_called_once_with('palpatine') |
1974 | |
1975 | self.assertEqual(task, self.called_with) |
1976 | |
1977 | === added file 'tests/unit/service/tasks/test_list_app_ids_task.py' |
1978 | --- tests/unit/service/tasks/test_list_app_ids_task.py 1970-01-01 00:00:00 +0000 |
1979 | +++ tests/unit/service/tasks/test_list_app_ids_task.py 2017-01-27 18:57:35 +0000 |
1980 | @@ -0,0 +1,59 @@ |
1981 | +# Copyright 2017 Canonical Ltd. |
1982 | +# |
1983 | +# This program is free software: you can redistribute it and/or modify it |
1984 | +# under the terms of the GNU General Public License version 3, as published |
1985 | +# by the Free Software Foundation. |
1986 | +# |
1987 | +# This program is distributed in the hope that it will be useful, but |
1988 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
1989 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1990 | +# PURPOSE. See the GNU General Public License for more details. |
1991 | +# |
1992 | +# You should have received a copy of the GNU General Public License along |
1993 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
1994 | + |
1995 | +import json |
1996 | +import unittest.mock |
1997 | +from unittest import TestCase |
1998 | +from libertine.service import tasks |
1999 | +from libertine.ContainersConfig import ContainersConfig |
2000 | + |
2001 | + |
2002 | +class TestListAppIdsTask(TestCase): |
2003 | + def setUp(self): |
2004 | + self.config = unittest.mock.create_autospec(ContainersConfig) |
2005 | + self.connection = unittest.mock.Mock() |
2006 | + self.lock = unittest.mock.MagicMock() |
2007 | + self.called_with = None |
2008 | + |
2009 | + def callback(self, task): |
2010 | + self.called_with = task |
2011 | + |
2012 | + def test_sends_error_on_non_existent_container(self): |
2013 | + self.config.container_exists.return_value = False |
2014 | + with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress: |
2015 | + progress = MockProgress.return_value |
2016 | + task = tasks.ListAppIdsTask('palpatine', self.config, self.connection, self.callback) |
2017 | + task._instant_callback = True |
2018 | + |
2019 | + with unittest.mock.patch('libertine.service.tasks.list_apps_task.LibertineContainer') as MockContainer: |
2020 | + task.start().join() |
2021 | + |
2022 | + progress.error.assert_called_once_with('Container \'palpatine\' does not exist, skipping list') |
2023 | + self.assertEqual(task, self.called_with) |
2024 | + |
2025 | + def test_successfully_lists_apps(self): |
2026 | + self.config.container_exists.return_value = True |
2027 | + with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress: |
2028 | + progress = MockProgress.return_value |
2029 | + progress.done = False |
2030 | + task = tasks.ListAppIdsTask('palpatine', self.config, self.connection, self.callback) |
2031 | + task._instant_callback = True |
2032 | + |
2033 | + with unittest.mock.patch('libertine.service.tasks.list_app_ids_task.LibertineContainer') as MockContainer: |
2034 | + MockContainer.return_value.list_app_ids.return_value = '["palpatine_gedit_0.0","palpatine_xterm_0.0"]' |
2035 | + task.start().join() |
2036 | + |
2037 | + progress.finished.assert_called_once_with('palpatine') |
2038 | + progress.data.assert_called_once_with(json.dumps('["palpatine_gedit_0.0","palpatine_xterm_0.0"]')) |
2039 | + self.assertEqual(task, self.called_with) |
2040 | |
2041 | === modified file 'tests/unit/service/tasks/test_list_task.py' |
2042 | --- tests/unit/service/tasks/test_list_task.py 2016-11-07 18:51:17 +0000 |
2043 | +++ tests/unit/service/tasks/test_list_task.py 2017-01-27 18:57:35 +0000 |
2044 | @@ -1,4 +1,4 @@ |
2045 | -# Copyright 2016 Canonical Ltd. |
2046 | +# Copyright 2016-2017 Canonical Ltd. |
2047 | # |
2048 | # This program is free software: you can redistribute it and/or modify it |
2049 | # under the terms of the GNU General Public License version 3, as published |
2050 | @@ -13,7 +13,9 @@ |
2051 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
2052 | |
2053 | |
2054 | +import json |
2055 | import unittest.mock |
2056 | + |
2057 | from unittest import TestCase |
2058 | from libertine.service import tasks |
2059 | from libertine.ContainersConfig import ContainersConfig |
2060 | @@ -32,14 +34,14 @@ |
2061 | with unittest.mock.patch('libertine.service.tasks.base_task.libertine.service.progress.Progress') as MockProgress: |
2062 | progress = MockProgress.return_value |
2063 | progress.done = False |
2064 | - task = tasks.ListTask(self.connection, callback) |
2065 | + |
2066 | + task = tasks.ListTask(self.config, self.connection, callback) |
2067 | task._instant_callback = True |
2068 | |
2069 | - with unittest.mock.patch('libertine.service.tasks.list_task.utils.Libertine') as MockLibertine: |
2070 | - MockLibertine.list_containers.return_value = 'palpatine\nvader\nmaul' |
2071 | - task.start().join() |
2072 | + self.config.get_containers.return_value = ['palatine', 'vader', 'maul'] |
2073 | + task.start().join() |
2074 | |
2075 | - progress.data.assert_called_once_with('palpatine\nvader\nmaul') |
2076 | + progress.data.assert_called_once_with(json.dumps(['palatine', 'vader', 'maul'])) |
2077 | progress.finished.assert_called_once_with('') |
2078 | |
2079 | self.assertEqual(task, self.called_with) |
2080 | |
2081 | === modified file 'tests/unit/service/test_apt.py' |
2082 | --- tests/unit/service/test_apt.py 2016-11-03 20:10:47 +0000 |
2083 | +++ tests/unit/service/test_apt.py 2017-01-27 18:57:35 +0000 |
2084 | @@ -1,4 +1,4 @@ |
2085 | -# Copyright 2016 Canonical Ltd. |
2086 | +# Copyright 2016-2017 Canonical Ltd. |
2087 | # |
2088 | # This program is free software: you can redistribute it and/or modify it |
2089 | # under the terms of the GNU General Public License version 3, as published |
2090 | @@ -14,8 +14,9 @@ |
2091 | |
2092 | import os |
2093 | import unittest.mock |
2094 | +from libertine import utils |
2095 | +from libertine.service import apt |
2096 | from unittest import TestCase |
2097 | -from libertine.service import apt |
2098 | |
2099 | |
2100 | def build_mock_app(name, summary, website, description): |
2101 | @@ -30,13 +31,13 @@ |
2102 | |
2103 | |
2104 | class TestAptCache(TestCase): |
2105 | + def setUp(self): |
2106 | + os.environ['XDG_CACHE_HOME'] = "{}/containerroot".format(os.environ['LIBERTINE_DATA_DIR']) |
2107 | + |
2108 | def test_search_returns_empty_when_no_matching_results(self): |
2109 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2110 | MockCache.return_value.keys.return_value = [] |
2111 | - |
2112 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2113 | - MockLibertine.container_path.return_value = '/some/junk' |
2114 | - self.assertEqual(apt.AptCache('palpatine').search('vim'), []) |
2115 | + self.assertEqual(apt.AptCache('palpatine').search('vim'), []) |
2116 | |
2117 | def test_search_returns_matching_results(self): |
2118 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2119 | @@ -47,9 +48,7 @@ |
2120 | "vim-common": build_mock_app("vim-common", "common vim stuff", "vim.common", "dependencies") |
2121 | } |
2122 | |
2123 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2124 | - MockLibertine.container_path.return_value = '/some/junk' |
2125 | - results = apt.AptCache('palpatine').search('vim') |
2126 | + results = apt.AptCache('palpatine').search('vim') |
2127 | |
2128 | self.assertEqual(len(results), 2) |
2129 | results = sorted(results, key=lambda xx: xx['id']) |
2130 | @@ -67,15 +66,13 @@ |
2131 | self.assertEqual(results[1]['website'], 'vim.common') |
2132 | self.assertEqual(results[1]['package'], 'vim-common') |
2133 | |
2134 | - MockCache.assert_called_once_with() |
2135 | + MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine')) |
2136 | |
2137 | def test_app_info_returns_empty_dict_when_no_such_app_exists(self): |
2138 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2139 | MockCache.return_value = {} |
2140 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2141 | - MockLibertine.container_path.return_value = '/some/junk' |
2142 | - self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {}) |
2143 | - MockCache.assert_called_once_with() |
2144 | + self.assertEqual(apt.AptCache('palpatine').app_info("vim"), {}) |
2145 | + MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine')) |
2146 | |
2147 | def test_app_info_returns_values_for_app(self): |
2148 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2149 | @@ -83,17 +80,15 @@ |
2150 | "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"), |
2151 | "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"), |
2152 | } |
2153 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2154 | - MockLibertine.container_path.return_value = '/some/junk' |
2155 | - self.assertEqual(apt.AptCache('palpatine').app_info("vim"), { |
2156 | - 'name': 'vim', |
2157 | - 'id': 'vim', |
2158 | - 'package': 'vim', |
2159 | - 'summary': 'vi improved', |
2160 | - 'description': 'who even uses raw vi', |
2161 | - 'website': 'vim.com' |
2162 | - }) |
2163 | - MockCache.assert_called_once_with() |
2164 | + self.assertEqual(apt.AptCache('palpatine').app_info("vim"), { |
2165 | + 'name': 'vim', |
2166 | + 'id': 'vim', |
2167 | + 'package': 'vim', |
2168 | + 'summary': 'vi improved', |
2169 | + 'description': 'who even uses raw vi', |
2170 | + 'website': 'vim.com' |
2171 | + }) |
2172 | + MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine')) |
2173 | |
2174 | def test_loads_cache_from_container_directory(self): |
2175 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2176 | @@ -101,19 +96,17 @@ |
2177 | "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"), |
2178 | "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"), |
2179 | } |
2180 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2181 | - containerpath = "%s/containerroot" % os.path.dirname(os.path.realpath(__file__)) |
2182 | - MockLibertine.container_path.return_value = containerpath |
2183 | - self.assertEqual(apt.AptCache('palpatine').app_info("vim"), { |
2184 | - 'name': 'vim', |
2185 | - 'id': 'vim', |
2186 | - 'package': 'vim', |
2187 | - 'summary': 'vi improved', |
2188 | - 'description': 'who even uses raw vi', |
2189 | - 'website': 'vim.com' |
2190 | - }) |
2191 | - |
2192 | - MockCache.assert_called_once_with(rootdir=containerpath) |
2193 | + |
2194 | + self.assertEqual(apt.AptCache('palpatine').app_info("vim"), { |
2195 | + 'name': 'vim', |
2196 | + 'id': 'vim', |
2197 | + 'package': 'vim', |
2198 | + 'summary': 'vi improved', |
2199 | + 'description': 'who even uses raw vi', |
2200 | + 'website': 'vim.com' |
2201 | + }) |
2202 | + |
2203 | + MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine')) |
2204 | |
2205 | def test_loads_cache_only_once(self): |
2206 | with unittest.mock.patch('libertine.service.apt.apt.Cache') as MockCache: |
2207 | @@ -121,13 +114,12 @@ |
2208 | "vim": build_mock_app("vim", "vi improved", "vim.com", "who even uses raw vi"), |
2209 | "gimp": build_mock_app("gimp", "foss photoshop", "gimp.com", "visual text editor"), |
2210 | } |
2211 | - with unittest.mock.patch('libertine.service.apt.Libertine') as MockLibertine: |
2212 | - MockLibertine.container_path.return_value = '/some/junk' |
2213 | - cache = apt.AptCache('palpatine') |
2214 | - cache.app_info("vim") |
2215 | - cache.app_info("vim") |
2216 | - |
2217 | - MockCache.assert_called_once_with() |
2218 | + |
2219 | + cache = apt.AptCache('palpatine') |
2220 | + cache.app_info("vim") |
2221 | + cache.app_info("vim") |
2222 | + |
2223 | + MockCache.assert_called_once_with(rootdir=utils.get_libertine_container_rootfs_path('palpatine')) |
2224 | |
2225 | |
2226 | if __name__ == '__main__': |
2227 | |
2228 | === modified file 'tests/unit/service/test_container.py' |
2229 | --- tests/unit/service/test_container.py 2016-11-04 15:54:34 +0000 |
2230 | +++ tests/unit/service/test_container.py 2017-01-27 18:57:35 +0000 |
2231 | @@ -1,4 +1,4 @@ |
2232 | -# Copyright 2016 Canonical Ltd. |
2233 | +# Copyright 2016-2017 Canonical Ltd. |
2234 | # |
2235 | # This program is free software: you can redistribute it and/or modify it |
2236 | # under the terms of the GNU General Public License version 3, as published |
2237 | @@ -22,12 +22,11 @@ |
2238 | def setUp(self): |
2239 | self._connection = unittest.mock.Mock() |
2240 | self._config = unittest.mock.Mock() |
2241 | - self._lock = unittest.mock.Mock() |
2242 | |
2243 | def test_search_creates_search_task(self): |
2244 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2245 | cache = MockCache.return_value |
2246 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2247 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2248 | with unittest.mock.patch('libertine.service.container.SearchTask') as MockSearchTask: |
2249 | c.search('darkseid') |
2250 | MockSearchTask.assert_called_once_with('palpatine', cache, 'darkseid', self._connection, unittest.mock.ANY) |
2251 | @@ -36,7 +35,7 @@ |
2252 | def test_app_info_creates_app_info_task(self): |
2253 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2254 | cache = MockCache.return_value |
2255 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2256 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2257 | with unittest.mock.patch('libertine.service.container.AppInfoTask') as MockAppInfoTask: |
2258 | c.app_info('force') |
2259 | MockAppInfoTask.assert_called_once_with('palpatine', cache, 'force', [], self._config, self._connection, unittest.mock.ANY) |
2260 | @@ -45,7 +44,7 @@ |
2261 | def test_app_info_gets_related_task_info(self): |
2262 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2263 | cache = MockCache.return_value |
2264 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2265 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2266 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
2267 | MockInstallTask.return_value.package = 'darkside' |
2268 | MockInstallTask.return_value.matches.return_value = False |
2269 | @@ -60,119 +59,115 @@ |
2270 | |
2271 | def test_install_creates_install_task(self): |
2272 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2273 | - cache = MockCache.return_value |
2274 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2275 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2276 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
2277 | c.install('force') |
2278 | - MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2279 | + MockInstallTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2280 | MockInstallTask.return_value.start.assert_called_once_with() |
2281 | |
2282 | def test_install_only_calls_once_when_unfinished(self): |
2283 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2284 | - cache = MockCache.return_value |
2285 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2286 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2287 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
2288 | c.install('darkside') |
2289 | c.install('darkside') |
2290 | c.install('darkside') |
2291 | - # MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2292 | + MockInstallTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2293 | MockInstallTask.return_value.start.assert_called_once_with() |
2294 | |
2295 | def test_remove_creates_remove_task(self): |
2296 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2297 | - cache = MockCache.return_value |
2298 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2299 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2300 | with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask: |
2301 | c.remove('force') |
2302 | - MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2303 | + MockRemoveTask.assert_called_once_with('force', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2304 | MockRemoveTask.return_value.start.assert_called_once_with() |
2305 | |
2306 | def test_remove_only_calls_once_when_unfinished(self): |
2307 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2308 | - cache = MockCache.return_value |
2309 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2310 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2311 | with unittest.mock.patch('libertine.service.container.RemoveTask') as MockRemoveTask: |
2312 | c.remove('darkside') |
2313 | c.remove('darkside') |
2314 | c.remove('darkside') |
2315 | - # MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2316 | + MockRemoveTask.assert_called_once_with('darkside', 'palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2317 | MockRemoveTask.return_value.start.assert_called_once_with() |
2318 | |
2319 | def test_create_creates_create_task(self): |
2320 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2321 | - cache = MockCache.return_value |
2322 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2323 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2324 | with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask: |
2325 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
2326 | MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False, |
2327 | - self._config, self._lock, self._connection, unittest.mock.ANY) |
2328 | + self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2329 | MockCreateTask.return_value.start.assert_called_once_with() |
2330 | |
2331 | def test_create_only_calls_once_when_unfinished(self): |
2332 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2333 | - cache = MockCache.return_value |
2334 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2335 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2336 | with unittest.mock.patch('libertine.service.container.CreateTask') as MockCreateTask: |
2337 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
2338 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
2339 | c.create('Emperor Palpatine', 'zesty', 'lxd', False) |
2340 | - # MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False, |
2341 | - # self._config, self._lock, self._connection, unittest.mock.ANY) |
2342 | + MockCreateTask.assert_called_once_with('palpatine', 'Emperor Palpatine', 'zesty', 'lxd', False, |
2343 | + self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2344 | MockCreateTask.return_value.start.assert_called_once_with() |
2345 | |
2346 | def test_destroy_creates_destroy_task(self): |
2347 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2348 | - cache = MockCache.return_value |
2349 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2350 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2351 | with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask: |
2352 | c.destroy() |
2353 | - # MockDestroyTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2354 | + MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2355 | MockDestroyTask.return_value.start.assert_called_once_with() |
2356 | |
2357 | def test_destroy_only_calls_once_when_unfinished(self): |
2358 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2359 | - cache = MockCache.return_value |
2360 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2361 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2362 | with unittest.mock.patch('libertine.service.container.DestroyTask') as MockDestroyTask: |
2363 | c.destroy() |
2364 | c.destroy() |
2365 | c.destroy() |
2366 | - # MockDestroyTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2367 | + MockDestroyTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2368 | MockDestroyTask.return_value.start.assert_called_once_with() |
2369 | |
2370 | def test_update_creates_update_task(self): |
2371 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2372 | - cache = MockCache.return_value |
2373 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2374 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2375 | with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask: |
2376 | c.update() |
2377 | - MockUpdateTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2378 | + MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2379 | MockUpdateTask.return_value.start.assert_called_once_with() |
2380 | |
2381 | def test_update_only_calls_once_when_unfinished(self): |
2382 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2383 | - cache = MockCache.return_value |
2384 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2385 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2386 | with unittest.mock.patch('libertine.service.container.UpdateTask') as MockUpdateTask: |
2387 | c.update() |
2388 | c.update() |
2389 | c.update() |
2390 | - # MockUpdateTask.assert_called_once_with('palpatine', self._config, self._lock, self._connection, unittest.mock.ANY) |
2391 | + MockUpdateTask.assert_called_once_with('palpatine', self._config, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2392 | MockUpdateTask.return_value.start.assert_called_once_with() |
2393 | |
2394 | def test_list_apps_creates_list_apps_task(self): |
2395 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2396 | - cache = MockCache.return_value |
2397 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2398 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2399 | with unittest.mock.patch('libertine.service.container.ListAppsTask') as MockListAppsTask: |
2400 | c.list_apps() |
2401 | MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY) |
2402 | MockListAppsTask.return_value.start.assert_called_once_with() |
2403 | |
2404 | + def test_list_app_ids_creates_list_app_ids_task(self): |
2405 | + with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2406 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2407 | + with unittest.mock.patch('libertine.service.container.ListAppIdsTask') as MockListAppsTask: |
2408 | + c.list_app_ids() |
2409 | + MockListAppsTask.assert_called_once_with('palpatine', self._config, self._connection, unittest.mock.ANY) |
2410 | + MockListAppsTask.return_value.start.assert_called_once_with() |
2411 | + |
2412 | def test_removes_task_during_callback(self): |
2413 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2414 | - cache = MockCache.return_value |
2415 | - c = container.Container('palpatine', self._config, self._lock, self._connection, lambda task: task) |
2416 | + c = container.Container('palpatine', self._config, self._connection, lambda task: task) |
2417 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
2418 | MockInstallTask.return_value.package = 'force' |
2419 | c.install('force') |
2420 | @@ -186,11 +181,10 @@ |
2421 | |
2422 | def test_completing_all_tasks_fires_callback(self): |
2423 | with unittest.mock.patch('libertine.service.container.apt.AptCache') as MockCache: |
2424 | - cache = MockCache.return_value |
2425 | self._container_id = None |
2426 | def callback(container): |
2427 | self._container_id = container.id |
2428 | - c = container.Container('palpatine', self._config, self._lock, self._connection, callback) |
2429 | + c = container.Container('palpatine', self._config, self._connection, callback) |
2430 | with unittest.mock.patch('libertine.service.container.InstallTask') as MockInstallTask: |
2431 | c.install('force') |
2432 | name, args, kwargs = MockInstallTask.mock_calls[0] |
2433 | |
2434 | === modified file 'tests/unit/service/test_task_dispatcher.py' |
2435 | --- tests/unit/service/test_task_dispatcher.py 2016-11-03 20:20:15 +0000 |
2436 | +++ tests/unit/service/test_task_dispatcher.py 2017-01-27 18:57:35 +0000 |
2437 | @@ -1,4 +1,4 @@ |
2438 | -# Copyright 2016 Canonical Ltd. |
2439 | +# Copyright 2016-2017 Canonical Ltd. |
2440 | # |
2441 | # This program is free software: you can redistribute it and/or modify it |
2442 | # under the terms of the GNU General Public License version 3, as published |
2443 | @@ -83,6 +83,13 @@ |
2444 | self.assertEqual(123, self._dispatcher.list_apps('palpatine')) |
2445 | c.list_apps.assert_called_once_with() |
2446 | |
2447 | + def test_list_apps_calls_list_apps_on_container(self): |
2448 | + with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
2449 | + c = MockContainer.return_value |
2450 | + c.list_app_ids.return_value = 123 |
2451 | + self.assertEqual(123, self._dispatcher.list_app_ids('palpatine')) |
2452 | + c.list_app_ids.assert_called_once_with() |
2453 | + |
2454 | def test_containers_reused_on_subsequent_calls(self): |
2455 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
2456 | c = MockContainer.return_value |
2457 | @@ -90,20 +97,20 @@ |
2458 | self._dispatcher.list_apps('palpatine') |
2459 | self._dispatcher.list_apps('palpatine') |
2460 | self._dispatcher.list_apps('palpatine') |
2461 | - MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2462 | + MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2463 | |
2464 | def test_container_callback_removes_container(self): |
2465 | with unittest.mock.patch('libertine.service.task_dispatcher.Container') as MockContainer: |
2466 | c = MockContainer.return_value |
2467 | c.id = 'palpatine' |
2468 | self._dispatcher.list_apps('palpatine') |
2469 | - MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2470 | + MockContainer.assert_called_once_with('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2471 | name, args, kwargs = MockContainer.mock_calls[0] |
2472 | args[len(args)-1](MockContainer.return_value) |
2473 | self._dispatcher.list_apps('palpatine') |
2474 | MockContainer.assert_has_calls([ # verify container constructed twice |
2475 | - unittest.mock.call('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY), |
2476 | - unittest.mock.call('palpatine', unittest.mock.ANY, unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2477 | + unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY), |
2478 | + unittest.mock.call('palpatine', unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2479 | ], any_order=True) |
2480 | |
2481 | def test_container_info_creates_container_info_task(self): |
2482 | @@ -131,13 +138,13 @@ |
2483 | task = MockListTask.return_value |
2484 | task.id = 123 |
2485 | self.assertEqual(123, self._dispatcher.list()) |
2486 | - MockListTask.assert_called_once_with(self._connection, unittest.mock.ANY) |
2487 | + MockListTask.assert_called_once_with(unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2488 | task.start.assert_called_once_with() |
2489 | |
2490 | def test_containerless_tasks_are_cleaned_up(self): |
2491 | with unittest.mock.patch('libertine.service.task_dispatcher.ListTask') as MockListTask: |
2492 | self._dispatcher.list() |
2493 | - MockListTask.assert_called_once_with(self._connection, unittest.mock.ANY) |
2494 | + MockListTask.assert_called_once_with(unittest.mock.ANY, self._connection, unittest.mock.ANY) |
2495 | name, args, kwargs = MockListTask.mock_calls[0] |
2496 | self.assertEqual(1, len(self._dispatcher._tasks)) |
2497 | args[len(args)-1](MockListTask.return_value) |
2498 | |
2499 | === modified file 'tests/unit/test_libertine_container.py' |
2500 | --- tests/unit/test_libertine_container.py 2016-11-10 17:40:14 +0000 |
2501 | +++ tests/unit/test_libertine_container.py 2017-01-27 18:57:35 +0000 |
2502 | @@ -1,5 +1,5 @@ |
2503 | """Unit tests for the LibertineContainer interface.""" |
2504 | -# Copyright 2015 Canonical Ltd. |
2505 | +# Copyright 2015-2017 Canonical Ltd. |
2506 | # |
2507 | # This program is free software: you can redistribute it and/or modify it |
2508 | # under the terms of the GNU General Public License version 3, as published |
2509 | @@ -52,6 +52,7 @@ |
2510 | |
2511 | def test_container_name_default(self): |
2512 | container_id = "test-id-3" |
2513 | + self._config.get_container_name.return_value = None |
2514 | container = Libertine.LibertineContainer(container_id, self._config) |
2515 | |
2516 | self.assertThat(container.name, Equals("Unknown")) |
2517 | |
2518 | === removed file 'tests/unit/test_libertine_gir.py' |
2519 | --- tests/unit/test_libertine_gir.py 2017-01-18 15:43:03 +0000 |
2520 | +++ tests/unit/test_libertine_gir.py 1970-01-01 00:00:00 +0000 |
2521 | @@ -1,65 +0,0 @@ |
2522 | -# Copyright 2015 Canonical Ltd. |
2523 | -# |
2524 | -# This program is free software: you can redistribute it and/or modify it |
2525 | -# under the terms of the GNU General Public License version 3, as published |
2526 | -# by the Free Software Foundation. |
2527 | -# |
2528 | -# This program is distributed in the hope that it will be useful, but |
2529 | -# WITHOUT ANY WARRANTY; without even the implied warranties of |
2530 | -# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2531 | -# PURPOSE. See the GNU General Public License for more details. |
2532 | -# |
2533 | -# You should have received a copy of the GNU General Public License along |
2534 | -# with this program. If not, see <http://www.gnu.org/licenses/>. |
2535 | - |
2536 | -import os |
2537 | -from testtools import TestCase |
2538 | -from testtools.matchers import Equals |
2539 | -from gi.repository import Libertine |
2540 | -from unittest import skip |
2541 | -from unittest.mock import patch |
2542 | - |
2543 | - |
2544 | -class TestLibertineGir(TestCase): |
2545 | - |
2546 | - def setUp(self): |
2547 | - super(TestLibertineGir, self).setUp() |
2548 | - self.cmake_source_dir = os.environ['LIBERTINE_DATA_DIR'] |
2549 | - |
2550 | - def test_list_containers(self): |
2551 | - with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}): |
2552 | - containers = Libertine.list_containers() |
2553 | - |
2554 | - self.assertThat(containers[0], Equals('wily')) |
2555 | - self.assertThat(containers[1], Equals('wily-2')) |
2556 | - |
2557 | - @skip("need to work around cached globals in glib") |
2558 | - def test_container_path(self): |
2559 | - container_id = 'wily' |
2560 | - with patch.dict('os.environ', {'XDG_CACHE_HOME': self.cmake_source_dir + '/libertine-data', 'IGNORE_SNAP': '1'}): |
2561 | - container_path = Libertine.container_path(container_id) |
2562 | - |
2563 | - self.assertThat(container_path, Equals(self.cmake_source_dir + '/libertine-data/libertine-container/wily/rootfs')) |
2564 | - |
2565 | - def test_container_home_path(self): |
2566 | - container_id = 'wily' |
2567 | - with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-home', 'IGNORE_SNAP': '1'}): |
2568 | - container_home_path = Libertine.container_home_path(container_id) |
2569 | - |
2570 | - self.assertThat(container_home_path, Equals(self.cmake_source_dir + '/libertine-home/libertine-container/user-data/wily')) |
2571 | - |
2572 | - def test_container_name(self): |
2573 | - with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}): |
2574 | - container_name = Libertine.container_name('wily') |
2575 | - |
2576 | - self.assertThat(container_name, Equals("Ubuntu 'Wily Werewolf'")) |
2577 | - |
2578 | - container_name = Libertine.container_name('wily-2') |
2579 | - |
2580 | - self.assertThat(container_name, Equals("Ubuntu 'Wily Werewolf' (2)")) |
2581 | - |
2582 | - def test_list_apps_for_container(self): |
2583 | - with patch.dict('os.environ', {'XDG_DATA_HOME': self.cmake_source_dir + '/libertine-config', 'IGNORE_SNAP': '1'}): |
2584 | - apps = Libertine.list_apps_for_container('wily') |
2585 | - |
2586 | - self.assertThat(len(apps), Equals(0)) |
2587 | |
2588 | === modified file 'tools/libertine-container-manager' |
2589 | --- tools/libertine-container-manager 2017-01-25 16:27:15 +0000 |
2590 | +++ tools/libertine-container-manager 2017-01-27 18:57:35 +0000 |
2591 | @@ -218,8 +218,7 @@ |
2592 | self.containers_config.update_container_install_status(container_id, "ready") |
2593 | |
2594 | def list(self, args): |
2595 | - containers = libertine.utils.Libertine.list_containers() |
2596 | - for container in containers: |
2597 | + for container in ContainersConfig().get_containers(): |
2598 | print("%s" % container) |
2599 | |
2600 | def list_apps(self, args): |
2601 | |
2602 | === modified file 'tools/libertine-lxc-manager' |
2603 | --- tools/libertine-lxc-manager 2017-01-24 20:21:16 +0000 |
2604 | +++ tools/libertine-lxc-manager 2017-01-27 18:57:35 +0000 |
2605 | @@ -83,7 +83,7 @@ |
2606 | mounts = self._sanitize_bind_mounts(libertine.utils.get_common_xdg_user_directories() + \ |
2607 | self._containers_config.get_container_bind_mounts(container_id)) |
2608 | |
2609 | - data_dir = libertine.utils.get_libertine_container_userdata_dir_path(container_id) |
2610 | + data_dir = libertine.utils.get_libertine_container_home_dir(container_id) |
2611 | for user_dir in libertine.utils.generate_binding_directories(mounts, self._home): |
2612 | if os.path.isabs(user_dir[1]): |
2613 | path = user_dir[1].strip('/') |
FAILED: Continuous integration, rev:357 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/343/ /jenkins. canonical. com/libertine/ job/build/ 672/console /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 682 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 663/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= zesty/663/ console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 663/console /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= zesty/663/ 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/343/ rebuild
https:/