Merge lp:~townsend/libertine/release-1.2 into lp:libertine/trunk

Proposed by Christopher Townsend
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
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/libertine/puritine/ exists and create it if it doesn't. (LP: #1585683)
* 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)

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Looks reasonable to me

review: Approve
lp:~townsend/libertine/release-1.2 updated
133. By Christopher Townsend

Fix a syntax error.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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:

Subscribers

People subscribed via source and target branches