Merge lp:~townsend/libertine/support-deb-install into lp:libertine
- support-deb-install
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Stephen M. Webb | ||||
Approved revision: | 181 | ||||
Merged at revision: | 186 | ||||
Proposed branch: | lp:~townsend/libertine/support-deb-install | ||||
Merge into: | lp:libertine | ||||
Diff against target: |
536 lines (+171/-58) 11 files modified
debian/control (+2/-0) libertine/ContainerAppsList.cpp (+0/-7) libertine/ContainerAppsList.h (+0/-3) libertine/ContainerConfigList.cpp (+41/-17) libertine/ContainerConfigList.h (+7/-5) libertine/qml/AppAddView.qml (+20/-11) libertine/qml/HomeView.qml (+13/-2) libertine/qml/PackageInfoView.qml (+25/-0) libertine/qml/SearchResults.qml (+0/-1) python/libertine/Libertine.py (+46/-5) tools/libertine-container-manager (+17/-7) |
||||
To merge this branch: | bzr merge lp:~townsend/libertine/support-deb-install | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stephen M. Webb (community) | Approve | ||
Libertine CI Bot | continuous-integration | Approve | |
Review via email: mp+287093@code.launchpad.net |
Commit message
Support installing Debian packages located on the host into the Libertine container.
Also fix a couple of bugs found during testing.
Description of the change
Libertine CI Bot (libertine-ci-bot) wrote : | # |
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:176
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:177
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:178
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:178
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Stephen M. Webb (bregma) wrote : | # |
When I tried to install a DEB file I ended up with a menu that did not have text [1]. I took a guess (and guessed right) and got the file selector page a selected a .deb file, but clicking 'Open' did nothing [2]. There was no way to navigate away from the file selector.
[1] http://
[2] http://
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:179
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:180
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:176
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Libertine CI Bot (libertine-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:180
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 181. By Christopher Townsend
-
Merge lp:libertine.
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:181
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Stephen M. Webb (bregma) wrote : | # |
The file dialog is sorely missed but some alternative solution can be addressed later: the rest of the change seems to work OK.
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-01-28 15:05:26 +0000 |
3 | +++ debian/control 2016-03-14 14:38:30 +0000 |
4 | @@ -10,6 +10,7 @@ |
5 | libgtest-dev, |
6 | libpam0g-dev, |
7 | lsb-release, |
8 | + python3-apt, |
9 | python3-dev, |
10 | python3-distro-info, |
11 | python3-gi, |
12 | @@ -37,6 +38,7 @@ |
13 | Package: libertine-tools |
14 | Architecture: any |
15 | Depends: lsb-release, |
16 | + python3-apt, |
17 | python3-distro-info, |
18 | python3-libertine, |
19 | ${misc:Depends}, |
20 | |
21 | === modified file 'libertine/ContainerAppsList.cpp' |
22 | --- libertine/ContainerAppsList.cpp 2016-01-20 17:34:19 +0000 |
23 | +++ libertine/ContainerAppsList.cpp 2016-03-14 14:38:30 +0000 |
24 | @@ -36,13 +36,6 @@ |
25 | setContainerApps(QString const& container_id) |
26 | { |
27 | apps_ = container_config_list_->getAppsForContainer(container_id); |
28 | -} |
29 | - |
30 | - |
31 | -void ContainerAppsList:: |
32 | -addNewApp(QString const& container_id, QString const& package_name) |
33 | -{ |
34 | - container_config_list_->addNewApp(container_id, package_name); |
35 | |
36 | beginResetModel(); |
37 | endResetModel(); |
38 | |
39 | === modified file 'libertine/ContainerAppsList.h' |
40 | --- libertine/ContainerAppsList.h 2016-01-20 17:34:19 +0000 |
41 | +++ libertine/ContainerAppsList.h 2016-03-14 14:38:30 +0000 |
42 | @@ -59,9 +59,6 @@ |
43 | setContainerApps(QString const& container_id); |
44 | |
45 | Q_INVOKABLE void |
46 | - addNewApp(QString const& container_id, QString const& package_name); |
47 | - |
48 | - Q_INVOKABLE void |
49 | removeApp(); |
50 | |
51 | Q_INVOKABLE bool |
52 | |
53 | === modified file 'libertine/ContainerConfigList.cpp' |
54 | --- libertine/ContainerConfigList.cpp 2016-03-10 21:33:25 +0000 |
55 | +++ libertine/ContainerConfigList.cpp 2016-03-14 14:38:30 +0000 |
56 | @@ -3,7 +3,7 @@ |
57 | * @brief Libertine Manager list of containers configurations |
58 | */ |
59 | /* |
60 | - * Copyright 2015 Canonical Ltd |
61 | + * Copyright 2015-2016 Canonical Ltd |
62 | * |
63 | * Libertine is free software: you can redistribute it and/or modify it under |
64 | * the terms of the GNU General Public License, version 3, as published by the |
65 | @@ -29,6 +29,7 @@ |
66 | #include <QtCore/QJsonObject> |
67 | #include <QtCore/QJsonParseError> |
68 | #include <QtCore/QJsonValue> |
69 | +#include <QtCore/QProcess> |
70 | #include <QtCore/QRegExp> |
71 | #include <QtCore/QSettings> |
72 | #include <QtCore/QString> |
73 | @@ -114,20 +115,6 @@ |
74 | } |
75 | |
76 | |
77 | -void ContainerConfigList:: |
78 | -addNewApp(QString const& container_id, QString const& package_name) |
79 | -{ |
80 | - for (auto const& config: configs_) |
81 | - { |
82 | - if (config->container_id() == container_id) |
83 | - { |
84 | - config->container_apps().append(new ContainerApps(package_name, CurrentStatus::New, this)); |
85 | - break; |
86 | - } |
87 | - } |
88 | -} |
89 | - |
90 | - |
91 | QList<ContainerApps*> * ContainerConfigList:: |
92 | getAppsForContainer(QString const& container_id) |
93 | { |
94 | @@ -187,12 +174,49 @@ |
95 | QString ContainerConfigList:: |
96 | getAppVersion(QString const& app_info) |
97 | { |
98 | - QStringList info = app_info.split('\n'); |
99 | + if (app_info.startsWith("N:") || app_info.isEmpty()) |
100 | + { |
101 | + return QString("Cannot determine package version."); |
102 | + } |
103 | + else |
104 | + { |
105 | + QStringList info = app_info.split('\n'); |
106 | |
107 | - return info.at(1).section(": ", 1, 1); |
108 | + return info.at(1).section(": ", 1, 1); |
109 | + } |
110 | } |
111 | |
112 | |
113 | +bool ContainerConfigList:: |
114 | +isValidDebianPackage(QString const& package_string) |
115 | +{ |
116 | + return (package_string.endsWith(".deb") && |
117 | + QFile::exists(package_string)); |
118 | +} |
119 | + |
120 | + |
121 | +QString ContainerConfigList:: |
122 | +getDebianPackageName(QString const& package_path) |
123 | +{ |
124 | + QProcess cmd; |
125 | + QString exec_line("dpkg-deb"); |
126 | + QStringList args; |
127 | + QByteArray package_name; |
128 | + |
129 | + args << "-f" << package_path << "Package"; |
130 | + |
131 | + cmd.start(exec_line, args); |
132 | + |
133 | + if (!cmd.waitForStarted()) |
134 | + return QString(package_name); |
135 | + |
136 | + cmd.waitForFinished(-1); |
137 | + |
138 | + package_name = cmd.readAllStandardOutput(); |
139 | + |
140 | + return QString(package_name.trimmed()); |
141 | +} |
142 | + |
143 | QList<ContainerArchives*> * ContainerConfigList:: |
144 | getArchivesForContainer(QString const& container_id) |
145 | { |
146 | |
147 | === modified file 'libertine/ContainerConfigList.h' |
148 | --- libertine/ContainerConfigList.h 2016-03-09 15:09:05 +0000 |
149 | +++ libertine/ContainerConfigList.h 2016-03-14 14:38:30 +0000 |
150 | @@ -3,7 +3,7 @@ |
151 | * @brief Libertine Manager list of containers configurations |
152 | */ |
153 | /* |
154 | - * Copyright 2015 Canonical Ltd |
155 | + * Copyright 2015-2016 Canonical Ltd |
156 | * |
157 | * Libertine is free software: you can redistribute it and/or modify it under |
158 | * the terms of the GNU General Public License, version 3, as published by the |
159 | @@ -95,10 +95,6 @@ |
160 | Q_INVOKABLE void |
161 | deleteContainer(); |
162 | |
163 | - Q_INVOKABLE void |
164 | - addNewApp(QString const& container_id, |
165 | - QString const& package_name); |
166 | - |
167 | QList<ContainerApps*> * |
168 | getAppsForContainer(QString const& container_id); |
169 | |
170 | @@ -113,6 +109,12 @@ |
171 | Q_INVOKABLE QString |
172 | getAppVersion(QString const& app_info); |
173 | |
174 | + Q_INVOKABLE bool |
175 | + isValidDebianPackage(QString const& package_string); |
176 | + |
177 | + Q_INVOKABLE QString |
178 | + getDebianPackageName(QString const& package_path); |
179 | + |
180 | QList<ContainerArchives*> * |
181 | getArchivesForContainer(QString const& container_id); |
182 | |
183 | |
184 | === modified file 'libertine/qml/AppAddView.qml' |
185 | --- libertine/qml/AppAddView.qml 2016-01-20 17:34:19 +0000 |
186 | +++ libertine/qml/AppAddView.qml 2016-03-14 14:38:30 +0000 |
187 | @@ -3,7 +3,7 @@ |
188 | * @brief Libertine app add view |
189 | */ |
190 | /* |
191 | - * Copyright 2015 Canonical Ltd |
192 | + * Copyright 2015-2016 Canonical Ltd |
193 | * |
194 | * Libertine is free software: you can redistribute it and/or modify it under |
195 | * the terms of the GNU General Public License, version 3, as published by the |
196 | @@ -18,7 +18,7 @@ |
197 | */ |
198 | import Libertine 1.0 |
199 | import QtQuick 2.4 |
200 | -import QtQuick.Layouts 1.0 |
201 | +import QtQuick.Layouts 1.1 |
202 | import Ubuntu.Components 1.2 |
203 | |
204 | |
205 | @@ -27,6 +27,7 @@ |
206 | title: i18n.tr("Install Apps") |
207 | property var search_comp: null |
208 | property var search_obj: null |
209 | + property var install_signal: null |
210 | |
211 | Label { |
212 | id: searchPackageMessage |
213 | @@ -71,7 +72,7 @@ |
214 | wrapMode: Text.Wrap |
215 | horizontalAlignment: Text.AlignHCenter |
216 | |
217 | - text: i18n.tr("Please enter the exact package name of the app to install:") |
218 | + text: i18n.tr("Please enter the exact package name or path to a Debian package to install:") |
219 | } |
220 | |
221 | TextField { |
222 | @@ -88,16 +89,19 @@ |
223 | width: parent.width - anchors.margins * 2 |
224 | |
225 | onAccepted: { |
226 | - if (!containerConfigList.isAppInstalled(mainView.currentContainer, text)) { |
227 | - containerAppsList.addNewApp(mainView.currentContainer, text) |
228 | + var package_name = text |
229 | + if (containerConfigList.isValidDebianPackage(text)) { |
230 | + package_name = containerConfigList.getDebianPackageName(text) |
231 | + } |
232 | + if (!containerConfigList.isAppInstalled(mainView.currentContainer, package_name)) { |
233 | installPackage(text) |
234 | containerAppsList.setContainerApps(mainView.currentContainer) |
235 | - mainView.currentPackage = text |
236 | + mainView.currentPackage = package_name |
237 | pageStack.pop() |
238 | - pageStack.push(Qt.resolvedUrl("PackageInfoView.qml")) |
239 | + pageStack.push(Qt.resolvedUrl("PackageInfoView.qml"), {install_signal: install_signal}) |
240 | } |
241 | else { |
242 | - appInstallMessage.text = i18n.tr("Package ") + text + i18n.tr(" already installed. Please try a different package name.") |
243 | + appInstallMessage.text = i18n.tr("Package ") + package_name + i18n.tr(" already installed. Please try a different package name.") |
244 | appInstallMessage.visible = true |
245 | appName.text = "" |
246 | } |
247 | @@ -130,8 +134,10 @@ |
248 | |
249 | head.actions: [ |
250 | Action { |
251 | - iconName: "search" |
252 | - onTriggered: { |
253 | + iconName: "search" |
254 | + text: i18n.tr("Search for package") |
255 | + description: i18n.tr("Search for packages in archives based on the search string entered.") |
256 | + onTriggered: { |
257 | if (search_obj) { |
258 | search_obj.destroy() |
259 | packageListModel.clear() |
260 | @@ -151,9 +157,11 @@ |
261 | searchString.visible = true |
262 | searchString.forceActiveFocus() |
263 | } |
264 | - }, |
265 | + }, |
266 | Action { |
267 | iconName: "settings" |
268 | + text: i18n.tr("Enter package name") |
269 | + description: i18n.tr("Enter the exact package name to install.") |
270 | onTriggered: { |
271 | if (search_obj) { |
272 | search_obj.destroy() |
273 | @@ -183,6 +191,7 @@ |
274 | "containerId": mainView.currentContainer, |
275 | "containerType": containerConfigList.getContainerType(mainView.currentContainer), |
276 | "data": package_name}) |
277 | + install_signal = worker.finishedInstall |
278 | worker.start() |
279 | } |
280 | |
281 | |
282 | === modified file 'libertine/qml/HomeView.qml' |
283 | --- libertine/qml/HomeView.qml 2016-02-10 19:31:10 +0000 |
284 | +++ libertine/qml/HomeView.qml 2016-03-14 14:38:30 +0000 |
285 | @@ -3,7 +3,7 @@ |
286 | * @brief Libertine container apps view |
287 | */ |
288 | /* |
289 | - * Copyright 2015 Canonical Ltd |
290 | + * Copyright 2015-2016 Canonical Ltd |
291 | * |
292 | * Libertine is free software: you can redistribute it and/or modify it under |
293 | * the terms of the GNU General Public License, version 3, as published by the |
294 | @@ -65,6 +65,18 @@ |
295 | } |
296 | } |
297 | |
298 | + Component.onCompleted: { |
299 | + containerConfigList.configChanged.connect(reloadAppList) |
300 | + } |
301 | + |
302 | + Component.onDestruction: { |
303 | + containerConfigList.configChanged.disconnect(reloadAppList) |
304 | + } |
305 | + |
306 | + function reloadAppList() { |
307 | + containerAppsList.setContainerApps(mainView.currentContainer) |
308 | + } |
309 | + |
310 | UbuntuListView { |
311 | anchors.fill: parent |
312 | model: containerAppsList |
313 | @@ -93,7 +105,6 @@ |
314 | text: i18n.tr("info") |
315 | description: i18n.tr("Package Info") |
316 | onTriggered: { |
317 | - containerAppsList.setContainerApps(mainView.currentContainer) |
318 | mainView.currentPackage = packageName |
319 | pageStack.push(Qt.resolvedUrl("PackageInfoView.qml")) |
320 | } |
321 | |
322 | === modified file 'libertine/qml/PackageInfoView.qml' |
323 | --- libertine/qml/PackageInfoView.qml 2016-01-22 17:27:03 +0000 |
324 | +++ libertine/qml/PackageInfoView.qml 2016-03-14 14:38:30 +0000 |
325 | @@ -28,8 +28,10 @@ |
326 | property string currentContainer: mainView.currentContainer |
327 | property var currentPackage: mainView.currentPackage |
328 | property var statusText: containerConfigList.getAppStatus(currentContainer, currentPackage) |
329 | + property var failureReasonText: null |
330 | property var packageVersionText: i18n.tr("Obtaining package version...") |
331 | property var worker: null |
332 | + property var install_signal: null |
333 | |
334 | Label { |
335 | id: packageVersion |
336 | @@ -44,7 +46,18 @@ |
337 | fontSize: "large" |
338 | } |
339 | |
340 | + Label { |
341 | + id: failureReason |
342 | + anchors.top: packageStatus.bottom |
343 | + text: i18n.tr("Failure reason: ") + failureReasonText |
344 | + fontSize: "large" |
345 | + visible: false |
346 | + } |
347 | + |
348 | Component.onCompleted: { |
349 | + if (install_signal) { |
350 | + install_signal.connect(installFinished) |
351 | + } |
352 | containerConfigList.configChanged.connect(reloadStatus) |
353 | var command = "apt-cache policy " + currentPackage |
354 | var comp = Qt.createComponent("ContainerManager.qml") |
355 | @@ -59,6 +72,9 @@ |
356 | Component.onDestruction: { |
357 | containerConfigList.configChanged.disconnect(reloadStatus) |
358 | worker.finishedCommand.disconnect(getPackageVersion) |
359 | + if (install_signal) { |
360 | + install_signal.disconnect(installFinished) |
361 | + } |
362 | } |
363 | |
364 | function reloadStatus() { |
365 | @@ -72,4 +88,13 @@ |
366 | function getPackageVersion(command_output) { |
367 | packageVersionText = containerConfigList.getAppVersion(command_output) |
368 | } |
369 | + |
370 | + function installFinished(success, error_msg) { |
371 | + if (!success) { |
372 | + statusText = i18n.tr("failed") |
373 | + failureReasonText = error_msg |
374 | + failureReason.visible = true |
375 | + } |
376 | + install_signal.disconnect(installFinished) |
377 | + } |
378 | } |
379 | |
380 | === modified file 'libertine/qml/SearchResults.qml' |
381 | --- libertine/qml/SearchResults.qml 2015-10-30 19:42:21 +0000 |
382 | +++ libertine/qml/SearchResults.qml 2016-03-14 14:38:30 +0000 |
383 | @@ -19,7 +19,6 @@ |
384 | description: i18n.tr("Install Package") |
385 | onTriggered: { |
386 | if (!containerConfigList.isAppInstalled(mainView.currentContainer, model.package_name)) { |
387 | - containerAppsList.addNewApp(mainView.currentContainer, model.package_name) |
388 | installPackage(model.package_name) |
389 | } |
390 | } |
391 | |
392 | === modified file 'python/libertine/Libertine.py' |
393 | --- python/libertine/Libertine.py 2016-03-09 15:09:05 +0000 |
394 | +++ python/libertine/Libertine.py 2016-03-14 14:38:30 +0000 |
395 | @@ -1,4 +1,4 @@ |
396 | -# Copyright 2015 Canonical Ltd. |
397 | +# Copyright 2015-2106 Canonical Ltd. |
398 | # |
399 | # This program is free software: you can redistribute it and/or modify it |
400 | # under the terms of the GNU General Public License version 3, as published |
401 | @@ -19,6 +19,7 @@ |
402 | import json |
403 | import libertine.utils |
404 | import os |
405 | +import shutil |
406 | |
407 | |
408 | def get_container_type(container_id): |
409 | @@ -76,6 +77,29 @@ |
410 | def destroy_libertine_container(self, verbosity=1): |
411 | pass |
412 | |
413 | + def copy_package_to_container(self, package_path): |
414 | + """ |
415 | + Copies a Debian package from the host to a pre-determined place |
416 | + in a container. |
417 | + |
418 | + :param package_path: The full path to the Debian package located |
419 | + on the host. |
420 | + """ |
421 | + if os.path.exists(os.path.join(self.root_path, 'tmp', package_path.split('/')[-1])): |
422 | + return False |
423 | + |
424 | + shutil.copy2(package_path, os.path.join(self.root_path, 'tmp')) |
425 | + return True |
426 | + |
427 | + def delete_package_in_container(self, package_path): |
428 | + """ |
429 | + Deletes a previously copied in Debian package in a container. |
430 | + |
431 | + :param package_path: The full path to the Debian package located |
432 | + on the host. |
433 | + """ |
434 | + os.remove(os.path.join(self.root_path, 'tmp', package_path.split('/')[-1])) |
435 | + |
436 | def is_running(self): |
437 | """ |
438 | Indicates if the container is 'running'. The definition of 'running' |
439 | @@ -119,11 +143,27 @@ |
440 | """ |
441 | Installs a named package in the container. |
442 | |
443 | - :param package_name: The name of the package as APT understands it. |
444 | + :param package_name: The name of the package as APT understands it or |
445 | + a full path to a Debian package on the host. |
446 | :param verbosity: the chattiness of the output on a range from 0 to 2 |
447 | """ |
448 | - return self.run_in_container(apt_command_prefix(verbosity) + |
449 | - extra_apt_args + " install '" + package_name + "'") == 0 |
450 | + if package_name.endswith('.deb'): |
451 | + delete_package = self.copy_package_to_container(package_name) |
452 | + |
453 | + self.run_in_container('ls -la ' + os.environ['HOME']) |
454 | + self.run_in_container('dpkg -i ' + |
455 | + os.path.join('/', 'tmp', package_name.split('/')[-1])) |
456 | + |
457 | + ret = self.run_in_container(apt_command_prefix(verbosity) + |
458 | + extra_apt_args + " install -f") == 0 |
459 | + |
460 | + if delete_package: |
461 | + self.delete_package_in_container(package_name) |
462 | + |
463 | + return ret |
464 | + else: |
465 | + return self.run_in_container(apt_command_prefix(verbosity) + |
466 | + extra_apt_args + " install '" + package_name + "'") == 0 |
467 | |
468 | def configure_command(self, command, *args, verbosity=1): |
469 | """ |
470 | @@ -283,7 +323,8 @@ |
471 | :param verbosity: The verbosity level of the progress reporting. |
472 | """ |
473 | with ContainerRunning(self.container): |
474 | - self.container.run_in_container(apt_command_prefix(verbosity) + "remove '" + package_name + "'") == 0 |
475 | + self.container.run_in_container(apt_command_prefix(verbosity) + "purge '" + package_name + "'") == 0 |
476 | + self.container.run_in_container(apt_command_prefix(verbosity) + "autoremove --purge") == 0 |
477 | |
478 | def search_package_cache(self, search_string): |
479 | """ |
480 | |
481 | === modified file 'tools/libertine-container-manager' |
482 | --- tools/libertine-container-manager 2016-03-10 21:33:25 +0000 |
483 | +++ tools/libertine-container-manager 2016-03-14 14:38:30 +0000 |
484 | @@ -25,6 +25,7 @@ |
485 | import os |
486 | import sys |
487 | |
488 | +from apt.debfile import DebPackage |
489 | from distro_info import UbuntuDistroInfo, DistroDataOutdated |
490 | from libertine import LibertineContainer |
491 | |
492 | @@ -353,20 +354,29 @@ |
493 | elif not args.id: |
494 | args.id = get_default_container_id() |
495 | |
496 | - if package_exists(args.id, args.package): |
497 | - print("Package \'%s\' is already installed." % args.package) |
498 | + if args.package.endswith('.deb'): |
499 | + if os.path.exists(args.package): |
500 | + package = DebPackage(args.package).pkgname |
501 | + else: |
502 | + print("%s does not exist." % args.package) |
503 | + sys.exit(1) |
504 | + else: |
505 | + package = args.package |
506 | + |
507 | + if package_exists(args.id, package): |
508 | + print("Package \'%s\' is already installed." % package) |
509 | sys.exit(1) |
510 | |
511 | - add_new_package(args.id, args.package) |
512 | + add_new_package(args.id, package) |
513 | |
514 | container = LibertineContainer(args.id) |
515 | |
516 | - update_package_install_status(args.id, args.package, "installing") |
517 | + update_package_install_status(args.id, package, "installing") |
518 | if not container.install_package(args.package, args.verbosity): |
519 | - delete_package(args.id, args.package) |
520 | + delete_package(args.id, package) |
521 | sys.exit(1) |
522 | |
523 | - update_package_install_status(args.id, args.package, "installed") |
524 | + update_package_install_status(args.id, package, "installed") |
525 | |
526 | |
527 | def remove_package(args): |
528 | @@ -541,7 +551,7 @@ |
529 | parser_install.add_argument( |
530 | '-p', '--package', |
531 | required=True, |
532 | - help=("Name of package to install. Required.")) |
533 | + help=("Name of package to install or full path to a Debian package. Required.")) |
534 | parser_install.add_argument( |
535 | '-i', '--id', |
536 | help=("Container identifier. Default container is used if omitted.")) |
FAILED: Continuous integration, rev:175 /jenkins. canonical. com/libertine/ job/libertine- ci-verify- mp/117/ /jenkins. canonical. com/libertine/ job/generic- ci-generate- dsc/120 /jenkins. canonical. com/libertine/ job/libertine- ci-build- and-test- dsc/architectur e=amd64, distribution= vivid,label_ exp=jenkins- slave-0% 20%7C%7C% 20jenkins- slave-2/ 79/console /jenkins. canonical. com/libertine/ job/libertine- ci-build- and-test- dsc/architectur e=amd64, distribution= xenial, label_exp= jenkins- slave-0% 20%7C%7C% 20jenkins- slave-2/ 79/console /jenkins. canonical. com/libertine/ job/libertine- ci-build- and-test- dsc/architectur e=i386, distribution= vivid,label_ exp=jenkins- slave-0% 20%7C%7C% 20jenkins- slave-2/ 79/console /jenkins. canonical. com/libertine/ job/libertine- ci-build- and-test- dsc/architectur e=i386, distribution= xenial, label_exp= jenkins- slave-0% 20%7C%7C% 20jenkins- slave-2/ 79/console /jenkins. canonical. com/libertine/ job/libertine- ci-update- mp/1015/ console
https:/
Executed test runs:
SUCCESS: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/libertine/ job/libertine- ci-verify- mp/117/ rebuild
https:/