Merge lp:~larryprice/libertine/private-ppas into lp:libertine
- private-ppas
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Christopher Townsend | ||||
Approved revision: | 280 | ||||
Merged at revision: | 271 | ||||
Proposed branch: | lp:~larryprice/libertine/private-ppas | ||||
Merge into: | lp:libertine | ||||
Diff against target: |
637 lines (+294/-151) 8 files modified
libertine/ContainerManager.cpp (+24/-0) libertine/ContainerManager.h (+1/-0) libertine/qml/AddExtraArchiveView.qml (+117/-0) libertine/qml/ExtraArchivesView.qml (+13/-68) libertine/qml/ManageContainer.qml (+1/-1) python/libertine/Libertine.py (+69/-33) tools/libertine-container-manager (+56/-41) tools/libertine-container-manager.1 (+13/-8) |
||||
To merge this branch: | bzr merge lp:~larryprice/libertine/private-ppas | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christopher Townsend | Approve | ||
Libertine CI Bot | continuous-integration | Approve | |
Review via email: mp+299838@code.launchpad.net |
Commit message
Support adding private PPAs inside of a container.
Description of the change
Support adding private PPAs inside of a container.
Refactored `libertine-
Moved archive additions to new page with line items for archive URI and optional public signing key.
Libertine CI Bot (libertine-ci-bot) wrote : | # |
Christopher Townsend (townsend) wrote : | # |
Very nice!
One general visual comment. When an archive with a long name is installing, the busy spinner is overlapping the text of the archive name. Is there any way to limit the right margin of the string to not overlap the spinner while the archive is being added? After the archive is successfully added, then I think it's ok to bring the right margin back over to where it is now.
- 280. By Larry Price
-
Remove unnecessary code and fix archive name length
Libertine CI Bot (libertine-ci-bot) wrote : | # |
PASSED: Continuous integration, rev:280
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild:
https:/
Christopher Townsend (townsend) wrote : | # |
Ok, good.
Preview Diff
1 | === modified file 'libertine/ContainerManager.cpp' | |||
2 | --- libertine/ContainerManager.cpp 2016-07-11 15:45:59 +0000 | |||
3 | +++ libertine/ContainerManager.cpp 2016-07-13 19:49:12 +0000 | |||
4 | @@ -17,6 +17,7 @@ | |||
5 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
6 | 18 | */ | 18 | */ |
7 | 19 | #include "libertine/ContainerManager.h" | 19 | #include "libertine/ContainerManager.h" |
8 | 20 | #include <QTemporaryFile> | ||
9 | 20 | 21 | ||
10 | 21 | 22 | ||
11 | 22 | namespace | 23 | namespace |
12 | @@ -293,6 +294,29 @@ | |||
13 | 293 | 294 | ||
14 | 294 | 295 | ||
15 | 295 | void ContainerManagerWorker:: | 296 | void ContainerManagerWorker:: |
16 | 297 | addArchive(const QString& container_id, const QString& container_name, const QString& archive, const QByteArray& signing_key) | ||
17 | 298 | { | ||
18 | 299 | QStringList command{"--archive", "add", "--archive-name", archive}; | ||
19 | 300 | if (!signing_key.isEmpty()) | ||
20 | 301 | { | ||
21 | 302 | QTemporaryFile keyfile; | ||
22 | 303 | if (!keyfile.open()) | ||
23 | 304 | { | ||
24 | 305 | emit error(CONTAINER_CONFIGURE_FAILED.arg(container_name), keyfile.errorString()); | ||
25 | 306 | return; | ||
26 | 307 | } | ||
27 | 308 | |||
28 | 309 | keyfile.setAutoRemove(false); | ||
29 | 310 | keyfile.write(signing_key); | ||
30 | 311 | |||
31 | 312 | command << "--public-key-file" << keyfile.fileName(); | ||
32 | 313 | } | ||
33 | 314 | |||
34 | 315 | configureContainer(container_id, container_name, command); | ||
35 | 316 | } | ||
36 | 317 | |||
37 | 318 | |||
38 | 319 | void ContainerManagerWorker:: | ||
39 | 296 | fixIntegrity() | 320 | fixIntegrity() |
40 | 297 | { | 321 | { |
41 | 298 | process_.start(libertine_container_manager_tool, QStringList{"fix-integrity"}); | 322 | process_.start(libertine_container_manager_tool, QStringList{"fix-integrity"}); |
42 | 299 | 323 | ||
43 | === modified file 'libertine/ContainerManager.h' | |||
44 | --- libertine/ContainerManager.h 2016-06-08 21:12:57 +0000 | |||
45 | +++ libertine/ContainerManager.h 2016-07-13 19:49:12 +0000 | |||
46 | @@ -42,6 +42,7 @@ | |||
47 | 42 | Q_INVOKABLE void updateContainer(const QString& container_id, const QString& container_name); | 42 | Q_INVOKABLE void updateContainer(const QString& container_id, const QString& container_name); |
48 | 43 | Q_INVOKABLE void runCommand(const QString& container_id, const QString& container_name, const QString& command_line); | 43 | Q_INVOKABLE void runCommand(const QString& container_id, const QString& container_name, const QString& command_line); |
49 | 44 | Q_INVOKABLE void configureContainer(const QString& container_id, const QString& container_name, const QStringList& configure_command); | 44 | Q_INVOKABLE void configureContainer(const QString& container_id, const QString& container_name, const QStringList& configure_command); |
50 | 45 | Q_INVOKABLE void addArchive(const QString& container_id, const QString& container_name, const QString& archive, const QByteArray& signing_key); | ||
51 | 45 | Q_INVOKABLE void fixIntegrity(); | 46 | Q_INVOKABLE void fixIntegrity(); |
52 | 46 | Q_INVOKABLE void setDefaultContainer(const QString& container_id, bool should_clear); | 47 | Q_INVOKABLE void setDefaultContainer(const QString& container_id, bool should_clear); |
53 | 47 | 48 | ||
54 | 48 | 49 | ||
55 | === added file 'libertine/qml/AddExtraArchiveView.qml' | |||
56 | --- libertine/qml/AddExtraArchiveView.qml 1970-01-01 00:00:00 +0000 | |||
57 | +++ libertine/qml/AddExtraArchiveView.qml 2016-07-13 19:49:12 +0000 | |||
58 | @@ -0,0 +1,117 @@ | |||
59 | 1 | /** | ||
60 | 2 | * @file AddExtraArchiveView.qml | ||
61 | 3 | * @brief Libertine container add archive view | ||
62 | 4 | */ | ||
63 | 5 | /* | ||
64 | 6 | * Copyright 2016 Canonical Ltd | ||
65 | 7 | * | ||
66 | 8 | * Libertine is free software: you can redistribute it and/or modify it under | ||
67 | 9 | * the terms of the GNU General Public License, version 3, as published by the | ||
68 | 10 | * Free Software Foundation. | ||
69 | 11 | * | ||
70 | 12 | * Libertine is distributed in the hope that it will be useful, but WITHOUT ANY | ||
71 | 13 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
72 | 14 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
73 | 15 | * | ||
74 | 16 | * You should have received a copy of the GNU General Public License | ||
75 | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
76 | 18 | */ | ||
77 | 19 | import Libertine 1.0 | ||
78 | 20 | import QtQuick 2.4 | ||
79 | 21 | import Ubuntu.Components 1.3 | ||
80 | 22 | |||
81 | 23 | Page { | ||
82 | 24 | id: addExtraArchiveView | ||
83 | 25 | header: PageHeader { | ||
84 | 26 | id: pageHeader | ||
85 | 27 | title: i18n.tr("Add Archive") | ||
86 | 28 | } | ||
87 | 29 | property string currentContainer: "" | ||
88 | 30 | |||
89 | 31 | Column { | ||
90 | 32 | spacing: units.gu(2) | ||
91 | 33 | |||
92 | 34 | anchors { | ||
93 | 35 | topMargin: pageHeader.height + units.gu(2) | ||
94 | 36 | leftMargin: units.gu(2) | ||
95 | 37 | rightMargin: units.gu(2) | ||
96 | 38 | fill: parent | ||
97 | 39 | } | ||
98 | 40 | |||
99 | 41 | Label { | ||
100 | 42 | text: i18n.tr("New archive identifier, e.g.") | ||
101 | 43 | anchors { | ||
102 | 44 | left: parent.left | ||
103 | 45 | right: parent.right | ||
104 | 46 | } | ||
105 | 47 | } | ||
106 | 48 | |||
107 | 49 | TextEdit { | ||
108 | 50 | text: i18n.tr("multiverse\nppa:user/repository\ndeb http://myserver/repo stable repo") | ||
109 | 51 | anchors { | ||
110 | 52 | left: parent.left | ||
111 | 53 | right: parent.right | ||
112 | 54 | leftMargin: units.gu(4) | ||
113 | 55 | } | ||
114 | 56 | |||
115 | 57 | readOnly: true | ||
116 | 58 | color: UbuntuColors.darkGrey | ||
117 | 59 | } | ||
118 | 60 | |||
119 | 61 | TextField { | ||
120 | 62 | id: extraArchiveString | ||
121 | 63 | anchors { | ||
122 | 64 | left: parent.left | ||
123 | 65 | right: parent.right | ||
124 | 66 | } | ||
125 | 67 | onAccepted: { | ||
126 | 68 | addArchive() | ||
127 | 69 | } | ||
128 | 70 | } | ||
129 | 71 | |||
130 | 72 | Label { | ||
131 | 73 | text: i18n.tr("(Optional) Public signing key for archive") | ||
132 | 74 | anchors { | ||
133 | 75 | left: parent.left | ||
134 | 76 | right: parent.right | ||
135 | 77 | } | ||
136 | 78 | } | ||
137 | 79 | |||
138 | 80 | TextArea { | ||
139 | 81 | id: publicSigningKey | ||
140 | 82 | anchors { | ||
141 | 83 | left: parent.left | ||
142 | 84 | right: parent.right | ||
143 | 85 | } | ||
144 | 86 | height: Math.max(addExtraArchiveView.height/3, units.gu(6)) | ||
145 | 87 | } | ||
146 | 88 | |||
147 | 89 | Button { | ||
148 | 90 | text: i18n.tr("Add") | ||
149 | 91 | color: UbuntuColors.green | ||
150 | 92 | onClicked: { | ||
151 | 93 | addArchive() | ||
152 | 94 | } | ||
153 | 95 | } | ||
154 | 96 | } | ||
155 | 97 | |||
156 | 98 | function addArchive() { | ||
157 | 99 | var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) | ||
158 | 100 | worker.finishedConfigure.connect(finishedConfigure) | ||
159 | 101 | worker.error.connect(mainView.error) | ||
160 | 102 | worker.addArchive(currentContainer, containerConfigList.getContainerName(currentContainer), | ||
161 | 103 | extraArchiveString.text, publicSigningKey.text.trim()) | ||
162 | 104 | |||
163 | 105 | pageStack.pop() | ||
164 | 106 | } | ||
165 | 107 | |||
166 | 108 | Component.onCompleted: { | ||
167 | 109 | extraArchiveString.forceActiveFocus() | ||
168 | 110 | } | ||
169 | 111 | |||
170 | 112 | function finishedConfigure() { | ||
171 | 113 | if (addExtraArchiveView) { | ||
172 | 114 | containerArchivesList.setContainerArchives(currentContainer) | ||
173 | 115 | } | ||
174 | 116 | } | ||
175 | 117 | } | ||
176 | 0 | 118 | ||
177 | === modified file 'libertine/qml/ExtraArchivesView.qml' | |||
178 | --- libertine/qml/ExtraArchivesView.qml 2016-07-11 17:06:17 +0000 | |||
179 | +++ libertine/qml/ExtraArchivesView.qml 2016-07-13 19:49:12 +0000 | |||
180 | @@ -1,6 +1,6 @@ | |||
181 | 1 | /** | 1 | /** |
182 | 2 | * @file ExtraArchiveView.qml | 2 | * @file ExtraArchiveView.qml |
184 | 3 | * @brief Libertine container add archive view | 3 | * @brief Libertine container extra archive view |
185 | 4 | */ | 4 | */ |
186 | 5 | /* | 5 | /* |
187 | 6 | * Copyright 2016 Canonical Ltd | 6 | * Copyright 2016 Canonical Ltd |
188 | @@ -19,66 +19,25 @@ | |||
189 | 19 | import Libertine 1.0 | 19 | import Libertine 1.0 |
190 | 20 | import QtQuick 2.4 | 20 | import QtQuick 2.4 |
191 | 21 | import Ubuntu.Components 1.3 | 21 | import Ubuntu.Components 1.3 |
192 | 22 | import Ubuntu.Components.Popups 1.3 | ||
193 | 23 | 22 | ||
194 | 24 | Page { | 23 | Page { |
195 | 25 | id: extraArchiveView | 24 | id: extraArchiveView |
196 | 26 | header: PageHeader { | 25 | header: PageHeader { |
197 | 27 | id: pageHeader | 26 | id: pageHeader |
199 | 28 | title: i18n.tr("Additional Archives and PPAs") | 27 | title: i18n.tr("Additional Archives") |
200 | 29 | trailingActionBar.actions: [ | 28 | trailingActionBar.actions: [ |
201 | 30 | Action { | 29 | Action { |
202 | 31 | iconName: "add" | 30 | iconName: "add" |
203 | 32 | text: i18n.tr("add") | 31 | text: i18n.tr("add") |
206 | 33 | description: i18n.tr("Add a new PPA") | 32 | description: i18n.tr("Add a new archive") |
207 | 34 | onTriggered: PopupUtils.open(addArchivePopup) | 33 | onTriggered: pageStack.push(Qt.resolvedUrl("AddExtraArchiveView.qml"), {currentContainer: currentContainer}) |
208 | 35 | } | 34 | } |
209 | 36 | ] | 35 | ] |
210 | 37 | } | 36 | } |
213 | 38 | property var archive_name: null | 37 | property string currentContainer: "" |
214 | 39 | property var worker: null | 38 | |
215 | 40 | signal error(string description, string details) | 39 | signal error(string description, string details) |
216 | 41 | 40 | ||
217 | 42 | Component { | ||
218 | 43 | id: addArchivePopup | ||
219 | 44 | Dialog { | ||
220 | 45 | id: addArchiveDialog | ||
221 | 46 | title: i18n.tr("Add additional archive") | ||
222 | 47 | text: i18n.tr("Enter new archive identifier, e.g.:") | ||
223 | 48 | |||
224 | 49 | TextEdit { | ||
225 | 50 | text: i18n.tr("multiverse\nppa:user/repository\ndeb http://myserver/repo stable repo") | ||
226 | 51 | readOnly: true | ||
227 | 52 | color: UbuntuColors.darkGrey | ||
228 | 53 | } | ||
229 | 54 | |||
230 | 55 | TextField { | ||
231 | 56 | id: extraArchiveString | ||
232 | 57 | placeholderText: i18n.tr("new archive name") | ||
233 | 58 | onAccepted: { | ||
234 | 59 | PopupUtils.close(addArchiveDialog) | ||
235 | 60 | addArchive(text) | ||
236 | 61 | } | ||
237 | 62 | } | ||
238 | 63 | Button { | ||
239 | 64 | text: i18n.tr("OK") | ||
240 | 65 | color: UbuntuColors.green | ||
241 | 66 | onClicked: { | ||
242 | 67 | PopupUtils.close(addArchiveDialog) | ||
243 | 68 | addArchive(extraArchiveString.text) | ||
244 | 69 | } | ||
245 | 70 | } | ||
246 | 71 | Button { | ||
247 | 72 | text: i18n.tr("Cancel") | ||
248 | 73 | color: UbuntuColors.red | ||
249 | 74 | onClicked: PopupUtils.close(addArchiveDialog) | ||
250 | 75 | } | ||
251 | 76 | Component.onCompleted: { | ||
252 | 77 | extraArchiveString.forceActiveFocus() | ||
253 | 78 | } | ||
254 | 79 | } | ||
255 | 80 | } | ||
256 | 81 | |||
257 | 82 | UbuntuListView { | 41 | UbuntuListView { |
258 | 83 | id: extraArchiveList | 42 | id: extraArchiveList |
259 | 84 | anchors { | 43 | anchors { |
260 | @@ -95,6 +54,8 @@ | |||
261 | 95 | leftMargin: units.gu(2) | 54 | leftMargin: units.gu(2) |
262 | 96 | } | 55 | } |
263 | 97 | text: archiveName | 56 | text: archiveName |
264 | 57 | width: parent.width - units.gu(8) | ||
265 | 58 | elide: Text.ElideMiddle | ||
266 | 98 | } | 59 | } |
267 | 99 | ActivityIndicator { | 60 | ActivityIndicator { |
268 | 100 | id: extraArchiveActivity | 61 | id: extraArchiveActivity |
269 | @@ -132,18 +93,11 @@ | |||
270 | 132 | text: i18n.tr("No additional archives and PPA's have been added") | 93 | text: i18n.tr("No additional archives and PPA's have been added") |
271 | 133 | } | 94 | } |
272 | 134 | 95 | ||
273 | 135 | function addArchive(archive) { | ||
274 | 136 | var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) | ||
275 | 137 | worker.finishedConfigure.connect(finishedConfigure) | ||
276 | 138 | worker.error.connect(sendAddError) | ||
277 | 139 | worker.configureContainer(mainView.currentContainer, containerConfigList.getContainerName(mainView.currentContainer), ["--add-archive", "\"" + archive + "\""]) | ||
278 | 140 | } | ||
279 | 141 | |||
280 | 142 | function deleteArchive(archive) { | 96 | function deleteArchive(archive) { |
281 | 143 | var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) | 97 | var worker = Qt.createComponent("ContainerManager.qml").createObject(mainView) |
282 | 144 | worker.finishedConfigure.connect(finishedConfigure) | 98 | worker.finishedConfigure.connect(finishedConfigure) |
283 | 145 | worker.error.connect(sendDeleteError) | 99 | worker.error.connect(sendDeleteError) |
285 | 146 | worker.configureContainer(mainView.currentContainer, containerConfigList.getContainerName(mainView.currentContainer), ["--delete-archive", "\"" + archive + "\""]) | 100 | worker.configureContainer(currentContainer, containerConfigList.getContainerName(currentContainer), ["--archive", "remove", "--archive-name", "\"" + archive + "\""]) |
286 | 147 | } | 101 | } |
287 | 148 | 102 | ||
288 | 149 | Component.onCompleted: { | 103 | Component.onCompleted: { |
289 | @@ -153,28 +107,19 @@ | |||
290 | 153 | 107 | ||
291 | 154 | Component.onDestruction: { | 108 | Component.onDestruction: { |
292 | 155 | containerConfigList.configChanged.disconnect(reloadArchives) | 109 | containerConfigList.configChanged.disconnect(reloadArchives) |
293 | 156 | |||
294 | 157 | error.disconnect(mainView.error) | 110 | error.disconnect(mainView.error) |
295 | 158 | |||
296 | 159 | if (worker) { | ||
297 | 160 | worker.finishedConfigure.disconnect(finishedConfigure) | ||
298 | 161 | worker.error.disconnect(sendAddError) | ||
299 | 162 | worker.error.disconnect(sendDeleteError) | ||
300 | 163 | } | ||
301 | 164 | } | 111 | } |
302 | 165 | 112 | ||
303 | 166 | function reloadArchives() { | 113 | function reloadArchives() { |
305 | 167 | containerArchivesList.setContainerArchives(mainView.currentContainer) | 114 | containerArchivesList.setContainerArchives(currentContainer) |
306 | 168 | 115 | ||
307 | 169 | extraArchiveList.visible = !containerArchivesList.empty() ? true : false | 116 | extraArchiveList.visible = !containerArchivesList.empty() ? true : false |
308 | 170 | } | 117 | } |
309 | 171 | 118 | ||
310 | 172 | function finishedConfigure() { | 119 | function finishedConfigure() { |
316 | 173 | containerArchivesList.setContainerArchives(mainView.currentContainer) | 120 | if (extraArchiveView) { |
317 | 174 | } | 121 | containerArchivesList.setContainerArchives(currentContainer) |
318 | 175 | 122 | } | |
314 | 176 | function sendAddError(desc, details) { | ||
315 | 177 | error(i18n.tr("Adding archive failed"), details) | ||
319 | 178 | } | 123 | } |
320 | 179 | 124 | ||
321 | 180 | function sendDeleteError(desc, details) { | 125 | function sendDeleteError(desc, details) { |
322 | 181 | 126 | ||
323 | === modified file 'libertine/qml/ManageContainer.qml' | |||
324 | --- libertine/qml/ManageContainer.qml 2016-06-08 21:56:53 +0000 | |||
325 | +++ libertine/qml/ManageContainer.qml 2016-07-13 19:49:12 +0000 | |||
326 | @@ -74,7 +74,7 @@ | |||
327 | 74 | progression: true | 74 | progression: true |
328 | 75 | onClicked: { | 75 | onClicked: { |
329 | 76 | containerArchivesList.setContainerArchives(currentContainer) | 76 | containerArchivesList.setContainerArchives(currentContainer) |
331 | 77 | pageStack.push(Qt.resolvedUrl("ExtraArchivesView.qml")) | 77 | pageStack.push(Qt.resolvedUrl("ExtraArchivesView.qml"), {currentContainer: currentContainer}) |
332 | 78 | } | 78 | } |
333 | 79 | } | 79 | } |
334 | 80 | 80 | ||
335 | 81 | 81 | ||
336 | === modified file 'python/libertine/Libertine.py' | |||
337 | --- python/libertine/Libertine.py 2016-07-11 18:41:59 +0000 | |||
338 | +++ python/libertine/Libertine.py 2016-07-13 19:49:12 +0000 | |||
339 | @@ -162,32 +162,52 @@ | |||
340 | 162 | os.environ['DEBIAN_FRONTEND'] = 'readline' | 162 | os.environ['DEBIAN_FRONTEND'] = 'readline' |
341 | 163 | return self.run_in_container(apt_command_prefix(verbosity) + " install '" + package_name + "'") == 0 | 163 | return self.run_in_container(apt_command_prefix(verbosity) + " install '" + package_name + "'") == 0 |
342 | 164 | 164 | ||
369 | 165 | def configure_command(self, command, *args, verbosity=1): | 165 | def configure_multiarch(self, should_enable, verbosity=1): |
370 | 166 | """ | 166 | """ |
371 | 167 | Configures the container based on what the command is. | 167 | Enables or disables multiarch repositories. |
372 | 168 | 168 | ||
373 | 169 | :param command: The configuration command to run. | 169 | :param should_enable: Whether or not to enable multiarch support. |
374 | 170 | :param *args: List of arguments used for the given configuration command | 170 | :param verbosity: the chattiness of the output on a range from 0 to 2 |
375 | 171 | """ | 171 | """ |
376 | 172 | if command == 'multiarch': | 172 | if should_enable: |
377 | 173 | if args[0] == 'enable': | 173 | ret = self.run_in_container("dpkg --add-architecture i386") |
378 | 174 | ret = self.run_in_container("dpkg --add-architecture i386") | 174 | if ret or ret == 0: |
379 | 175 | if ret or ret == 0: | 175 | self.run_in_container(apt_command_prefix(verbosity) + '--force-yes update') |
380 | 176 | self.run_in_container(apt_command_prefix(verbosity) + '--force-yes update') | 176 | return ret |
381 | 177 | return ret | 177 | else: |
382 | 178 | else: | 178 | self.run_in_container(apt_command_prefix(verbosity) + "purge \".*:i386\"") |
383 | 179 | self.run_in_container(apt_command_prefix(verbosity) + "purge \".*:i386\"") | 179 | return self.run_in_container("dpkg --remove-architecture i386") |
384 | 180 | return self.run_in_container("dpkg --remove-architecture i386") | 180 | |
385 | 181 | 181 | def configure_add_archive(self, archive, public_key_file, verbosity=1): | |
386 | 182 | elif command == 'add-archive': | 182 | """ |
387 | 183 | if not os.path.exists(os.path.join(self.root_path, 'usr', 'bin', 'add-apt-repository')): | 183 | Adds the given archive. If this archive requires a key, prompt user. |
388 | 184 | self.update_packages(verbosity) | 184 | |
389 | 185 | self.install_package("software-properties-common", verbosity) | 185 | :param archive: The configuration command to run. |
390 | 186 | 186 | :param public_key_file: file containing the public key used to sign this archive | |
391 | 187 | return self.run_in_container("add-apt-repository -y " + args[0]) | 187 | :param verbosity: the chattiness of the output on a range from 0 to 2 |
392 | 188 | 188 | """ | |
393 | 189 | elif command == 'delete-archive': | 189 | if not os.path.exists(os.path.join(self.root_path, 'usr', 'bin', 'add-apt-repository')): |
394 | 190 | return self.run_in_container("add-apt-repository -y -r " + args[0]) | 190 | self.update_packages(verbosity) |
395 | 191 | self.install_package("software-properties-common", verbosity) | ||
396 | 192 | if 'https://' in archive and not os.path.exists(os.path.join(self.root_path, 'usr', 'lib', 'apt', 'methods', 'https')): | ||
397 | 193 | self.update_packages(verbosity) | ||
398 | 194 | self.install_package("apt-transport-https", verbosity) | ||
399 | 195 | |||
400 | 196 | retcode = self.run_in_container("add-apt-repository -y " + archive) | ||
401 | 197 | if retcode is 0 and public_key_file is not None: | ||
402 | 198 | with open(public_key_file, 'r') as keyfile: | ||
403 | 199 | return self.run_in_container("bash -c 'echo \"%s\" | apt-key add -'" % keyfile.read()) | ||
404 | 200 | |||
405 | 201 | return retcode | ||
406 | 202 | |||
407 | 203 | def configure_remove_archive(self, archive, verbosity=1): | ||
408 | 204 | """ | ||
409 | 205 | Removes the given archive. | ||
410 | 206 | |||
411 | 207 | :param archive: The configuration command to run. | ||
412 | 208 | :param verbosity: the chattiness of the output on a range from 0 to 2 | ||
413 | 209 | """ | ||
414 | 210 | return self.run_in_container("add-apt-repository -y -r " + archive) | ||
415 | 191 | 211 | ||
416 | 192 | @property | 212 | @property |
417 | 193 | def name(self): | 213 | def name(self): |
418 | @@ -248,7 +268,9 @@ | |||
419 | 248 | """ | 268 | """ |
420 | 249 | super().__init__() | 269 | super().__init__() |
421 | 250 | 270 | ||
423 | 251 | container_type = ContainersConfig().get_container_type(container_id) | 271 | self.containers_config = ContainersConfig() |
424 | 272 | |||
425 | 273 | container_type = self.containers_config.get_container_type(container_id) | ||
426 | 252 | 274 | ||
427 | 253 | if container_type == None or container_type == "lxc": | 275 | if container_type == None or container_type == "lxc": |
428 | 254 | from libertine.LxcContainer import LibertineLXC | 276 | from libertine.LxcContainer import LibertineLXC |
429 | @@ -288,7 +310,7 @@ | |||
430 | 288 | Creates the container. | 310 | Creates the container. |
431 | 289 | """ | 311 | """ |
432 | 290 | self.container.architecture = HostInfo().get_host_architecture() | 312 | self.container.architecture = HostInfo().get_host_architecture() |
434 | 291 | self.container.installed_release = ContainersConfig().get_container_distro(self.container_id) | 313 | self.container.installed_release = self.containers_config.get_container_distro(self.container_id) |
435 | 292 | 314 | ||
436 | 293 | return self.container.create_libertine_container(password, multiarch, verbosity) | 315 | return self.container.create_libertine_container(password, multiarch, verbosity) |
437 | 294 | 316 | ||
438 | @@ -350,7 +372,7 @@ | |||
439 | 350 | :param app_exec_line: the application exec line as passed in by | 372 | :param app_exec_line: the application exec line as passed in by |
440 | 351 | ubuntu-app-launch | 373 | ubuntu-app-launch |
441 | 352 | """ | 374 | """ |
443 | 353 | if ContainersConfig().container_exists(self.container.container_id): | 375 | if self.containers_config.container_exists(self.container.container_id): |
444 | 354 | # Update $PATH as necessary | 376 | # Update $PATH as necessary |
445 | 355 | if '/usr/games' not in os.environ['PATH']: | 377 | if '/usr/games' not in os.environ['PATH']: |
446 | 356 | os.environ['PATH'] = os.environ['PATH'] + ":/usr/games" | 378 | os.environ['PATH'] = os.environ['PATH'] + ":/usr/games" |
447 | @@ -391,10 +413,24 @@ | |||
448 | 391 | except RuntimeError as e: | 413 | except RuntimeError as e: |
449 | 392 | return handle_runtime_error(e) | 414 | return handle_runtime_error(e) |
450 | 393 | 415 | ||
455 | 394 | def configure_command(self, command, *args): | 416 | def configure_multiarch(self, should_enable, verbosity=1): |
456 | 395 | try: | 417 | try: |
457 | 396 | with ContainerRunning(self.container): | 418 | with ContainerRunning(self.container): |
458 | 397 | return self.container.configure_command(command, *args) | 419 | return self.container.configure_multiarch(should_enable, verbosity) |
459 | 420 | except RuntimeError as e: | ||
460 | 421 | return handle_runtime_error(e) | ||
461 | 422 | |||
462 | 423 | def configure_add_archive(self, archive, key, verbosity): | ||
463 | 424 | try: | ||
464 | 425 | with ContainerRunning(self.container): | ||
465 | 426 | return self.container.configure_add_archive(archive, key, verbosity) | ||
466 | 427 | except RuntimeError as e: | ||
467 | 428 | return handle_runtime_error(e) | ||
468 | 429 | |||
469 | 430 | def configure_remove_archive(self, archive, verbosity): | ||
470 | 431 | try: | ||
471 | 432 | with ContainerRunning(self.container): | ||
472 | 433 | return self.container.configure_remove_archive(archive, verbosity) | ||
473 | 398 | except RuntimeError as e: | 434 | except RuntimeError as e: |
474 | 399 | return handle_runtime_error(e) | 435 | return handle_runtime_error(e) |
475 | 400 | 436 | ||
476 | 401 | 437 | ||
477 | === modified file 'tools/libertine-container-manager' | |||
478 | --- tools/libertine-container-manager 2016-07-11 18:41:59 +0000 | |||
479 | +++ tools/libertine-container-manager 2016-07-13 19:49:12 +0000 | |||
480 | @@ -206,11 +206,11 @@ | |||
481 | 206 | if not container.exec_command(args.command): | 206 | if not container.exec_command(args.command): |
482 | 207 | sys.exit(1) | 207 | sys.exit(1) |
483 | 208 | 208 | ||
485 | 209 | def delete_archive_by_name(self, container_id, archive_name): | 209 | def delete_archive_by_name(self, container_id, archive_name, verbosity=1): |
486 | 210 | self.containers_config.update_archive_install_status(container_id, archive_name, 'removing') | 210 | self.containers_config.update_archive_install_status(container_id, archive_name, 'removing') |
487 | 211 | if self.containers_config.get_archive_install_status(container_id, archive_name) == 'installed': | 211 | if self.containers_config.get_archive_install_status(container_id, archive_name) == 'installed': |
488 | 212 | self.containers_config.update_archive_install_status(container_id, archive_name, 'removing') | 212 | self.containers_config.update_archive_install_status(container_id, archive_name, 'removing') |
490 | 213 | if LibertineContainer(container_id).configure_command('delete-archive', "\"" + archive_name + "\"") is not 0: | 213 | if LibertineContainer(container_id).configure_remove_archive("\"" + archive_name + "\"", verbosity) is not 0: |
491 | 214 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installed') | 214 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installed') |
492 | 215 | return False | 215 | return False |
493 | 216 | 216 | ||
494 | @@ -232,36 +232,41 @@ | |||
495 | 232 | print("i386 multiarch support is already %s" % multiarch) | 232 | print("i386 multiarch support is already %s" % multiarch) |
496 | 233 | sys.exit(1) | 233 | sys.exit(1) |
497 | 234 | 234 | ||
499 | 235 | if container.configure_command('multiarch', args.multiarch) is not 0: | 235 | if container.configure_multiarch(args.multiarch, args.verbosity) is not 0: |
500 | 236 | sys.exit(1) | 236 | sys.exit(1) |
501 | 237 | 237 | ||
502 | 238 | self.containers_config.update_container_multiarch_support(container_id, multiarch) | 238 | self.containers_config.update_container_multiarch_support(container_id, multiarch) |
503 | 239 | 239 | ||
506 | 240 | elif args.add_archive: | 240 | elif args.archive is not None: |
507 | 241 | archive_name = args.add_archive.strip("\'\"") | 241 | archive_name = args.archive_name.strip("\'\"") |
508 | 242 | archive_name_esc = "\"" + archive_name + "\"" | 242 | archive_name_esc = "\"" + archive_name + "\"" |
509 | 243 | 243 | ||
531 | 244 | if self.containers_config.archive_exists(container_id, archive_name): | 244 | if args.archive == 'add': |
532 | 245 | print("%s already added in container." % archive_name) | 245 | if self.containers_config.archive_exists(container_id, archive_name): |
533 | 246 | sys.exit(1) | 246 | print("%s already added in container." % archive_name) |
534 | 247 | 247 | sys.exit(1) | |
535 | 248 | self.containers_config.add_container_archive(container_id, archive_name) | 248 | |
536 | 249 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installing') | 249 | self.containers_config.add_container_archive(container_id, archive_name) |
537 | 250 | if container.configure_command('add-archive', archive_name_esc) is not 0: | 250 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installing') |
538 | 251 | self.containers_config.delete_container_archive(container_id, archive_name) | 251 | if container.configure_add_archive(archive_name_esc, args.public_key_file, args.verbosity) is not 0: |
539 | 252 | sys.exit(1) | 252 | self.containers_config.delete_container_archive(container_id, archive_name) |
540 | 253 | 253 | sys.exit(1) | |
541 | 254 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installed') | 254 | |
542 | 255 | 255 | self.containers_config.update_archive_install_status(container_id, archive_name, 'installed') | |
543 | 256 | elif args.delete_archive: | 256 | |
544 | 257 | archive_name = args.delete_archive.strip("\'\"") | 257 | elif args.archive == 'remove': |
545 | 258 | if not self.containers_config.archive_exists(container_id, archive_name): | 258 | if not self.containers_config.archive_exists(container_id, archive_name): |
546 | 259 | print("%s is not added in container." % archive_name) | 259 | print("%s is not added in container." % archive_name) |
547 | 260 | sys.exit(1) | 260 | sys.exit(1) |
548 | 261 | 261 | ||
549 | 262 | if not self.delete_archive_by_name(container_id, archive_name): | 262 | if not self.delete_archive_by_name(container_id, archive_name): |
550 | 263 | print("%s was not properly deleted." % archive_name) | 263 | print("%s was not properly deleted." % archive_name) |
551 | 264 | sys.exit(1) | 264 | sys.exit(1) |
552 | 265 | |||
553 | 266 | else: | ||
554 | 267 | print("Configure called with no subcommand. See configure --help for usage.") | ||
555 | 268 | sys.exit(1) | ||
556 | 269 | |||
557 | 265 | 270 | ||
558 | 266 | def merge(self, args): | 271 | def merge(self, args): |
559 | 267 | self.containers_config.merge_container_config_files(args.file) | 272 | self.containers_config.merge_container_config_files(args.file) |
560 | @@ -444,21 +449,31 @@ | |||
561 | 444 | parser_configure.add_argument( | 449 | parser_configure.add_argument( |
562 | 445 | '-i', '--id', | 450 | '-i', '--id', |
563 | 446 | help=("Container identifier. Default container is used if omitted.")) | 451 | help=("Container identifier. Default container is used if omitted.")) |
579 | 447 | parser_configure.add_argument( | 452 | multiarch_group = parser_configure.add_argument_group("Multiarch support", |
580 | 448 | '-m', '--multiarch', | 453 | "Enable or disable multiarch support for a container.") |
581 | 449 | choices=['enable', 'disable'], | 454 | multiarch_group.add_argument( |
582 | 450 | help=("Enables or disables i386 multiarch support for amd64 Libertine " | 455 | '-m', '--multiarch', |
583 | 451 | "containers. This option has no effect when the Libertine " | 456 | choices=['enable', 'disable'], |
584 | 452 | "container is i386.")) | 457 | help=("Enables or disables i386 multiarch support for amd64 Libertine " |
585 | 453 | parser_configure.add_argument( | 458 | "containers. This option has no effect when the Libertine " |
586 | 454 | '-a', '--add-archive', | 459 | "container is i386.")) |
587 | 455 | metavar='Archive name', | 460 | |
588 | 456 | help=("Adds an archive in the specified Libertine container. Examples: " | 461 | archive_group = parser_configure.add_argument_group("Additional archive support", |
589 | 457 | "'deb http://myserver/path/to/repo stable myrepo', ppa:user/repository, multiverse")) | 462 | "Add or delete an additional archive (PPA).") |
590 | 458 | parser_configure.add_argument( | 463 | archive_group.add_argument( |
591 | 459 | '-d', '--delete-archive', | 464 | '-a', '--archive', |
592 | 460 | metavar='Archive name', | 465 | choices=['add', 'remove'], |
593 | 461 | help=("Deletes an existing archive in the specified Libertine container.")) | 466 | help=("Adds or removes an archive (PPA) in the specified Libertine container.")) |
594 | 467 | archive_group.add_argument( | ||
595 | 468 | '-n', '--archive-name', | ||
596 | 469 | metavar='Archive name', | ||
597 | 470 | help=("Archive name to be added or removed.")) | ||
598 | 471 | archive_group.add_argument( | ||
599 | 472 | '-k', '--public-key-file', | ||
600 | 473 | metavar='Public key file', | ||
601 | 474 | help=("File containing the key used to sign the given archive. " | ||
602 | 475 | "Useful for third-party or private archives.")) | ||
603 | 476 | |||
604 | 462 | parser_configure.set_defaults(func=container_manager.configure) | 477 | parser_configure.set_defaults(func=container_manager.configure) |
605 | 463 | 478 | ||
606 | 464 | # Handle merging another ContainersConfig.json file into the main ContainersConfig.json file | 479 | # Handle merging another ContainersConfig.json file into the main ContainersConfig.json file |
607 | 465 | 480 | ||
608 | === modified file 'tools/libertine-container-manager.1' | |||
609 | --- tools/libertine-container-manager.1 2016-07-07 18:54:59 +0000 | |||
610 | +++ tools/libertine-container-manager.1 2016-07-13 19:49:12 +0000 | |||
611 | @@ -265,14 +265,19 @@ | |||
612 | 265 | Enable i386 support. | 265 | Enable i386 support. |
613 | 266 | .RE | 266 | .RE |
614 | 267 | .IP | 267 | .IP |
623 | 268 | .BR \-a " ARCHIVE_NAME, " \-\-add-archive " ARCHIVE_NAME" "" | 268 | .BR \-a " {add,remove}, " \-\-archive "{add,remove}" "" |
624 | 269 | .RS 14 | 269 | .RS 14 |
625 | 270 | Adds an archive to the specified container. Examples: 'deb http://myserver/path/to/repo stable myrepo', ppa:user/repository, multiverse | 270 | Adds or removes an archive in the specified container. |
626 | 271 | .RE | 271 | .RE |
627 | 272 | .IP | 272 | .IP |
628 | 273 | .BR \-d " ARCHIVE_NAME, " \-\-delete-archive " ARCHIVE_NAME" "" | 273 | .BR \-n " ARCHIVE_NAME, " \-\-archive-name " ARCHIVE_NAME" "" |
629 | 274 | .RS 14 | 274 | .RS 14 |
630 | 275 | Deletes an archive to the specified container. Examples: 'deb http://myserver/path/to/repo stable myrepo', ppa:user/repository, multiverse | 275 | Archive to be added or removed. Examples: 'deb http://myserver/path/to/repo stable myrepo', ppa:user/repository, multiverse |
631 | 276 | .RE | ||
632 | 277 | .IP | ||
633 | 278 | .BR \-k " PUBLIC_KEY_FILE, " \-\-public-key-file " PUBLIC_KEY_FILE" "" | ||
634 | 279 | .RS 14 | ||
635 | 280 | File containing public key used to sign new archive. | ||
636 | 276 | .RE | 281 | .RE |
637 | 277 | .TP | 282 | .TP |
638 | 278 | 283 |
PASSED: Continuous integration, rev:279 /jenkins. canonical. com/libertine/ job/lp- libertine- ci/52/ /jenkins. canonical. com/libertine/ job/build/ 174 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=amd64, release= vivid+overlay, testname= default/ 135 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=amd64, release= xenial+ overlay, testname= default/ 135 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=amd64, release= yakkety, testname= default/ 135 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=i386, release= vivid+overlay, testname= default/ 135 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=i386, release= xenial+ overlay, testname= default/ 135 /jenkins. canonical. com/libertine/ job/test- 0-autopkgtest/ label=i386, release= yakkety, testname= default/ 135 /jenkins. canonical. com/libertine/ job/lp- generic- update- mp/137/ console /jenkins. canonical. com/libertine/ job/build- 0-fetch/ 177 /jenkins. canonical. com/libertine/ job/build- 1-sourcepkg/ release= vivid+overlay/ 162 /jenkins. canonical. com/libertine/ job/build- 1-sourcepkg/ release= xenial+ overlay/ 162 /jenkins. canonical. com/libertine/ job/build- 1-sourcepkg/ release= yakkety/ 162 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= vivid+overlay/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= vivid+overlay/ 155/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= xenial+ overlay/ 155/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= yakkety/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=amd64, release= yakkety/ 155/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= vivid+overlay/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= vivid+overlay/ 155/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= xenial+ overlay/ 155/artifact/ output/ *zip*/output. zip /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= yakkety/ 155 /jenkins. canonical. com/libertine/ job/build- 2-binpkg/ arch=i386, release= yakkety/ 155/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
None: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /jenkins. canonical. com/libertine/ job/lp- libertine- ci/52/rebuild
https:/