Merge lp:~townsend/libertine/release-1.2 into lp:libertine/trunk
- release-1.2
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Christopher Townsend |
Approved revision: | 133 |
Merged at revision: | 132 |
Proposed branch: | lp:~townsend/libertine/release-1.2 |
Merge into: | lp:libertine/trunk |
Diff against target: |
1268 lines (+475/-159) 24 files modified
debian/changelog (+26/-0) debian/control (+2/-1) debian/libertine-tools.install (+1/-1) libertine/ContainerConfigList.cpp (+11/-3) libertine/ContainerConfigList.h (+1/-1) libertine/ContainerManager.cpp (+51/-3) libertine/ContainerManager.h (+3/-2) libertine/qml/ContainerInfoView.qml (+52/-2) libertine/qml/ContainerPasswordDialog.qml (+5/-0) libertine/qml/ContainersView.qml (+2/-3) libertine/qml/HomeView.qml (+5/-5) libertine/qml/ManageContainer.qml (+54/-21) libertine/qml/PackageInfoView.qml (+29/-10) libertine/qml/libertine.qml (+52/-27) python/libertine/ChrootContainer.py (+7/-1) python/libertine/Libertine.py (+5/-2) python/libertine/LxcContainer.py (+12/-0) python/libertine/utils.py (+17/-2) tools/CMakeLists.txt (+2/-2) tools/bash_completion.d/libertine-container-manager (+0/-72) tools/completions/libertine-container-manager (+75/-0) tools/libertine-container-manager (+38/-1) tools/libertine-container-manager.1 (+22/-0) tools/update-puritine-containers (+3/-0) |
To merge this branch: | bzr merge lp:~townsend/libertine/release-1.2 |
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brandon Schaefer (community) | Approve | ||
Review via email: mp+297503@code.launchpad.net |
Commit message
* Add maliit packages for seeding in containers upon creation. (LP: #1543351)
* Enable title bars in matchbox to work around input focus issue when using OSK in X apps. (LP: #1592549)
* Add the Vivid Stable Overlay PPA to Vivid based chroots during creation. (LP: #1587890)
* Check if ~/.cache/
* Be more verbose when the LXC container won't start. (LP: #1591228)
* Invalid Libertine Scope results after successfully installing or removing a package. (LP: #1592115)
* Add a method to set the default container. (LP: #1589674)
* Show candidate package version when installed version unavailable. (LP: #1589683)
* Install bash completion in modern install directory.
* Show operation details for create container, update container, enable multiarch, install package, and remove package. (LP: #1583323)
Description of the change
- 133. By Christopher Townsend
-
Fix a syntax error.
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2016-06-07 12:44:16 +0000 |
3 | +++ debian/changelog 2016-06-15 18:21:36 +0000 |
4 | @@ -1,3 +1,29 @@ |
5 | +libertine (1.2-0ubuntu1) UNRELEASED; urgency=medium |
6 | + |
7 | + [ Brandon Schaefer ] |
8 | + * Add maliit packages for seeding in containers upon creation. (LP: #1543351) |
9 | + * Enable title bars in matchbox to work around input focus issue when using |
10 | + OSK in X apps. (LP: #1592549) |
11 | + |
12 | + [ Chris Townsend] |
13 | + * Add the Vivid Stable Overlay PPA to Vivid based chroots during creation. |
14 | + (LP: #1587890) |
15 | + * Check if ~/.cache/libertine/puritine/ exists and create it if it doesn't. |
16 | + (LP: #1585683) |
17 | + * Be more verbose when the LXC container won't start. (LP: #1591228) |
18 | + * Invalid Libertine Scope results after successfully installing or removing |
19 | + a package. (LP: #1592115) |
20 | + |
21 | + [ Larry Price ] |
22 | + * Add a method to set the default container. (LP: #1589674) |
23 | + * Show candidate package version when installed version unavailable. |
24 | + (LP: #1589683) |
25 | + * Install bash completion in modern install directory. |
26 | + * Show operation details for create container, update container, enable |
27 | + multiarch, install package, and remove package. (LP: #1583323) |
28 | + |
29 | + -- Chris Townsend <christopher.townsend@canonical.com> Wed, 15 Jun 2016 12:28:15 -0400 |
30 | + |
31 | libertine (1.1+16.10.20160607-0ubuntu1) yakkety; urgency=medium |
32 | |
33 | [ Brandon Schaefer ] |
34 | |
35 | === modified file 'debian/control' |
36 | --- debian/control 2016-06-02 18:57:43 +0000 |
37 | +++ debian/control 2016-06-15 18:21:36 +0000 |
38 | @@ -43,7 +43,8 @@ |
39 | |
40 | Package: libertine-tools |
41 | Architecture: any |
42 | -Depends: lsb-release, |
43 | +Depends: libglib2.0-bin, |
44 | + lsb-release, |
45 | python3-apt, |
46 | python3-distro-info, |
47 | python3-libertine, |
48 | |
49 | === modified file 'debian/libertine-tools.install' |
50 | --- debian/libertine-tools.install 2016-06-06 17:40:06 +0000 |
51 | +++ debian/libertine-tools.install 2016-06-15 18:21:36 +0000 |
52 | @@ -3,7 +3,7 @@ |
53 | usr/bin/libertine-container-manager |
54 | usr/bin/libertine-lxc-manager |
55 | usr/bin/libertine-xmir |
56 | -etc/bash_completion.d/libertine-container-manager |
57 | +usr/share/bash-completion/completions/libertine-container-manager |
58 | usr/lib/*/libertine/update-puritine-containers |
59 | usr/share/man |
60 | usr/share/libertine/libertine-lxc.conf |
61 | |
62 | === modified file 'libertine/ContainerConfigList.cpp' |
63 | --- libertine/ContainerConfigList.cpp 2016-04-22 14:41:08 +0000 |
64 | +++ libertine/ContainerConfigList.cpp 2016-06-15 18:21:36 +0000 |
65 | @@ -39,6 +39,13 @@ |
66 | |
67 | #include <sys/file.h> |
68 | |
69 | +namespace |
70 | +{ |
71 | +static constexpr auto POLICY_INSTALLED_VERSION_LINE = 1; |
72 | +static constexpr auto POLICY_CANDIDATE_VERSION_LINE = 2; |
73 | + |
74 | +} |
75 | + |
76 | |
77 | const QString ContainerConfigList::Json_container_list = "containerList"; |
78 | const QString ContainerConfigList::Json_default_container = "defaultContainer"; |
79 | @@ -182,7 +189,7 @@ |
80 | |
81 | |
82 | QString ContainerConfigList:: |
83 | -getAppVersion(QString const& app_info) |
84 | +getAppVersion(QString const& app_info, bool installed) |
85 | { |
86 | if (app_info.startsWith("N:") || app_info.isEmpty()) |
87 | { |
88 | @@ -191,9 +198,10 @@ |
89 | else |
90 | { |
91 | QStringList info = app_info.split('\n'); |
92 | - return info.at(1).section(": ", 1, 1); |
93 | + return info.at(installed ? POLICY_INSTALLED_VERSION_LINE : POLICY_CANDIDATE_VERSION_LINE) |
94 | + .section(": ", 1, 1); |
95 | } |
96 | -} |
97 | +} |
98 | |
99 | |
100 | bool ContainerConfigList:: |
101 | |
102 | === modified file 'libertine/ContainerConfigList.h' |
103 | --- libertine/ContainerConfigList.h 2016-04-08 20:16:41 +0000 |
104 | +++ libertine/ContainerConfigList.h 2016-06-15 18:21:36 +0000 |
105 | @@ -111,7 +111,7 @@ |
106 | QString const& package_name); |
107 | |
108 | Q_INVOKABLE QString |
109 | - getAppVersion(QString const& app_info); |
110 | + getAppVersion(QString const& app_info, bool installed); |
111 | |
112 | Q_INVOKABLE bool |
113 | isValidDebianPackage(QString const& package_string); |
114 | |
115 | === modified file 'libertine/ContainerManager.cpp' |
116 | --- libertine/ContainerManager.cpp 2016-06-02 18:02:50 +0000 |
117 | +++ libertine/ContainerManager.cpp 2016-06-15 18:21:36 +0000 |
118 | @@ -30,6 +30,7 @@ |
119 | static const QString CONTAINER_DESTROY_FAILED = QObject::tr("Destroying container %1 failed"); |
120 | static const QString RUN_COMMAND_FAILED = QObject::tr("Running command %1 failed"); |
121 | static const QString CONTAINER_CONFIGURE_FAILED = QObject::tr("Attempt to configure container %1 failed"); |
122 | +static const QString SET_DEFAULT_CONTAINER_FAILED = QObject::tr("Attempt to set container as default failed"); |
123 | constexpr auto libertine_container_manager_tool = "libertine-container-manager"; |
124 | |
125 | |
126 | @@ -79,12 +80,20 @@ |
127 | void ContainerManagerWorker:: |
128 | createContainer(const QString& id, const QString& name, const QString& distro, bool multiarch, const QString& password) |
129 | { |
130 | + connect(&process_, &QProcess::readyRead, [=](){ |
131 | + auto output = process_.readAllStandardOutput(); |
132 | + if (!output.isEmpty()) |
133 | + { |
134 | + emit updateOperationDetails(id, "", output); |
135 | + } |
136 | + }); |
137 | connect(&process_, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), |
138 | [=](int exitCode, QProcess::ExitStatus){ |
139 | if (exitCode != 0) |
140 | { |
141 | emit error(CONTAINER_CREATE_FAILED.arg(id), process_.readAllStandardError()); |
142 | } |
143 | + emit operationFinished(id, ""); |
144 | }); |
145 | connect(&process_, &QProcess::started, [=]() { |
146 | process_.write(password.toUtf8()); |
147 | @@ -133,7 +142,7 @@ |
148 | auto output = process_.readAllStandardOutput(); |
149 | if (!output.isEmpty()) |
150 | { |
151 | - emit updatePackageOperationDetails(container_id, package_name, output); |
152 | + emit updateOperationDetails(container_id, package_name, output); |
153 | process_output_ += output; |
154 | } |
155 | }); |
156 | @@ -144,7 +153,7 @@ |
157 | auto stderr = process_.readAllStandardError(); |
158 | emit error(PACKAGE_INSTALLATION_FAILED.arg(package_name), stderr.isEmpty() ? process_output_ : stderr); |
159 | } |
160 | - emit packageOperationFinished(container_id, package_name); |
161 | + emit operationFinished(container_id, package_name); |
162 | }); |
163 | |
164 | process_.start(libertine_container_manager_tool, QStringList{"install-package", "-i", container_id, "-p", package_name, "-r"}); |
165 | @@ -158,7 +167,7 @@ |
166 | auto output = process_.readAllStandardOutput(); |
167 | if (!output.isEmpty()) |
168 | { |
169 | - emit updatePackageOperationDetails(container_id, package_name, output); |
170 | + emit updateOperationDetails(container_id, package_name, output); |
171 | process_output_ += output; |
172 | } |
173 | }); |
174 | @@ -168,6 +177,7 @@ |
175 | { |
176 | emit error(PACKAGE_INSTALLATION_FAILED.arg(package_name), process_output_.isEmpty() ? process_.readAllStandardError() : process_output_); |
177 | } |
178 | + emit operationFinished(container_id, package_name); |
179 | }); |
180 | |
181 | process_.start(libertine_container_manager_tool, QStringList{"remove-package", "-i", container_id, "-p", package_name, "-r"}); |
182 | @@ -211,12 +221,20 @@ |
183 | void ContainerManagerWorker:: |
184 | updateContainer(const QString& container_id, const QString& container_name) |
185 | { |
186 | + connect(&process_, &QProcess::readyRead, [=](){ |
187 | + auto output = process_.readAllStandardOutput(); |
188 | + if (!output.isEmpty()) |
189 | + { |
190 | + emit updateOperationDetails(container_id, "", output); |
191 | + } |
192 | + }); |
193 | connect(&process_, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), |
194 | [=](int exitCode, QProcess::ExitStatus){ |
195 | if (exitCode != 0) |
196 | { |
197 | emit error(CONTAINER_UPDATE_FAILED.arg(container_name), readAllStdOutOrStdErr(process_)); |
198 | } |
199 | + emit operationFinished(container_id, ""); |
200 | }); |
201 | |
202 | process_.start(libertine_container_manager_tool, QStringList{"update", "-i", container_id}); |
203 | @@ -245,6 +263,13 @@ |
204 | void ContainerManagerWorker:: |
205 | configureContainer(const QString& container_id, const QString& container_name, const QStringList& configure_command) |
206 | { |
207 | + connect(&process_, &QProcess::readyRead, [=](){ |
208 | + auto output = process_.readAllStandardOutput(); |
209 | + if (!output.isEmpty()) |
210 | + { |
211 | + emit updateOperationDetails(container_id, "", output); |
212 | + } |
213 | + }); |
214 | connect(&process_, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), |
215 | [=](int exitCode, QProcess::ExitStatus){ |
216 | if (exitCode != 0) |
217 | @@ -255,6 +280,7 @@ |
218 | { |
219 | emit finishedConfigure(); |
220 | } |
221 | + emit operationFinished(container_id, ""); |
222 | }); |
223 | |
224 | QStringList args{"configure", "-i", container_id}; |
225 | @@ -268,3 +294,25 @@ |
226 | { |
227 | process_.start(libertine_container_manager_tool, QStringList{"fix-integrity"}); |
228 | } |
229 | + |
230 | + |
231 | +void ContainerManagerWorker:: |
232 | +setDefaultContainer(const QString& container_id, bool should_clear) |
233 | +{ |
234 | + connect(&process_, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), |
235 | + [=](int exitCode, QProcess::ExitStatus){ |
236 | + if (exitCode != 0) |
237 | + { |
238 | + emit error(SET_DEFAULT_CONTAINER_FAILED, readAllStdOutOrStdErr(process_)); |
239 | + } |
240 | + }); |
241 | + |
242 | + if (should_clear) |
243 | + { |
244 | + process_.start(libertine_container_manager_tool, QStringList{"set-default", "-c"}); |
245 | + } |
246 | + else |
247 | + { |
248 | + process_.start(libertine_container_manager_tool, QStringList{"set-default", "-i", container_id}); |
249 | + } |
250 | +} |
251 | |
252 | === modified file 'libertine/ContainerManager.h' |
253 | --- libertine/ContainerManager.h 2016-06-01 20:51:05 +0000 |
254 | +++ libertine/ContainerManager.h 2016-06-15 18:21:36 +0000 |
255 | @@ -43,6 +43,7 @@ |
256 | Q_INVOKABLE void runCommand(const QString& container_id, const QString& container_name, const QString& command_line); |
257 | Q_INVOKABLE void configureContainer(const QString& container_id, const QString& container_name, const QStringList& configure_command); |
258 | Q_INVOKABLE void fixIntegrity(); |
259 | + Q_INVOKABLE void setDefaultContainer(const QString& container_id, bool should_clear); |
260 | |
261 | public slots: |
262 | void packageOperationInteraction(const QString& input); |
263 | @@ -65,8 +66,8 @@ |
264 | void finishedSearch(QList<QString> packageList); |
265 | void finishedCommand(QString const& command_output); |
266 | void finishedConfigure(); |
267 | - void updatePackageOperationDetails(const QString& container_id, const QString& package_name, const QString& details); |
268 | - void packageOperationFinished(const QString& container_id, const QString& package_name); |
269 | + void updateOperationDetails(const QString& container_id, const QString& package_name, const QString& details); |
270 | + void operationFinished(const QString& container_id, const QString& package_name); |
271 | |
272 | void error(const QString& short_description, const QString& details); |
273 | }; |
274 | |
275 | === modified file 'libertine/qml/ContainerInfoView.qml' |
276 | --- libertine/qml/ContainerInfoView.qml 2016-05-06 21:13:01 +0000 |
277 | +++ libertine/qml/ContainerInfoView.qml 2016-06-15 18:21:36 +0000 |
278 | @@ -27,14 +27,16 @@ |
279 | id: containerInfoView |
280 | header: PageHeader { |
281 | id: pageHeader |
282 | - title: i18n.tr("Container information for %1").arg(containerConfigList.getContainerName(mainView.currentContainer)) |
283 | + title: i18n.tr("Container information for %1").arg(containerConfigList.getContainerName(currentContainer)) |
284 | } |
285 | |
286 | - property string currentContainer: mainView.currentContainer |
287 | + property string currentContainer: null |
288 | property string containerDistroText: containerConfigList.getContainerDistro(currentContainer) |
289 | property string containerNameText: containerConfigList.getContainerName(currentContainer) |
290 | property string containerIdText: currentContainer |
291 | property var statusText: containerConfigList.getContainerStatus(currentContainer) |
292 | + property bool showDetails: false |
293 | + property string operationDetails: "" |
294 | |
295 | Flickable { |
296 | anchors { |
297 | @@ -50,6 +52,7 @@ |
298 | anchors.right: parent.right |
299 | |
300 | ListItem.Standard { |
301 | + id: idView |
302 | text: i18n.tr("ID") |
303 | control: Label { |
304 | text: containerIdText |
305 | @@ -57,6 +60,7 @@ |
306 | } |
307 | |
308 | ListItem.Standard { |
309 | + id: nameView |
310 | text: i18n.tr("Name") |
311 | control: Label { |
312 | text: containerNameText |
313 | @@ -64,6 +68,7 @@ |
314 | } |
315 | |
316 | ListItem.Standard { |
317 | + id: distroView |
318 | text: i18n.tr("Distribution") |
319 | control: Label { |
320 | text: containerDistroText |
321 | @@ -71,22 +76,67 @@ |
322 | } |
323 | |
324 | ListItem.Standard { |
325 | + id: statusView |
326 | text: i18n.tr("Status") |
327 | control: Label { |
328 | text: statusText |
329 | } |
330 | } |
331 | + |
332 | + ListItem.Standard { |
333 | + id: showDetailsView |
334 | + control: Button { |
335 | + text: enabled ? |
336 | + showDetails ? i18n.tr('Hide') : i18n.tr('Show') |
337 | + : i18n.tr('None') |
338 | + enabled: operationDetails != "" |
339 | + onClicked: { |
340 | + showDetails = !showDetails |
341 | + } |
342 | + } |
343 | + text: i18n.tr("Operation details") |
344 | + } |
345 | + |
346 | + TextArea { |
347 | + id: operationDetailsView |
348 | + visible: showDetails |
349 | + anchors.left: parent.left |
350 | + anchors.right: parent.right |
351 | + height: Math.max(containerInfoView.height - pageHeader.height - idView.height - nameView.height - distroView.height |
352 | + - statusView.height - showDetailsView.height, |
353 | + units.gu(35)) |
354 | + readOnly: true |
355 | + text: operationDetails |
356 | + } |
357 | } |
358 | } |
359 | |
360 | Component.onCompleted: { |
361 | containerConfigList.configChanged.connect(reloadStatus) |
362 | + |
363 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
364 | + |
365 | + operationDetails = mainView.getOperationDetails(currentContainer) |
366 | + operationDetailsView.cursorPosition = operationDetailsView.length |
367 | + if (operationDetails != "") { |
368 | + showDetails = !showDetails |
369 | + } |
370 | + |
371 | + mainView.operationDetailsUpdated.connect(updateDetails) |
372 | } |
373 | |
374 | Component.onDestruction: { |
375 | + mainView.operationDetailsUpdated.disconnect(updateDetails) |
376 | containerConfigList.configChanged.disconnect(reloadStatus) |
377 | } |
378 | |
379 | + function updateDetails(container_id, package_name, details) { |
380 | + if (container_id === currentContainer && package_name === "") { |
381 | + operationDetails += details |
382 | + operationDetailsView.cursorPosition = operationDetailsView.length |
383 | + } |
384 | + } |
385 | + |
386 | function reloadStatus() { |
387 | statusText = containerConfigList.getContainerStatus(currentContainer) |
388 | if (!statusText) { |
389 | |
390 | === modified file 'libertine/qml/ContainerPasswordDialog.qml' |
391 | --- libertine/qml/ContainerPasswordDialog.qml 2016-05-19 17:56:43 +0000 |
392 | +++ libertine/qml/ContainerPasswordDialog.qml 2016-06-15 18:21:36 +0000 |
393 | @@ -87,6 +87,11 @@ |
394 | var container_id = containerConfigList.addNewContainer("lxc", containerName) |
395 | var comp = Qt.createComponent("ContainerManager.qml") |
396 | var worker = comp.createObject(mainView) |
397 | + |
398 | + worker.updateOperationDetails.connect(mainView.updateOperationDetails) |
399 | + worker.operationFinished.connect(mainView.resetOperationDetails) |
400 | + worker.error.connect(mainView.error) |
401 | + |
402 | worker.createContainer(container_id, containerConfigList.getContainerName(container_id), |
403 | containerConfigList.getContainerDistro(container_id), enableMultiarch, password) |
404 | } |
405 | |
406 | === modified file 'libertine/qml/ContainersView.qml' |
407 | --- libertine/qml/ContainersView.qml 2016-05-19 17:56:43 +0000 |
408 | +++ libertine/qml/ContainersView.qml 2016-06-15 18:21:36 +0000 |
409 | @@ -92,8 +92,7 @@ |
410 | text: i18n.tr("delete") |
411 | description: i18n.tr("Delete Container") |
412 | onTriggered: { |
413 | - var comp = Qt.createComponent("ContainerManager.qml") |
414 | - var worker = comp.createObject(mainView) |
415 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
416 | worker.destroyContainer(containerId) |
417 | mainView.currentContainer = containerId |
418 | } |
419 | @@ -109,7 +108,7 @@ |
420 | description: i18n.tr("Container Info") |
421 | onTriggered: { |
422 | mainView.currentContainer = containerId |
423 | - pageStack.push(Qt.resolvedUrl("ContainerInfoView.qml")) |
424 | + pageStack.push(Qt.resolvedUrl("ContainerInfoView.qml"), {currentContainer: containerId}) |
425 | } |
426 | }, |
427 | Action { |
428 | |
429 | === modified file 'libertine/qml/HomeView.qml' |
430 | --- libertine/qml/HomeView.qml 2016-05-19 18:49:06 +0000 |
431 | +++ libertine/qml/HomeView.qml 2016-06-15 18:21:36 +0000 |
432 | @@ -39,7 +39,7 @@ |
433 | } |
434 | ] |
435 | } |
436 | - property var currentContainer: null |
437 | + property string currentContainer: null |
438 | |
439 | Component { |
440 | id: enterPackagePopup |
441 | @@ -103,13 +103,13 @@ |
442 | Action { |
443 | text: i18n.tr("Manage Container") |
444 | onTriggered: { |
445 | - pageStack.push(Qt.resolvedUrl("ManageContainer.qml")) |
446 | + pageStack.push(Qt.resolvedUrl("ManageContainer.qml"), {currentContainer: currentContainer}) |
447 | } |
448 | } |
449 | Action { |
450 | text: i18n.tr("Container Information") |
451 | onTriggered: { |
452 | - pageStack.push(Qt.resolvedUrl("ContainerInfoView.qml")) |
453 | + pageStack.push(Qt.resolvedUrl("ContainerInfoView.qml"), {currentContainer: currentContainer}) |
454 | } |
455 | } |
456 | Action { |
457 | @@ -244,9 +244,9 @@ |
458 | var comp = Qt.createComponent("ContainerManager.qml") |
459 | var worker = comp.createObject(mainView) |
460 | worker.error.connect(mainView.error) |
461 | - worker.updatePackageOperationDetails.connect(mainView.updatePackageOperationDetails) |
462 | + worker.updateOperationDetails.connect(mainView.updateOperationDetails) |
463 | mainView.packageOperationInteraction.connect(worker.packageOperationInteraction) |
464 | - worker.packageOperationFinished.connect(mainView.resetPackageDetails) |
465 | + worker.operationFinished.connect(mainView.resetOperationDetails) |
466 | return worker |
467 | } |
468 | |
469 | |
470 | === modified file 'libertine/qml/ManageContainer.qml' |
471 | --- libertine/qml/ManageContainer.qml 2016-05-19 17:56:43 +0000 |
472 | +++ libertine/qml/ManageContainer.qml 2016-06-15 18:21:36 +0000 |
473 | @@ -26,8 +26,11 @@ |
474 | id: manageView |
475 | header: PageHeader { |
476 | id: pageHeader |
477 | - title: i18n.tr("Manage %1").arg(containerConfigList.getContainerName(mainView.currentContainer)) |
478 | + title: i18n.tr("Manage %1").arg(containerConfigList.getContainerName(currentContainer)) |
479 | } |
480 | + property bool isDefaultContainer: null |
481 | + property bool isMultiarchEnabled: null |
482 | + property string currentContainer: null |
483 | |
484 | Flickable { |
485 | anchors { |
486 | @@ -45,18 +48,21 @@ |
487 | ListItem.Standard { |
488 | visible: containerConfigList.getHostArchitecture() == 'x86_64' ? true : false |
489 | control: CheckBox { |
490 | - checked: containerConfigList.getContainerMultiarchSupport(mainView.currentContainer) == 'enabled' ? true : false |
491 | + checked: isMultiarchEnabled |
492 | onClicked: { |
493 | - var comp = Qt.createComponent("ContainerManager.qml") |
494 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
495 | + |
496 | + worker.updateOperationDetails.connect(mainView.updateOperationDetails) |
497 | + worker.operationFinished.connect(mainView.resetOperationDetails) |
498 | + |
499 | if (checked) { |
500 | - comp.createObject(mainView).configureContainer(mainView.currentContainer, |
501 | - containerConfigList.getContainerName(mainView.currentContainer), |
502 | - ["--multiarch", "enable"]) |
503 | - } |
504 | - else { |
505 | - comp.createObject(mainView).configureContainer(mainView.currentContainer, |
506 | - containerConfigList.getContainerName(mainView.currentContainer), |
507 | - ["--multiarch", "disable"]) |
508 | + worker.configureContainer(currentContainer, |
509 | + containerConfigList.getContainerName(currentContainer), |
510 | + ["--multiarch", "enable"]) |
511 | + } else { |
512 | + worker.configureContainer(currentContainer, |
513 | + containerConfigList.getContainerName(currentContainer), |
514 | + ["--multiarch", "disable"]) |
515 | } |
516 | } |
517 | } |
518 | @@ -67,7 +73,7 @@ |
519 | text: i18n.tr("Additional archives and PPAs") |
520 | progression: true |
521 | onClicked: { |
522 | - containerArchivesList.setContainerArchives(mainView.currentContainer) |
523 | + containerArchivesList.setContainerArchives(currentContainer) |
524 | pageStack.push(Qt.resolvedUrl("ExtraArchivesView.qml")) |
525 | } |
526 | } |
527 | @@ -76,7 +82,7 @@ |
528 | control: Button { |
529 | id: updateButton |
530 | text: i18n.tr("Update…") |
531 | - visible: (containerConfigList.getContainerStatus(mainView.currentContainer) === i18n.tr("ready")) ? true : false |
532 | + visible: (containerConfigList.getContainerStatus(currentContainer) === i18n.tr("ready")) ? true : false |
533 | onClicked: { |
534 | updateContainer() |
535 | } |
536 | @@ -88,35 +94,62 @@ |
537 | right: parent.right |
538 | rightMargin: units.gu(2) |
539 | } |
540 | - visible: (containerConfigList.getContainerStatus(mainView.currentContainer) === i18n.tr("updating")) ? true : false |
541 | + visible: (containerConfigList.getContainerStatus(currentContainer) === i18n.tr("updating")) ? true : false |
542 | running: updateActivity.visible |
543 | } |
544 | text: i18n.tr("Update container") |
545 | } |
546 | + |
547 | + |
548 | + ListItem.Standard { |
549 | + control: CheckBox { |
550 | + checked: isDefaultContainer |
551 | + onClicked: { |
552 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
553 | + worker.error.connect(mainView.error) |
554 | + var fallback = checked |
555 | + worker.error.connect(function() { |
556 | + checked = fallback |
557 | + }) |
558 | + worker.setDefaultContainer(currentContainer, !checked) |
559 | + } |
560 | + } |
561 | + text: i18n.tr("Default container") |
562 | + } |
563 | } |
564 | } |
565 | |
566 | Component.onCompleted: { |
567 | - containerConfigList.configChanged.connect(updateStatus) |
568 | + updateContainerInfo() |
569 | + containerConfigList.configChanged.connect(updateContainerInfo) |
570 | } |
571 | |
572 | Component.onDestruction: { |
573 | - containerConfigList.configChanged.disconnect(updateStatus) |
574 | + containerConfigList.configChanged.disconnect(updateContainerInfo) |
575 | } |
576 | |
577 | function updateContainer() { |
578 | - var comp = Qt.createComponent("ContainerManager.qml") |
579 | - var worker = comp.createObject(mainView) |
580 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
581 | worker.error.connect(mainView.error); |
582 | - worker.updateContainer(mainView.currentContainer, containerConfigList.getContainerName(mainView.currentContainer)) |
583 | + |
584 | + worker.updateOperationDetails.connect(mainView.updateOperationDetails) |
585 | + worker.operationFinished.connect(mainView.resetOperationDetails) |
586 | + |
587 | + worker.updateContainer(currentContainer, containerConfigList.getContainerName(currentContainer)) |
588 | + } |
589 | + |
590 | + function updateContainerInfo() { |
591 | + updateStatus() |
592 | + isDefaultContainer = containerConfigList.defaultContainerId === currentContainer |
593 | + isMultiarchEnabled = containerConfigList.getContainerMultiarchSupport(currentContainer) === 'enabled' |
594 | } |
595 | |
596 | function updateStatus() { |
597 | - if (containerConfigList.getContainerStatus(mainView.currentContainer) === i18n.tr("updating")) { |
598 | + if (containerConfigList.getContainerStatus(currentContainer) === i18n.tr("updating")) { |
599 | updateButton.visible = false |
600 | updateActivity.visible = true |
601 | } |
602 | - else if (containerConfigList.getContainerStatus(mainView.currentContainer) === i18n.tr("ready")) { |
603 | + else if (containerConfigList.getContainerStatus(currentContainer) === i18n.tr("ready")) { |
604 | updateButton.visible = true |
605 | updateActivity.visible = false |
606 | } |
607 | |
608 | === modified file 'libertine/qml/PackageInfoView.qml' |
609 | --- libertine/qml/PackageInfoView.qml 2016-05-19 17:56:43 +0000 |
610 | +++ libertine/qml/PackageInfoView.qml 2016-06-15 18:21:36 +0000 |
611 | @@ -35,6 +35,7 @@ |
612 | property var packageVersionText: i18n.tr("Obtaining package version…") |
613 | property string packageOperationDetails: "" |
614 | property var worker: null |
615 | + property bool showDetails: false |
616 | |
617 | signal sendOperationInteraction(string text) |
618 | |
619 | @@ -70,18 +71,33 @@ |
620 | } |
621 | } |
622 | |
623 | + ListItem.Standard { |
624 | + id: showDetailsView |
625 | + control: Button { |
626 | + text: enabled ? |
627 | + showDetails ? i18n.tr('Hide') : i18n.tr('Show') |
628 | + : i18n.tr('None') |
629 | + enabled: packageOperationDetails != "" |
630 | + onClicked: { |
631 | + showDetails = !showDetails |
632 | + } |
633 | + } |
634 | + text: i18n.tr("Operation details") |
635 | + } |
636 | + |
637 | TextArea { |
638 | id: packageDetailsView |
639 | - visible: text !== "" |
640 | + visible: showDetails |
641 | anchors.left: parent.left |
642 | anchors.right: parent.right |
643 | - height: Math.max(packageInfoView.height - pageHeader.height - packageListItem.height - statusListItem.height - 35, units.gu(35)) |
644 | + height: Math.max(packageInfoView.height - pageHeader.height - packageListItem.height - showDetailsView.height - statusListItem.height - 35, units.gu(35)) |
645 | readOnly: true |
646 | text: packageOperationDetails |
647 | } |
648 | |
649 | TextField { |
650 | - visible: packageDetailsView.visible && (statusText === "installing" || statusText === "removing") |
651 | + id: packageInputField |
652 | + visible: showDetails && (statusText === "installing" || statusText === "removing") |
653 | anchors.left: parent.left |
654 | anchors.right: parent.right |
655 | text: "" |
656 | @@ -96,24 +112,25 @@ |
657 | Component.onCompleted: { |
658 | containerConfigList.configChanged.connect(reloadStatus) |
659 | var command = "apt-cache policy " + currentPackage |
660 | - var comp = Qt.createComponent("ContainerManager.qml") |
661 | - worker = comp.createObject(mainView) |
662 | + var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
663 | worker.finishedCommand.connect(getPackageVersion) |
664 | |
665 | - packageOperationDetails = mainView.getPackageOperationDetails(currentContainer, currentPackage) |
666 | + packageOperationDetails = mainView.getOperationDetails(currentContainer, currentPackage) |
667 | packageDetailsView.cursorPosition = packageDetailsView.length |
668 | + if (packageOperationDetails != "") { |
669 | + showDetails = !showDetails |
670 | + } |
671 | |
672 | - mainView.updatePackageDetails.connect(updatePackageDetails) |
673 | + mainView.operationDetailsUpdated.connect(updatePackageDetails) |
674 | sendOperationInteraction.connect(mainView.packageOperationInteraction) |
675 | |
676 | - worker.error.connect(mainView.error) |
677 | worker.error.connect(onError) |
678 | worker.runCommand(currentContainer, containerConfigList.getContainerName(currentContainer), command) |
679 | } |
680 | |
681 | Component.onDestruction: { |
682 | containerConfigList.configChanged.disconnect(reloadStatus) |
683 | - mainView.updatePackageDetails.disconnect(updatePackageDetails) |
684 | + mainView.operationDetailsUpdated.disconnect(updatePackageDetails) |
685 | sendOperationInteraction.disconnect(mainView.packageOperationInteraction) |
686 | } |
687 | |
688 | @@ -133,7 +150,9 @@ |
689 | } |
690 | |
691 | function getPackageVersion(command_output) { |
692 | - packageVersionText = containerConfigList.getAppVersion(command_output) |
693 | + if (packageInfoView) { |
694 | + packageVersionText = containerConfigList.getAppVersion(command_output, statusText === "installed") |
695 | + } |
696 | } |
697 | |
698 | function onError() { |
699 | |
700 | === modified file 'libertine/qml/libertine.qml' |
701 | --- libertine/qml/libertine.qml 2016-06-02 18:02:50 +0000 |
702 | +++ libertine/qml/libertine.qml 2016-06-15 18:21:36 +0000 |
703 | @@ -29,10 +29,10 @@ |
704 | width: units.gu(90) |
705 | height: units.gu(75) |
706 | property var currentContainer: undefined |
707 | - property var packageOperationDetails: undefined |
708 | + property var operationDetails: undefined |
709 | |
710 | signal error(string short_description, string details) |
711 | - signal updatePackageDetails(string container_id, string package_name, string details) |
712 | + signal operationDetailsUpdated(string container_id, string package_name, string details) |
713 | signal packageOperationInteraction(string data) |
714 | |
715 | PageStack { |
716 | @@ -48,7 +48,7 @@ |
717 | pageStack.push(Qt.resolvedUrl("ContainersView.qml")) |
718 | if (mainView.currentContainer) { |
719 | containerAppsList.setContainerApps(mainView.currentContainer) |
720 | - pageStack.push(Qt.resolvedUrl("HomeView.qml"), {"currentContainer": mainView.currentContainer}) |
721 | + pageStack.push(Qt.resolvedUrl("HomeView.qml"), {currentContainer: mainView.currentContainer}) |
722 | } |
723 | } |
724 | else { |
725 | @@ -61,33 +61,58 @@ |
726 | {"short_description": short_description, "details": details}) |
727 | } |
728 | |
729 | - function updatePackageOperationDetails(container_id, package_name, details) { |
730 | + function initializeDetails(container_id, package_name) { |
731 | + if (!operationDetails) { |
732 | + operationDetails = {} |
733 | + } |
734 | + if (!operationDetails[container_id]) { |
735 | + operationDetails[container_id] = {packages: {}, details: ""} |
736 | + } |
737 | + if (!operationDetails[container_id].details) { |
738 | + operationDetails[container_id].details = "" |
739 | + } |
740 | + if (package_name && !operationDetails[container_id].packages[package_name]) { |
741 | + operationDetails[container_id].packages[package_name] = "" |
742 | + } |
743 | + } |
744 | + |
745 | + function updateOperationDetails(container_id, package_name, details) { |
746 | if (!mainView) { |
747 | return |
748 | } |
749 | - if (!packageOperationDetails) { |
750 | - packageOperationDetails = {} |
751 | - } |
752 | - if (!packageOperationDetails[container_id]) { |
753 | - packageOperationDetails[container_id] = {} |
754 | - } |
755 | - if (!packageOperationDetails[container_id][package_name]) { |
756 | - packageOperationDetails[container_id][package_name] = "" |
757 | - } |
758 | - packageOperationDetails[container_id][package_name] += details |
759 | - |
760 | - updatePackageDetails(container_id, package_name, details) |
761 | - } |
762 | - |
763 | - function resetPackageDetails(container_id, package_name) { |
764 | - if (mainView && packageOperationDetails && packageOperationDetails[container_id] && packageOperationDetails[container_id][package_name]) { |
765 | - delete packageOperationDetails[container_id][package_name] |
766 | - } |
767 | - } |
768 | - |
769 | - function getPackageOperationDetails(container_id, package_name) { |
770 | - if (packageOperationDetails && packageOperationDetails[container_id] && packageOperationDetails[container_id][package_name]) { |
771 | - return packageOperationDetails[container_id][package_name] |
772 | + |
773 | + initializeDetails(container_id, package_name) |
774 | + |
775 | + if (package_name) { |
776 | + operationDetails[container_id].packages[package_name] += details |
777 | + } else { |
778 | + operationDetails[container_id].details += details |
779 | + } |
780 | + |
781 | + operationDetailsUpdated(container_id, package_name, details) |
782 | + } |
783 | + |
784 | + function resetOperationDetails(container_id, package_name) { |
785 | + if (mainView && operationDetails && operationDetails[container_id]) { |
786 | + if (package_name) { |
787 | + if (operationDetails[container_id].packages[package_name]) { |
788 | + delete operationDetails[container_id].packages[package_name] |
789 | + } |
790 | + } else { |
791 | + delete operationDetails[container_id].details |
792 | + } |
793 | + } |
794 | + } |
795 | + |
796 | + function getOperationDetails(container_id, package_name) { |
797 | + if (operationDetails && operationDetails[container_id]) { |
798 | + if (package_name) { |
799 | + if (operationDetails[container_id].packages[package_name]) { |
800 | + return operationDetails[container_id].packages[package_name] |
801 | + } |
802 | + } else if (operationDetails[container_id].details) { |
803 | + return operationDetails[container_id].details |
804 | + } |
805 | } |
806 | return "" |
807 | } |
808 | |
809 | === modified file 'python/libertine/ChrootContainer.py' |
810 | --- python/libertine/ChrootContainer.py 2016-05-20 14:37:56 +0000 |
811 | +++ python/libertine/ChrootContainer.py 2016-06-15 18:21:36 +0000 |
812 | @@ -170,6 +170,12 @@ |
813 | self.destroy_libertine_container() |
814 | return False |
815 | |
816 | + if installed_release == "vivid": |
817 | + if verbosity == 1: |
818 | + print("Installing the Vivid Stable Overlay PPA...") |
819 | + self.run_in_container("add-apt-repository ppa:ci-train-ppa-service/stable-phone-overlay -y") |
820 | + self.update_packages(verbosity) |
821 | + |
822 | # Check if the container was created as root and chown the user directories as necessary |
823 | chown_recursive_dirs(utils.get_libertine_container_userdata_dir_path(self.container_id)) |
824 | |
825 | @@ -244,7 +250,7 @@ |
826 | proot_cmd = self._build_proot_command() |
827 | |
828 | args = shlex.split(proot_cmd) |
829 | - args.extend(utils.setup_window_manager(self.container_id)) |
830 | + args.extend(utils.setup_window_manager(self.container_id, enable_toolbars=True)) |
831 | window_manager = psutil.Popen(args) |
832 | |
833 | args = shlex.split(proot_cmd) |
834 | |
835 | === modified file 'python/libertine/Libertine.py' |
836 | --- python/libertine/Libertine.py 2016-06-02 18:57:43 +0000 |
837 | +++ python/libertine/Libertine.py 2016-06-15 18:21:36 +0000 |
838 | @@ -80,7 +80,10 @@ |
839 | self.default_packages = ['matchbox', |
840 | 'libnss-extrausers', |
841 | 'software-properties-common', |
842 | - 'humanity-icon-theme'] |
843 | + 'humanity-icon-theme', |
844 | + 'maliit-inputcontext-gtk2', |
845 | + 'maliit-inputcontext-gtk3', |
846 | + 'maliit-framework'] |
847 | |
848 | def create_libertine_container(self, password=None, multiarch=False, verbosity=1): |
849 | pass |
850 | @@ -148,7 +151,7 @@ |
851 | :param verbosity: the chattiness of the output on a range from 0 to 2 |
852 | """ |
853 | self.run_in_container(apt_command_prefix(verbosity) + '--force-yes update') |
854 | - return self.run_in_container(apt_command_prefix(verbosity) + '--force-yes upgrade') |
855 | + return self.run_in_container(apt_command_prefix(verbosity) + '--force-yes dist-upgrade') |
856 | |
857 | def install_package(self, package_name, verbosity=1, readline=False): |
858 | """ |
859 | |
860 | === modified file 'python/libertine/LxcContainer.py' |
861 | --- python/libertine/LxcContainer.py 2016-05-20 14:37:56 +0000 |
862 | +++ python/libertine/LxcContainer.py 2016-06-15 18:21:36 +0000 |
863 | @@ -18,6 +18,8 @@ |
864 | import psutil |
865 | import shlex |
866 | import subprocess |
867 | +import tempfile |
868 | + |
869 | from .Libertine import BaseContainer |
870 | from . import utils |
871 | from socket import * |
872 | @@ -82,6 +84,9 @@ |
873 | super().__init__(container_id) |
874 | self.container_type = "lxc" |
875 | self.container = lxc_container(container_id) |
876 | + self.lxc_log_file = os.path.join(tempfile.mkdtemp(), 'lxc-start.log') |
877 | + self.container.append_config_item("lxc.logfile", self.lxc_log_file) |
878 | + self.container.append_config_item("lxc.logpriority", "3") |
879 | |
880 | def is_running(self): |
881 | return self.container.running |
882 | @@ -100,8 +105,10 @@ |
883 | def start_container(self): |
884 | if not self.container.running: |
885 | if not self.container.start(): |
886 | + self._dump_lxc_log() |
887 | raise RuntimeError("Container failed to start") |
888 | if not self.container.wait("RUNNING", 10): |
889 | + self._dump_lxc_log() |
890 | raise RuntimeError("Container failed to enter the RUNNING state") |
891 | |
892 | if not self.container.get_ips(timeout=30): |
893 | @@ -298,3 +305,8 @@ |
894 | # Receive the reply from libertine-lxc-manager (ignore it for now). |
895 | data = libertine_lxc_mgr_sock.recv(1024) |
896 | libertine_lxc_mgr_sock.close() |
897 | + |
898 | + def _dump_lxc_log(self): |
899 | + with open(self.lxc_log_file, 'r') as fd: |
900 | + for line in fd: |
901 | + print(line.lstrip()) |
902 | |
903 | === modified file 'python/libertine/utils.py' |
904 | --- python/libertine/utils.py 2016-05-20 14:37:56 +0000 |
905 | +++ python/libertine/utils.py 2016-06-15 18:21:36 +0000 |
906 | @@ -19,6 +19,7 @@ |
907 | import json |
908 | import os |
909 | import psutil |
910 | +import shlex |
911 | import subprocess |
912 | import xdg.BaseDirectory as basedir |
913 | |
914 | @@ -29,7 +30,7 @@ |
915 | |
916 | def container_exists(container_id): |
917 | container_config_file_path = get_libertine_database_file_path() |
918 | - |
919 | + |
920 | if (os.path.exists(container_config_file_path) and |
921 | os.path.getsize(container_config_file_path) != 0): |
922 | with open(get_libertine_database_file_path()) as fd: |
923 | @@ -132,9 +133,12 @@ |
924 | return os.path.join(get_libertine_runtime_dir(), 'pulse_socket') |
925 | |
926 | |
927 | -def setup_window_manager(container_id): |
928 | +def setup_window_manager(container_id, enable_toolbars=False): |
929 | if os.path.exists(os.path.join(get_libertine_container_rootfs_path(container_id), |
930 | 'usr', 'bin', 'matchbox-window-manager')): |
931 | + if enable_toolbars: |
932 | + return ['matchbox-window-manager'] |
933 | + |
934 | return ['matchbox-window-manager', '-use_titlebar', 'no'] |
935 | else: |
936 | return ['compiz'] |
937 | @@ -147,3 +151,14 @@ |
938 | |
939 | window_manager.terminate() |
940 | window_manager.wait() |
941 | + |
942 | + |
943 | +def refresh_libertine_scope(): |
944 | + scopes_object_path = "/com/canonical/unity/scopes" |
945 | + invalidate_signal = "com.canonical.unity.scopes.InvalidateResults" |
946 | + libertine_scope_id = "libertine-scope.ubuntu_libertine-scope" |
947 | + |
948 | + gdbus_cmd = ("gdbus emit --session --object-path %s --signal %s %s" % |
949 | + (scopes_object_path, invalidate_signal, libertine_scope_id)) |
950 | + |
951 | + subprocess.Popen(shlex.split(gdbus_cmd)) |
952 | |
953 | === modified file 'tools/CMakeLists.txt' |
954 | --- tools/CMakeLists.txt 2016-06-02 20:36:30 +0000 |
955 | +++ tools/CMakeLists.txt 2016-06-15 18:21:36 +0000 |
956 | @@ -6,5 +6,5 @@ |
957 | install(PROGRAMS update-puritine-containers |
958 | DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libertine) |
959 | |
960 | -install(FILES bash_completion.d/libertine-container-manager |
961 | - DESTINATION ${DESTDIR}/etc/bash_completion.d) |
962 | +install(FILES completions/libertine-container-manager |
963 | + DESTINATION ${DESTDIR}/usr/share/bash-completion/completions/) |
964 | |
965 | === removed directory 'tools/bash_completion.d' |
966 | === removed file 'tools/bash_completion.d/libertine-container-manager' |
967 | --- tools/bash_completion.d/libertine-container-manager 2016-06-02 19:53:04 +0000 |
968 | +++ tools/bash_completion.d/libertine-container-manager 1970-01-01 00:00:00 +0000 |
969 | @@ -1,72 +0,0 @@ |
970 | -# Copyright (C) 2016 Canonical Ltd. |
971 | -# Author: Larry Price <larry.price@canonical.com> |
972 | - |
973 | -# This program is free software: you can redistribute it and/or modify |
974 | -# it under the terms of the GNU General Public License as published by |
975 | -# the Free Software Foundation; version 3 of the License. |
976 | -# |
977 | -# This program is distributed in the hope that it will be useful, |
978 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
979 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
980 | -# GNU General Public License for more details. |
981 | -# |
982 | -# You should have received a copy of the GNU General Public License |
983 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
984 | - |
985 | - |
986 | -_libertine-container-manager() |
987 | -{ |
988 | - local cur cmd opts |
989 | - COMPREPLY=() |
990 | - cur="${COMP_WORDS[COMP_CWORD]}" |
991 | - cmd="${COMP_WORDS[1]}" |
992 | - |
993 | - if [[ ${cur} == -* ]]; then |
994 | - case "${cmd}" in |
995 | - "install-package" ) |
996 | - opts="--help --id --package --readline" |
997 | - ;; |
998 | - "remove-package" ) |
999 | - opts="--help --id --package --readline" |
1000 | - ;; |
1001 | - "create" ) |
1002 | - opts="--help --id --type --distro --name --force --multiarch --password" |
1003 | - ;; |
1004 | - "destroy" ) |
1005 | - opts="--help --id" |
1006 | - ;; |
1007 | - "search-cache" ) |
1008 | - opts="--help --id --search-string" |
1009 | - ;; |
1010 | - "update" ) |
1011 | - opts="--help --id" |
1012 | - ;; |
1013 | - "list-apps" ) |
1014 | - opts="--help --id --json" |
1015 | - ;; |
1016 | - "list" ) |
1017 | - opts="--help" |
1018 | - ;; |
1019 | - "configure" ) |
1020 | - opts="--help --id --multiarch --add-archive --delete-archive" |
1021 | - ;; |
1022 | - * ) |
1023 | - opts="--help --quiet --verbose" |
1024 | - ;; |
1025 | - esac |
1026 | - fi |
1027 | - |
1028 | - if [[ ${cmd} == "configure" && "${COMP_WORDS[COMP_CWORD-1]}" == "--multiarch" ]]; then |
1029 | - opts="enable disable" |
1030 | - fi |
1031 | - |
1032 | - if [[ -z ${opts} && "${COMP_CWORD}" == "1" ]]; then |
1033 | - opts="create destroy install-package remove-package search-cache update list list-apps configure" |
1034 | - fi |
1035 | - |
1036 | - if [[ -n "${opts}" ]]; then |
1037 | - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) |
1038 | - return 0 |
1039 | - fi |
1040 | -} |
1041 | -complete -F _libertine-container-manager libertine-container-manager |
1042 | |
1043 | === added directory 'tools/completions' |
1044 | === added file 'tools/completions/libertine-container-manager' |
1045 | --- tools/completions/libertine-container-manager 1970-01-01 00:00:00 +0000 |
1046 | +++ tools/completions/libertine-container-manager 2016-06-15 18:21:36 +0000 |
1047 | @@ -0,0 +1,75 @@ |
1048 | +# Copyright (C) 2016 Canonical Ltd. |
1049 | +# Author: Larry Price <larry.price@canonical.com> |
1050 | + |
1051 | +# This program is free software: you can redistribute it and/or modify |
1052 | +# it under the terms of the GNU General Public License as published by |
1053 | +# the Free Software Foundation; version 3 of the License. |
1054 | +# |
1055 | +# This program is distributed in the hope that it will be useful, |
1056 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1057 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1058 | +# GNU General Public License for more details. |
1059 | +# |
1060 | +# You should have received a copy of the GNU General Public License |
1061 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1062 | + |
1063 | + |
1064 | +_libertine-container-manager() |
1065 | +{ |
1066 | + local cur cmd opts |
1067 | + COMPREPLY=() |
1068 | + cur="${COMP_WORDS[COMP_CWORD]}" |
1069 | + cmd="${COMP_WORDS[1]}" |
1070 | + |
1071 | + if [[ ${cur} == -* ]]; then |
1072 | + case "${cmd}" in |
1073 | + "install-package" ) |
1074 | + opts="--help --id --package --readline" |
1075 | + ;; |
1076 | + "remove-package" ) |
1077 | + opts="--help --id --package --readline" |
1078 | + ;; |
1079 | + "create" ) |
1080 | + opts="--help --id --type --distro --name --force --multiarch --password" |
1081 | + ;; |
1082 | + "destroy" ) |
1083 | + opts="--help --id" |
1084 | + ;; |
1085 | + "search-cache" ) |
1086 | + opts="--help --id --search-string" |
1087 | + ;; |
1088 | + "update" ) |
1089 | + opts="--help --id" |
1090 | + ;; |
1091 | + "list-apps" ) |
1092 | + opts="--help --id --json" |
1093 | + ;; |
1094 | + "list" ) |
1095 | + opts="--help" |
1096 | + ;; |
1097 | + "configure" ) |
1098 | + opts="--help --id --multiarch --add-archive --delete-archive" |
1099 | + ;; |
1100 | + "set-default" ) |
1101 | + opts="--help --id --clear" |
1102 | + ;; |
1103 | + * ) |
1104 | + opts="--help --quiet --verbose" |
1105 | + ;; |
1106 | + esac |
1107 | + fi |
1108 | + |
1109 | + if [[ ${cmd} == "configure" && "${COMP_WORDS[COMP_CWORD-1]}" == "--multiarch" ]]; then |
1110 | + opts="enable disable" |
1111 | + fi |
1112 | + |
1113 | + if [[ -z ${opts} && "${COMP_CWORD}" == "1" ]]; then |
1114 | + opts="create destroy install-package remove-package search-cache update list list-apps configure set-default" |
1115 | + fi |
1116 | + |
1117 | + if [[ -n "${opts}" ]]; then |
1118 | + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) |
1119 | + return 0 |
1120 | + fi |
1121 | +} |
1122 | +complete -F _libertine-container-manager libertine-container-manager |
1123 | |
1124 | === modified file 'tools/libertine-container-manager' |
1125 | --- tools/libertine-container-manager 2016-06-02 18:02:50 +0000 |
1126 | +++ tools/libertine-container-manager 2016-06-15 18:21:36 +0000 |
1127 | @@ -401,6 +401,8 @@ |
1128 | sys.exit(1) |
1129 | update_container_install_status(args.id, "ready") |
1130 | |
1131 | + libertine.utils.refresh_libertine_scope() |
1132 | + |
1133 | |
1134 | def destroy_container_by_id(id): |
1135 | container = LibertineContainer(id) |
1136 | @@ -419,6 +421,8 @@ |
1137 | |
1138 | destroy_container_by_id(args.id) |
1139 | |
1140 | + libertine.utils.refresh_libertine_scope() |
1141 | + |
1142 | |
1143 | def install_package(args): |
1144 | if args.id and not libertine.utils.container_exists(args.id): |
1145 | @@ -454,6 +458,8 @@ |
1146 | |
1147 | update_package_install_status(args.id, package, "installed") |
1148 | |
1149 | + libertine.utils.refresh_libertine_scope() |
1150 | + |
1151 | |
1152 | def remove_package_by_name(container_id, package_name, verbosity=1, readline=False): |
1153 | fallback_status = get_package_install_status(container_id, package_name) |
1154 | @@ -484,6 +490,8 @@ |
1155 | if not remove_package_by_name(args.id, args.package, args.verbosity, args.readline): |
1156 | sys.exit(1) |
1157 | |
1158 | + libertine.utils.refresh_libertine_scope() |
1159 | + |
1160 | |
1161 | def search_cache(args): |
1162 | if args.id and not libertine.utils.container_exists(args.id): |
1163 | @@ -571,7 +579,7 @@ |
1164 | print("i386 multiarch support is already %s" % multiarch) |
1165 | sys.exit(1) |
1166 | |
1167 | - if not container.configure_command('multiarch', args.multiarch): |
1168 | + if container.configure_command('multiarch', args.multiarch) is not 0: |
1169 | sys.exit(1) |
1170 | |
1171 | update_container_multiarch_support(args.id, multiarch) |
1172 | @@ -618,6 +626,22 @@ |
1173 | delete_archive_by_name(container['id'], archive['archiveName']) |
1174 | |
1175 | |
1176 | +def set_default(args): |
1177 | + if args.clear: |
1178 | + container_list = read_container_config_file() |
1179 | + container_list.pop('defaultContainer', None) |
1180 | + write_container_config_file(container_list) |
1181 | + sys.exit(0) |
1182 | + |
1183 | + if not libertine.utils.container_exists(args.id): |
1184 | + print("Container id \'%s\' does not exist." % args.id, file=sys.stderr) |
1185 | + sys.exit(1) |
1186 | + |
1187 | + container_list = read_container_config_file() |
1188 | + container_list['defaultContainer'] = args.id |
1189 | + write_container_config_file(container_list) |
1190 | + |
1191 | + |
1192 | if __name__ == '__main__': |
1193 | parser = argparse.ArgumentParser(description="Legacy X application support for Unity 8") |
1194 | |
1195 | @@ -801,6 +825,19 @@ |
1196 | add_help=False) |
1197 | parser_integrity.set_defaults(func=fix_integrity) |
1198 | |
1199 | + # Set the default container in ContainersConfig |
1200 | + parser_default = subparsers.add_parser( |
1201 | + 'set-default', |
1202 | + help=("Set the default container.")) |
1203 | + parser_default.add_argument( |
1204 | + '-i', '--id', |
1205 | + metavar='Container id', |
1206 | + help=("Container identifier. Default container is used if omitted.")) |
1207 | + parser_default.add_argument( |
1208 | + '-c', '--clear', action='store_true', |
1209 | + help=("Clear the default container.")) |
1210 | + parser_default.set_defaults(func=set_default) |
1211 | + |
1212 | # Actually parse the args |
1213 | args = parser.parse_args() |
1214 | if args.verbosity is None: |
1215 | |
1216 | === modified file 'tools/libertine-container-manager.1' |
1217 | --- tools/libertine-container-manager.1 2016-04-05 19:50:38 +0000 |
1218 | +++ tools/libertine-container-manager.1 2016-06-15 18:21:36 +0000 |
1219 | @@ -65,6 +65,9 @@ |
1220 | .TP |
1221 | .B libertine-container-manager configure [options] |
1222 | Configures various options in the specified Libertine container. |
1223 | +.TP |
1224 | +.B libertine-container-manager set-default [options] |
1225 | +Sets default container. |
1226 | |
1227 | .SH COMMAND REFERENCE |
1228 | .TP |
1229 | @@ -273,6 +276,25 @@ |
1230 | .RE |
1231 | .TP |
1232 | |
1233 | +.B libertine-container-manager set-default [options] |
1234 | +.TP |
1235 | +.SS Options: |
1236 | +.BR \-h ", " \-\-help "" |
1237 | +.RS 14 |
1238 | +Prints help for this command and exits. |
1239 | +.RE |
1240 | +.IP |
1241 | +.BR \-i " ID, " \-\-id " ID" "" |
1242 | +.RS 14 |
1243 | +Container identifier. |
1244 | +.RE |
1245 | +.IP |
1246 | +.BR \-c ", " \-\-clear "" |
1247 | +.RS 14 |
1248 | +Clear default container. |
1249 | +.RE |
1250 | +.TP |
1251 | + |
1252 | .SH SEE ALSO |
1253 | .UR https://launchpad.net/libertine |
1254 | .BR https://launchpad.net/libertine |
1255 | |
1256 | === modified file 'tools/update-puritine-containers' |
1257 | --- tools/update-puritine-containers 2016-05-06 20:12:27 +0000 |
1258 | +++ tools/update-puritine-containers 2016-06-15 18:21:36 +0000 |
1259 | @@ -119,6 +119,9 @@ |
1260 | |
1261 | puritine_symlink_farm_list = {} |
1262 | |
1263 | +if not os.path.exists(puritine_hook_dir): |
1264 | + os.makedirs(puritine_hook_dir) |
1265 | + |
1266 | if (os.path.exists(puritine_symlink_farm_file) and |
1267 | os.path.getsize(puritine_symlink_farm_file) != 0): |
1268 | with open(puritine_symlink_farm_file, 'r') as fd: |
Looks reasonable to me