Merge ~nteodosio/software-properties:xenial-ua into software-properties:ubuntu/master
- Git
- lp:~nteodosio/software-properties
- xenial-ua
- Merge into ubuntu/master
Status: | Superseded |
---|---|
Proposed branch: | ~nteodosio/software-properties:xenial-ua |
Merge into: | software-properties:ubuntu/master |
Diff against target: |
1639 lines (+976/-2) (has conflicts) 17 files modified
add-apt-repository (+34/-0) data/gtkbuilder/dialog-ua-attach.ui (+33/-0) data/gtkbuilder/main.ui (+155/-0) data/ubuntu-pro-logo.svg (+28/-1) debian/changelog (+83/-0) debian/control (+19/-0) debian/software-properties-gtk.install (+5/-0) po/POTFILES.in (+4/-0) softwareproperties/SoftwareProperties.py (+36/-1) softwareproperties/cloudarchive.py (+21/-0) softwareproperties/gtk/DialogUaAttach.py (+33/-0) softwareproperties/gtk/SoftwarePropertiesGtk.py (+92/-0) softwareproperties/gtk/UbuntuProPage.py (+10/-0) softwareproperties/gtk/utils.py (+27/-0) softwareproperties/ppa.py (+345/-0) softwareproperties/shortcuts.py (+5/-0) tests/test_shortcuts.py (+46/-0) Conflict in add-apt-repository Conflict in data/gtkbuilder/dialog-ua-attach.ui Conflict in data/gtkbuilder/main.ui Conflict in data/ubuntu-pro-logo.svg Conflict in debian/changelog Conflict in debian/control Conflict in debian/software-properties-gtk.install Conflict in po/POTFILES.in Conflict in softwareproperties/SoftwareProperties.py Conflict in softwareproperties/cloudarchive.py Conflict in softwareproperties/gtk/DialogUaAttach.py Conflict in softwareproperties/gtk/SoftwarePropertiesGtk.py Conflict in softwareproperties/gtk/UbuntuProPage.py Conflict in softwareproperties/gtk/utils.py Conflict in softwareproperties/ppa.py Conflict in softwareproperties/shortcuts.py Conflict in tests/test_shortcuts.py |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sebastien Bacher | Pending | ||
Review via email:
|
Commit message
Description of the change
0.96.20.11[1] was blocked in proposed because of syntax error[2] in a exception with Xenial's old Python.
We committed the fix already but need to release it yet, for we should coordinate LP:1990450 (update-manager) with LP:2029473 (software-
[1] https:/
[2] https:/
Unmerged commits
- 7d9f5be... by Nathan Teodosio
-
Release software-properties 0.96.20.12.
- 4cbf8e7... by Nathan Teodosio
-
Fix invalid syntax and unused import.
- f2e294b... by Sebastien Bacher
-
releasing package software-properties version 0.96.20.11
- 09a94a9... by Sebastien Bacher
-
Update translatable sources
- a57fef4... by Nathan Teodosio
-
Add comment explaining why we need to decode to UTF8.
- d9c3635... by Nathan Teodosio
-
Do not block on daemon thread.
Would happen upon exiting after launching Enable Ubuntu Pro.
- bdd470d... by Nathan Teodosio
-
Only decode to UTF8 if coming from ua call.
- b3b28a9... by Nathan Teodosio
-
Add SVG to .install
- b4c2e04... by Nathan Teodosio
-
status_
json.decode( "utf-8" ) To avoid JSON object must be str, not bytes
- 71b072d... by Nathan Teodosio
-
Depend on python3-distro-info and ubuntu-
advantage- {tools, desktop- daemon} .
Preview Diff
1 | diff --git a/add-apt-repository b/add-apt-repository |
2 | index 985cae9..bf6dc41 100755 |
3 | --- a/add-apt-repository |
4 | +++ b/add-apt-repository |
5 | @@ -203,6 +203,7 @@ class AddAptRepository(object): |
6 | if (s.uri, suite) in binary_entries: |
7 | binary_entries[(s.uri, suite)].append(s) |
8 | else: |
9 | +<<<<<<< add-apt-repository |
10 | binary_entries[(s.uri, suite)] = [s] |
11 | |
12 | for (uri, suite), entries in binary_entries.items(): |
13 | @@ -228,6 +229,39 @@ class AddAptRepository(object): |
14 | if get_source_entry_pocket(e) == 'release': |
15 | comps += e.comps |
16 | comps = list(set(comps)) |
17 | +======= |
18 | + print(_("'%s' distribution component is already enabled for all sources.") % line) |
19 | + sys.exit(0) |
20 | + sp.sourceslist.save() |
21 | + sys.exit(0) |
22 | + |
23 | + # this wasn't a component name ('multiverse', 'backports'), so its either |
24 | + # a actual line to be added or a shortcut. |
25 | + try: |
26 | + shortcut = shortcut_handler(line) |
27 | + except ShortcutException as e: |
28 | + print(e) |
29 | + sys.exit(1) |
30 | + |
31 | + # display more information about the shortcut / ppa info |
32 | + if not options.assume_yes and shortcut.should_confirm(): |
33 | + try: |
34 | + info = shortcut.info() |
35 | + except ShortcutException as e: |
36 | + print(e) |
37 | + sys.exit(1) |
38 | + |
39 | + # strip ANSI escape sequences |
40 | + description = re.sub(r"(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]", |
41 | + "", info["description"] or "") |
42 | + |
43 | + print(" %s" % description) |
44 | + print(_(" More info: %s") % str(info["web_link"])) |
45 | + if (sys.stdin.isatty() and |
46 | + not "FORCE_ADD_APT_REPOSITORY" in os.environ): |
47 | + if options.remove: |
48 | + print(_("Press [ENTER] to continue or ctrl-c to cancel removing it")) |
49 | +>>>>>>> add-apt-repository |
50 | else: |
51 | comps = ['main', 'restricted'] |
52 | |
53 | diff --git a/data/gtkbuilder/dialog-ua-attach.ui b/data/gtkbuilder/dialog-ua-attach.ui |
54 | index 1445b82..0f0f195 100644 |
55 | --- a/data/gtkbuilder/dialog-ua-attach.ui |
56 | +++ b/data/gtkbuilder/dialog-ua-attach.ui |
57 | @@ -39,6 +39,10 @@ |
58 | <property name="margin-top">30</property> |
59 | <property name="xalign">0</property> |
60 | <property name="group">magic_radio</property> |
61 | +<<<<<<< data/gtkbuilder/dialog-ua-attach.ui |
62 | +======= |
63 | + <signal name="toggled" handler="on_radio_toggled" swapped="no"/> |
64 | +>>>>>>> data/gtkbuilder/dialog-ua-attach.ui |
65 | <signal name="clicked" handler="on_magic_radio_clicked" swapped="no"/> |
66 | </object> |
67 | </child> |
68 | @@ -48,6 +52,7 @@ |
69 | <property name="can-focus">False</property> |
70 | <property name="orientation">horizontal</property> |
71 | <child> |
72 | +<<<<<<< data/gtkbuilder/dialog-ua-attach.ui |
73 | <object class="GtkLabel" id="pin_label"> |
74 | <property name="label"> </property> |
75 | <property name="visible">True</property> |
76 | @@ -61,6 +66,30 @@ |
77 | <attributes> |
78 | <attribute name="scale" value="2"/> |
79 | </attributes> |
80 | +======= |
81 | + <object class="GtkBox" id="pin_label_box"> |
82 | + <property name="visible">True</property> |
83 | + <property name="margin-left">20</property> |
84 | + <property name="margin-top">12</property> |
85 | + <property name="margin-bottom">8</property> |
86 | + <property name="can-focus">False</property> |
87 | + <child> |
88 | + <object class="GtkLabel" id="pin_label"> |
89 | + <property name="label"> </property> |
90 | + <property name="visible">True</property> |
91 | + <property name="selectable">True</property> |
92 | + <property name="can-focus">False</property> |
93 | + <property name="halign">start</property> |
94 | + <property name="margin-left">6</property> |
95 | + <property name="margin-right">6</property> |
96 | + <property name="margin-top">4</property> |
97 | + <property name="margin-bottom">4</property> |
98 | + <attributes> |
99 | + <attribute name="scale" value="2"/> |
100 | + </attributes> |
101 | + </object> |
102 | + </child> |
103 | +>>>>>>> data/gtkbuilder/dialog-ua-attach.ui |
104 | </object> |
105 | </child> |
106 | <child> |
107 | @@ -68,6 +97,10 @@ |
108 | <property name="visible">True</property> |
109 | <property name="valign">center</property> |
110 | <property name="margin">3</property> |
111 | +<<<<<<< data/gtkbuilder/dialog-ua-attach.ui |
112 | +======= |
113 | + <property name="margin-left">9</property> |
114 | +>>>>>>> data/gtkbuilder/dialog-ua-attach.ui |
115 | <child> |
116 | <object class="GtkSpinner" id="pin_spinner"> |
117 | <property name="visible">True</property> |
118 | diff --git a/data/gtkbuilder/main.ui b/data/gtkbuilder/main.ui |
119 | index 9c3551b..ac6b91c 100644 |
120 | --- a/data/gtkbuilder/main.ui |
121 | +++ b/data/gtkbuilder/main.ui |
122 | @@ -539,6 +539,33 @@ |
123 | <property name="position">0</property> |
124 | </packing> |
125 | </child> |
126 | +<<<<<<< data/gtkbuilder/main.ui |
127 | +======= |
128 | + </object> |
129 | + <packing> |
130 | + <property name="expand">False</property> |
131 | + <property name="fill">True</property> |
132 | + </packing> |
133 | + </child> |
134 | + <child> |
135 | + <object class="GtkLabel"> |
136 | + <property name="visible">True</property> |
137 | + <property name="can_focus">False</property> |
138 | + <property name="label" translatable="yes">Snap package updates are checked routinely and installed automatically.</property> |
139 | + <property name="xalign">0</property> |
140 | + </object> |
141 | + <packing> |
142 | + <property name="expand">False</property> |
143 | + <property name="fill">False</property> |
144 | + </packing> |
145 | + </child> |
146 | + <child> |
147 | + <object class="GtkAlignment" id="alignment2"> |
148 | + <property name="visible">True</property> |
149 | + <property name="can_focus">False</property> |
150 | + <property name="top_padding">6</property> |
151 | + <property name="left_padding">12</property> |
152 | +>>>>>>> data/gtkbuilder/main.ui |
153 | <child> |
154 | <object class="GtkAlignment"> |
155 | <property name="visible">True</property> |
156 | @@ -546,7 +573,103 @@ |
157 | <property name="top_padding">6</property> |
158 | <property name="left_padding">12</property> |
159 | <child> |
160 | +<<<<<<< data/gtkbuilder/main.ui |
161 | <object class="GtkVBox"> |
162 | +======= |
163 | + <object class="GtkHBox"> |
164 | + <property name="visible">True</property> |
165 | + <property name="can_focus">False</property> |
166 | + <property name="spacing">6</property> |
167 | + <child> |
168 | + <object class="GtkLabel" id="label_esm_heading"> |
169 | + <property name="visible">True</property> |
170 | + <property name="can_focus">False</property> |
171 | + <property name="xalign">1</property> |
172 | + <property name="label" translatable="yes">For other packages, this system has:</property> |
173 | + </object> |
174 | + <packing> |
175 | + <property name="expand">False</property> |
176 | + <property name="fill">False</property> |
177 | + <property name="position">0</property> |
178 | + </packing> |
179 | + </child> |
180 | + <child> |
181 | + <object class="GtkHBox"> |
182 | + <property name="visible">True</property> |
183 | + <property name="can_focus">False</property> |
184 | + <property name="spacing">6</property> |
185 | + <child> |
186 | + <object class="GtkLabel" id="label_esm_status"> |
187 | + <property name="visible">True</property> |
188 | + <property name="can_focus">False</property> |
189 | + <property name="xalign">0</property> |
190 | + </object> |
191 | + <packing> |
192 | + <property name="expand">False</property> |
193 | + <property name="fill">True</property> |
194 | + </packing> |
195 | + </child> |
196 | + <child> |
197 | + <object class="GtkLabel" id="label_esm_subscribe"> |
198 | + <property name="visible">True</property> |
199 | + <property name="can_focus">False</property> |
200 | + <property name="xalign">1</property> |
201 | + </object> |
202 | + <packing> |
203 | + <property name="expand">True</property> |
204 | + <property name="fill">True</property> |
205 | + </packing> |
206 | + </child> |
207 | + </object> |
208 | + <packing> |
209 | + <property name="expand">True</property> |
210 | + <property name="fill">True</property> |
211 | + <property name="position">1</property> |
212 | + </packing> |
213 | + </child> |
214 | + </object> |
215 | + <packing> |
216 | + <property name="expand">False</property> |
217 | + <property name="fill">False</property> |
218 | + </packing> |
219 | + </child> |
220 | + <child> |
221 | + <object class="GtkHBox"> |
222 | + <property name="visible">True</property> |
223 | + <property name="can_focus">False</property> |
224 | + <property name="spacing">6</property> |
225 | + <child> |
226 | + <object class="GtkLabel" id="label_eol_heading"> |
227 | + <property name="visible">True</property> |
228 | + <property name="can_focus">False</property> |
229 | + </object> |
230 | + <packing> |
231 | + <property name="expand">False</property> |
232 | + <property name="fill">False</property> |
233 | + <property name="position">0</property> |
234 | + </packing> |
235 | + </child> |
236 | + <child> |
237 | + <object class="GtkLabel" id="label_eol"> |
238 | + <property name="visible">True</property> |
239 | + <property name="can_focus">False</property> |
240 | + <property name="xalign">0</property> |
241 | + </object> |
242 | + <packing> |
243 | + <property name="expand">True</property> |
244 | + <property name="fill">True</property> |
245 | + <property name="position">1</property> |
246 | + </packing> |
247 | + </child> |
248 | + </object> |
249 | + <packing> |
250 | + <property name="expand">False</property> |
251 | + <property name="fill">False</property> |
252 | + </packing> |
253 | + </child> |
254 | + <child> |
255 | + <object class="GtkHBox" id="hbox_check_for_updates"> |
256 | +>>>>>>> data/gtkbuilder/main.ui |
257 | <property name="visible">True</property> |
258 | <property name="can_focus">False</property> |
259 | <property name="spacing">6</property> |
260 | @@ -1236,7 +1359,11 @@ |
261 | </child> |
262 | <child> |
263 | <object class="GtkStack" id="stack_ua_main"> |
264 | +<<<<<<< data/gtkbuilder/main.ui |
265 | <property name="visible">False</property> |
266 | +======= |
267 | + <property name="visible">True</property> |
268 | +>>>>>>> data/gtkbuilder/main.ui |
269 | <child> |
270 | <object class="GtkBox" id="box_ua_options"> |
271 | <property name="visible">True</property> |
272 | @@ -1376,6 +1503,10 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
273 | <child> |
274 | <object class="GtkLabel" id="label_ua_esm_infra_error"> |
275 | <property name="visible">False</property> |
276 | +<<<<<<< data/gtkbuilder/main.ui |
277 | +======= |
278 | + <property name="label" translatable="yes">Could not enable ESM Infra. Please try again.</property> |
279 | +>>>>>>> data/gtkbuilder/main.ui |
280 | <property name="valign">center</property> |
281 | <property name="xalign">0</property> |
282 | <attributes> |
283 | @@ -1413,6 +1544,10 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
284 | <child> |
285 | <object class="GtkLabel" id="label_ua_esm_apps_error"> |
286 | <property name="visible">False</property> |
287 | +<<<<<<< data/gtkbuilder/main.ui |
288 | +======= |
289 | + <property name="label" translatable="yes">Could not enable ESM Apps. Please try again.</property> |
290 | +>>>>>>> data/gtkbuilder/main.ui |
291 | <property name="xalign">0</property> |
292 | <attributes> |
293 | <attribute name="foreground" value="red"/> |
294 | @@ -1450,6 +1585,10 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
295 | <child> |
296 | <object class="GtkLabel" id="label_ua_livepatch_error"> |
297 | <property name="visible">False</property> |
298 | +<<<<<<< data/gtkbuilder/main.ui |
299 | +======= |
300 | + <property name="label" translatable="yes">Could not enable Livepatch. Please try again.</property> |
301 | +>>>>>>> data/gtkbuilder/main.ui |
302 | <property name="xalign">0</property> |
303 | <attributes> |
304 | <attribute name="foreground" value="red"/> |
305 | @@ -1534,7 +1673,11 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
306 | <child> |
307 | <object class="GtkLabel" id="label_ua_fips_status"> |
308 | <property name="visible">True</property> |
309 | +<<<<<<< data/gtkbuilder/main.ui |
310 | <property name="label"><b>FIPS 140-2</b></property> |
311 | +======= |
312 | + <property name="label" translatable="yes"><b>FIPS 140-2</b></property> |
313 | +>>>>>>> data/gtkbuilder/main.ui |
314 | <property name="use_markup">True</property> |
315 | <property name="xalign">0</property> |
316 | </object> |
317 | @@ -1713,6 +1856,7 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
318 | <child type="titlebar"> |
319 | <placeholder/> |
320 | </child> |
321 | +<<<<<<< data/gtkbuilder/main.ui |
322 | </object> |
323 | <object class="GtkSizeGroup"> |
324 | <widgets> |
325 | @@ -1724,14 +1868,25 @@ Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machi |
326 | <widget name="label_updates_6"/> |
327 | <widget name="label_updates_7"/> |
328 | </widgets> |
329 | +======= |
330 | +>>>>>>> data/gtkbuilder/main.ui |
331 | </object> |
332 | <object class="GtkSizeGroup"> |
333 | <widgets> |
334 | +<<<<<<< data/gtkbuilder/main.ui |
335 | <widget name="combobox_updates_subscription"/> |
336 | <widget name="combobox_update_interval"/> |
337 | <widget name="combobox_security_updates"/> |
338 | <widget name="combobox_other_updates"/> |
339 | <widget name="combobox_release_upgrades"/> |
340 | +======= |
341 | + <widget name="label_esm_heading"/> |
342 | + <widget name="label_eol_heading"/> |
343 | + <widget name="label3"/> |
344 | + <widget name="label4"/> |
345 | + <widget name="label5"/> |
346 | + <widget name="label29"/> |
347 | +>>>>>>> data/gtkbuilder/main.ui |
348 | </widgets> |
349 | </object> |
350 | </interface> |
351 | diff --git a/data/ubuntu-pro-logo.svg b/data/ubuntu-pro-logo.svg |
352 | index b94971a..2ad3260 100644 |
353 | --- a/data/ubuntu-pro-logo.svg |
354 | +++ b/data/ubuntu-pro-logo.svg |
355 | @@ -1 +1,28 @@ |
356 | -<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130.71 34"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#e95420;}.cls-3{fill:none;}</style></defs><g><path d="M31.74,29.47c-1.3,0-2.33-.25-3.1-.76-.77-.51-1.33-1.19-1.67-2.05-.34-.86-.51-1.81-.51-2.87V14.68h1.42v8.92c0,1.59,.36,2.75,1.07,3.49,.71,.74,1.64,1.11,2.8,1.11s2.09-.37,2.8-1.11c.71-.74,1.07-1.9,1.07-3.49V14.68h1.42v9.11c0,1.06-.17,2.02-.51,2.87s-.9,1.54-1.67,2.05-1.81,.76-3.1,.76Z"/><path d="M44.46,29.41c-.63,0-1.19-.03-1.68-.09-.49-.06-.93-.14-1.29-.23-.37-.09-.69-.18-.95-.26V13.2l1.36-.25v6.06c.24-.18,.62-.37,1.15-.57,.53-.2,1.14-.3,1.84-.3,1.04,0,1.93,.24,2.65,.72,.72,.48,1.28,1.15,1.66,2,.38,.85,.57,1.82,.57,2.92,0,1.17-.22,2.18-.67,3.02-.45,.84-1.06,1.49-1.86,1.94-.79,.45-1.72,.68-2.78,.68Zm-.02-1.23c.78,0,1.46-.17,2.04-.51,.58-.34,1.03-.84,1.36-1.5,.33-.66,.49-1.46,.49-2.39,0-.6-.06-1.16-.19-1.69-.13-.53-.33-1-.61-1.41-.28-.41-.64-.73-1.1-.96s-1.01-.34-1.68-.34-1.22,.11-1.73,.33c-.52,.22-.89,.43-1.13,.63v7.56c.21,.06,.52,.12,.94,.19,.42,.07,.95,.1,1.61,.1Z"/><path d="M56.74,29.37c-1.07,0-1.92-.21-2.55-.62-.63-.41-1.07-.99-1.34-1.73-.26-.75-.4-1.61-.4-2.6v-6.06h1.36v5.62c0,1.02,.1,1.83,.3,2.43,.2,.61,.53,1.04,.99,1.32,.46,.27,1.07,.41,1.84,.41,.64,0,1.2-.04,1.67-.1s.77-.13,.9-.19v-9.48h1.36v10.42c-.4,.11-.95,.24-1.63,.38-.68,.14-1.52,.21-2.51,.21Z"/><path d="M64.26,29.16v-10.42c.4-.11,.95-.24,1.64-.38,.69-.14,1.52-.21,2.5-.21,1.1,0,1.96,.21,2.58,.63,.62,.42,1.06,1,1.32,1.74,.26,.75,.39,1.61,.39,2.6v6.04h-1.36v-5.6c0-1.02-.09-1.83-.28-2.44-.19-.61-.51-1.05-.97-1.33-.46-.27-1.09-.41-1.88-.41-.64,0-1.19,.04-1.66,.1-.47,.07-.77,.13-.91,.19v9.48h-1.36Z"/><path d="M79.39,29.39c-.89,0-1.59-.16-2.11-.47s-.88-.78-1.09-1.41-.31-1.42-.31-2.38V15.19l1.36-.25v3.43h4.3v1.15h-4.3v5.74c0,.82,.09,1.44,.27,1.86,.18,.42,.44,.7,.78,.83,.34,.14,.73,.21,1.18,.21,.57,0,1.03-.07,1.38-.21,.35-.14,.62-.26,.81-.35l.33,1.13c-.2,.12-.54,.27-1.02,.43-.49,.16-1.02,.24-1.59,.24Z"/><path d="M88.09,29.37c-1.07,0-1.92-.21-2.55-.62-.63-.41-1.07-.99-1.34-1.73-.26-.75-.4-1.61-.4-2.6v-6.06h1.36v5.62c0,1.02,.1,1.83,.3,2.43,.2,.61,.53,1.04,.99,1.32,.46,.27,1.07,.41,1.84,.41,.64,0,1.2-.04,1.67-.1s.77-.13,.9-.19v-9.48h1.36v10.42c-.4,.11-.95,.24-1.63,.38-.68,.14-1.52,.21-2.51,.21Z"/><path d="M100.67,29.16V14.96c.5-.14,1.09-.24,1.77-.3,.67-.06,1.3-.09,1.89-.09,2.03,0,3.55,.39,4.56,1.18s1.51,1.89,1.51,3.31c0,1.1-.25,1.98-.76,2.64-.51,.66-1.24,1.14-2.18,1.43-.95,.29-2.08,.44-3.41,.44h-1.96v5.6h-1.42Zm1.42-6.83h1.8c1.02,0,1.9-.09,2.65-.26,.75-.17,1.34-.5,1.75-.98,.42-.48,.63-1.17,.63-2.06s-.22-1.51-.66-1.97c-.44-.47-1-.79-1.69-.98-.69-.19-1.42-.28-2.18-.28-.52,0-.96,.02-1.34,.05s-.7,.07-.96,.09v6.39Z"/><path d="M112.84,29.16v-10.3c.35-.15,.83-.31,1.44-.47,.61-.16,1.36-.24,2.24-.24,.29,0,.58,.02,.87,.05,.29,.04,.54,.08,.75,.12s.37,.09,.47,.14l-.27,1.17c-.1-.06-.32-.12-.67-.18-.35-.06-.8-.09-1.36-.09-.58,0-1.05,.04-1.41,.12-.35,.08-.59,.15-.7,.21v9.46h-1.36Z"/><path d="M124.62,29.41c-.96,0-1.81-.23-2.55-.7-.74-.47-1.32-1.12-1.74-1.97s-.64-1.84-.64-2.97,.21-2.13,.64-2.98c.42-.84,1.01-1.5,1.74-1.97s1.59-.71,2.55-.71,1.81,.24,2.56,.71c.74,.47,1.33,1.13,1.74,1.97,.42,.84,.63,1.83,.63,2.98s-.21,2.12-.63,2.97-1,1.51-1.74,1.97c-.75,.47-1.6,.7-2.56,.7Zm0-1.23c.71,0,1.33-.18,1.85-.54,.52-.36,.93-.87,1.21-1.54,.29-.66,.43-1.44,.43-2.33s-.14-1.69-.43-2.35-.69-1.17-1.21-1.54c-.52-.36-1.14-.54-1.85-.54s-1.33,.18-1.85,.54c-.52,.36-.93,.87-1.21,1.54-.29,.66-.43,1.45-.43,2.35s.14,1.67,.43,2.33c.29,.66,.69,1.17,1.21,1.54,.52,.36,1.14,.54,1.85,.54Z"/></g><g><rect class="cls-2" x="0" width="21" height="32"/><rect class="cls-3" x="2.5" y="14" width="16" height="16"/><circle class="cls-1" cx="4.8" cy="21.15" r="2.17"/><circle class="cls-1" cx="13.86" cy="16.39" r="2.17"/><path class="cls-1" d="M9.7,26.75c-1.57-.34-2.87-1.34-3.61-2.75-.58,.26-1.23,.34-1.86,.23,.89,2.19,2.78,3.77,5.1,4.27,.51,.11,1.03,.16,1.54,.16-.4-.52-.62-1.16-.64-1.82-.18-.02-.36-.05-.53-.09Z"/><circle class="cls-1" cx="13.37" cy="26.76" r="2.17"/><path class="cls-1" d="M16.39,25.96c.68-.85,1.15-1.86,1.38-2.93,.4-1.87,.03-3.83-1.03-5.42-.25,.59-.68,1.09-1.22,1.43,.59,1.11,.77,2.38,.5,3.61-.13,.6-.36,1.17-.68,1.68,.51,.42,.87,.98,1.04,1.62Z"/><path class="cls-1" d="M4.63,18.04c.06,0,.11,0,.17,0,.22,0,.44,.02,.66,.07,.35,.08,.69,.21,.99,.4,.98-1.41,2.56-2.25,4.27-2.28,0-.16,.03-.33,.07-.49,.1-.47,.3-.9,.59-1.27-2.73-.22-5.39,1.19-6.74,3.58Z"/></g></svg> |
357 | \ No newline at end of file |
358 | +<<<<<<< data/ubuntu-pro-logo.svg |
359 | +<?xml version="1.0" encoding="UTF-8"?><svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 130.71 34"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#e95420;}.cls-3{fill:none;}</style></defs><g><path d="M31.74,29.47c-1.3,0-2.33-.25-3.1-.76-.77-.51-1.33-1.19-1.67-2.05-.34-.86-.51-1.81-.51-2.87V14.68h1.42v8.92c0,1.59,.36,2.75,1.07,3.49,.71,.74,1.64,1.11,2.8,1.11s2.09-.37,2.8-1.11c.71-.74,1.07-1.9,1.07-3.49V14.68h1.42v9.11c0,1.06-.17,2.02-.51,2.87s-.9,1.54-1.67,2.05-1.81,.76-3.1,.76Z"/><path d="M44.46,29.41c-.63,0-1.19-.03-1.68-.09-.49-.06-.93-.14-1.29-.23-.37-.09-.69-.18-.95-.26V13.2l1.36-.25v6.06c.24-.18,.62-.37,1.15-.57,.53-.2,1.14-.3,1.84-.3,1.04,0,1.93,.24,2.65,.72,.72,.48,1.28,1.15,1.66,2,.38,.85,.57,1.82,.57,2.92,0,1.17-.22,2.18-.67,3.02-.45,.84-1.06,1.49-1.86,1.94-.79,.45-1.72,.68-2.78,.68Zm-.02-1.23c.78,0,1.46-.17,2.04-.51,.58-.34,1.03-.84,1.36-1.5,.33-.66,.49-1.46,.49-2.39,0-.6-.06-1.16-.19-1.69-.13-.53-.33-1-.61-1.41-.28-.41-.64-.73-1.1-.96s-1.01-.34-1.68-.34-1.22,.11-1.73,.33c-.52,.22-.89,.43-1.13,.63v7.56c.21,.06,.52,.12,.94,.19,.42,.07,.95,.1,1.61,.1Z"/><path d="M56.74,29.37c-1.07,0-1.92-.21-2.55-.62-.63-.41-1.07-.99-1.34-1.73-.26-.75-.4-1.61-.4-2.6v-6.06h1.36v5.62c0,1.02,.1,1.83,.3,2.43,.2,.61,.53,1.04,.99,1.32,.46,.27,1.07,.41,1.84,.41,.64,0,1.2-.04,1.67-.1s.77-.13,.9-.19v-9.48h1.36v10.42c-.4,.11-.95,.24-1.63,.38-.68,.14-1.52,.21-2.51,.21Z"/><path d="M64.26,29.16v-10.42c.4-.11,.95-.24,1.64-.38,.69-.14,1.52-.21,2.5-.21,1.1,0,1.96,.21,2.58,.63,.62,.42,1.06,1,1.32,1.74,.26,.75,.39,1.61,.39,2.6v6.04h-1.36v-5.6c0-1.02-.09-1.83-.28-2.44-.19-.61-.51-1.05-.97-1.33-.46-.27-1.09-.41-1.88-.41-.64,0-1.19,.04-1.66,.1-.47,.07-.77,.13-.91,.19v9.48h-1.36Z"/><path d="M79.39,29.39c-.89,0-1.59-.16-2.11-.47s-.88-.78-1.09-1.41-.31-1.42-.31-2.38V15.19l1.36-.25v3.43h4.3v1.15h-4.3v5.74c0,.82,.09,1.44,.27,1.86,.18,.42,.44,.7,.78,.83,.34,.14,.73,.21,1.18,.21,.57,0,1.03-.07,1.38-.21,.35-.14,.62-.26,.81-.35l.33,1.13c-.2,.12-.54,.27-1.02,.43-.49,.16-1.02,.24-1.59,.24Z"/><path d="M88.09,29.37c-1.07,0-1.92-.21-2.55-.62-.63-.41-1.07-.99-1.34-1.73-.26-.75-.4-1.61-.4-2.6v-6.06h1.36v5.62c0,1.02,.1,1.83,.3,2.43,.2,.61,.53,1.04,.99,1.32,.46,.27,1.07,.41,1.84,.41,.64,0,1.2-.04,1.67-.1s.77-.13,.9-.19v-9.48h1.36v10.42c-.4,.11-.95,.24-1.63,.38-.68,.14-1.52,.21-2.51,.21Z"/><path d="M100.67,29.16V14.96c.5-.14,1.09-.24,1.77-.3,.67-.06,1.3-.09,1.89-.09,2.03,0,3.55,.39,4.56,1.18s1.51,1.89,1.51,3.31c0,1.1-.25,1.98-.76,2.64-.51,.66-1.24,1.14-2.18,1.43-.95,.29-2.08,.44-3.41,.44h-1.96v5.6h-1.42Zm1.42-6.83h1.8c1.02,0,1.9-.09,2.65-.26,.75-.17,1.34-.5,1.75-.98,.42-.48,.63-1.17,.63-2.06s-.22-1.51-.66-1.97c-.44-.47-1-.79-1.69-.98-.69-.19-1.42-.28-2.18-.28-.52,0-.96,.02-1.34,.05s-.7,.07-.96,.09v6.39Z"/><path d="M112.84,29.16v-10.3c.35-.15,.83-.31,1.44-.47,.61-.16,1.36-.24,2.24-.24,.29,0,.58,.02,.87,.05,.29,.04,.54,.08,.75,.12s.37,.09,.47,.14l-.27,1.17c-.1-.06-.32-.12-.67-.18-.35-.06-.8-.09-1.36-.09-.58,0-1.05,.04-1.41,.12-.35,.08-.59,.15-.7,.21v9.46h-1.36Z"/><path d="M124.62,29.41c-.96,0-1.81-.23-2.55-.7-.74-.47-1.32-1.12-1.74-1.97s-.64-1.84-.64-2.97,.21-2.13,.64-2.98c.42-.84,1.01-1.5,1.74-1.97s1.59-.71,2.55-.71,1.81,.24,2.56,.71c.74,.47,1.33,1.13,1.74,1.97,.42,.84,.63,1.83,.63,2.98s-.21,2.12-.63,2.97-1,1.51-1.74,1.97c-.75,.47-1.6,.7-2.56,.7Zm0-1.23c.71,0,1.33-.18,1.85-.54,.52-.36,.93-.87,1.21-1.54,.29-.66,.43-1.44,.43-2.33s-.14-1.69-.43-2.35-.69-1.17-1.21-1.54c-.52-.36-1.14-.54-1.85-.54s-1.33,.18-1.85,.54c-.52,.36-.93,.87-1.21,1.54-.29,.66-.43,1.45-.43,2.35s.14,1.67,.43,2.33c.29,.66,.69,1.17,1.21,1.54,.52,.36,1.14,.54,1.85,.54Z"/></g><g><rect class="cls-2" x="0" width="21" height="32"/><rect class="cls-3" x="2.5" y="14" width="16" height="16"/><circle class="cls-1" cx="4.8" cy="21.15" r="2.17"/><circle class="cls-1" cx="13.86" cy="16.39" r="2.17"/><path class="cls-1" d="M9.7,26.75c-1.57-.34-2.87-1.34-3.61-2.75-.58,.26-1.23,.34-1.86,.23,.89,2.19,2.78,3.77,5.1,4.27,.51,.11,1.03,.16,1.54,.16-.4-.52-.62-1.16-.64-1.82-.18-.02-.36-.05-.53-.09Z"/><circle class="cls-1" cx="13.37" cy="26.76" r="2.17"/><path class="cls-1" d="M16.39,25.96c.68-.85,1.15-1.86,1.38-2.93,.4-1.87,.03-3.83-1.03-5.42-.25,.59-.68,1.09-1.22,1.43,.59,1.11,.77,2.38,.5,3.61-.13,.6-.36,1.17-.68,1.68,.51,.42,.87,.98,1.04,1.62Z"/><path class="cls-1" d="M4.63,18.04c.06,0,.11,0,.17,0,.22,0,.44,.02,.66,.07,.35,.08,.69,.21,.99,.4,.98-1.41,2.56-2.25,4.27-2.28,0-.16,.03-.33,.07-.49,.1-.47,.3-.9,.59-1.27-2.73-.22-5.39,1.19-6.74,3.58Z"/></g></svg> |
360 | +======= |
361 | +<?xml version="1.0" encoding="UTF-8"?> |
362 | +<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1579.82 400"> |
363 | + <g> |
364 | + <path d="m381.87,354.01c-11.69,0-21.64-1.78-29.85-5.33-8.22-3.56-14.86-8.47-19.94-14.74-5.08-6.26-8.77-13.59-11.05-21.98-2.29-8.38-3.43-17.4-3.43-27.06v-110.77h17.28v108.49c0,9.65,1.14,18,3.43,25.03,2.29,7.03,5.46,12.83,9.53,17.4,4.06,4.57,8.97,7.96,14.74,10.16,5.76,2.2,12.2,3.3,19.31,3.3s13.55-1.1,19.31-3.3c5.76-2.2,10.67-5.59,14.74-10.16s7.24-10.37,9.53-17.4c2.29-7.03,3.43-15.37,3.43-25.03v-108.49h17.28v110.77c0,9.65-1.14,18.67-3.43,27.06-2.29,8.38-5.97,15.71-11.05,21.98-5.08,6.27-11.73,11.18-19.94,14.74-8.22,3.56-18.17,5.33-29.85,5.33Z"/> |
365 | + <path d="m500.62,226.73c2.88-2.2,7.5-4.53,13.85-6.99,6.35-2.45,13.85-3.68,22.48-3.68,9.48,0,17.91,1.7,25.28,5.08,7.37,3.39,13.59,8.13,18.67,14.23,5.08,6.1,8.93,13.34,11.56,21.72,2.62,8.38,3.94,17.57,3.94,27.57,0,10.67-1.57,20.24-4.7,28.71-3.13,8.47-7.54,15.67-13.21,21.59-5.68,5.93-12.45,10.46-20.32,13.59-7.88,3.13-16.64,4.7-26.3,4.7-11.69,0-21.34-.76-28.96-2.29-7.62-1.52-13.89-3.13-18.8-4.83v-190.04l16.51-3.05v73.68Zm0,107.98c2.54.85,6.31,1.65,11.31,2.41,4.99.76,11.56,1.14,19.69,1.14,14.23,0,25.66-4.61,34.3-13.85,8.64-9.23,12.96-22.49,12.96-39.76,0-7.28-.76-14.18-2.29-20.71-1.52-6.52-3.98-12.19-7.37-17.02-3.39-4.83-7.84-8.68-13.34-11.56-5.51-2.88-12.32-4.32-20.45-4.32-3.9,0-7.62.38-11.18,1.14-3.56.76-6.86,1.74-9.91,2.92-3.05,1.19-5.72,2.46-8,3.81-2.29,1.36-4.19,2.63-5.72,3.81v91.97Z"/> |
366 | + <path d="m726.96,345.63c-4.91,1.36-11.52,2.88-19.82,4.57-8.3,1.69-18.46,2.54-30.49,2.54-9.82,0-18.04-1.44-24.64-4.32-6.61-2.88-11.94-6.94-16.01-12.2-4.06-5.25-6.99-11.6-8.76-19.05-1.78-7.45-2.67-15.67-2.67-24.64v-73.68h16.51v68.34c0,9.32.67,17.19,2.03,23.63,1.35,6.44,3.56,11.65,6.61,15.62,3.05,3.98,6.99,6.86,11.81,8.64,4.83,1.78,10.71,2.67,17.66,2.67,7.79,0,14.56-.42,20.33-1.27,5.76-.85,9.4-1.61,10.92-2.29v-115.34h16.51v126.78Z"/> |
367 | + <path d="m763.39,223.43c4.91-1.35,11.52-2.88,19.82-4.57,8.3-1.69,18.46-2.54,30.49-2.54,9.99,0,18.33,1.44,25.03,4.32,6.69,2.88,12.02,6.99,16.01,12.32,3.98,5.33,6.81,11.73,8.51,19.18,1.69,7.46,2.54,15.67,2.54,24.64v73.42h-16.51v-68.09c0-9.31-.63-17.19-1.91-23.63-1.27-6.44-3.39-11.69-6.35-15.75-2.96-4.07-6.86-6.99-11.69-8.77-4.83-1.78-10.88-2.67-18.17-2.67-7.79,0-14.53.42-20.2,1.27-5.68.85-9.36,1.61-11.05,2.29v115.34h-16.51v-126.78Z"/> |
368 | + <path d="m916.61,218.85h52.34v13.97h-52.34v69.87c0,7.46.63,13.51,1.9,18.17,1.27,4.66,3.09,8.26,5.46,10.8,2.37,2.54,5.25,4.24,8.64,5.08,3.38.85,7.11,1.27,11.18,1.27,6.94,0,12.53-.8,16.77-2.41,4.23-1.61,7.53-3.09,9.91-4.45l4.06,13.72c-2.37,1.52-6.52,3.26-12.45,5.21-5.93,1.95-12.37,2.92-19.31,2.92-8.13,0-14.95-1.06-20.45-3.18-5.51-2.12-9.91-5.34-13.21-9.65-3.3-4.32-5.63-9.69-6.99-16.13-1.36-6.43-2.03-14.06-2.03-22.87v-120.93l16.52-3.05v41.67Z"/> |
369 | + <path d="m1094.4,345.63c-4.91,1.36-11.52,2.88-19.82,4.57-8.3,1.69-18.46,2.54-30.49,2.54-9.82,0-18.04-1.44-24.64-4.32-6.61-2.88-11.94-6.94-16.01-12.2-4.06-5.25-6.99-11.6-8.76-19.05-1.78-7.45-2.67-15.67-2.67-24.64v-73.68h16.51v68.34c0,9.32.67,17.19,2.03,23.63,1.35,6.44,3.56,11.65,6.61,15.62,3.05,3.98,6.99,6.86,11.81,8.64,4.83,1.78,10.71,2.67,17.66,2.67,7.79,0,14.56-.42,20.32-1.27,5.76-.85,9.4-1.61,10.93-2.29v-115.34h16.51v126.78Z"/> |
370 | + <path d="m1241.5,172.61c24.9,0,43.44,4.74,55.64,14.23,12.2,9.49,18.29,22.95,18.29,40.4,0,10-1.78,18.51-5.34,25.53-3.56,7.03-8.64,12.7-15.24,17.02-6.61,4.32-14.7,7.46-24.26,9.4-9.57,1.95-20.37,2.92-32.39,2.92h-23.88v68.09h-17.28v-172.76c6.1-1.69,13.25-2.92,21.47-3.68,8.21-.76,15.88-1.14,22.99-1.14Zm.76,14.99c-6.44,0-11.9.21-16.39.63-4.49.42-8.35.81-11.56,1.14v77.74h21.85c9.31,0,17.74-.55,25.28-1.65,7.54-1.1,13.97-3.13,19.31-6.1,5.34-2.96,9.44-7.07,12.32-12.32,2.88-5.25,4.32-11.94,4.32-20.07s-1.57-14.23-4.7-19.31c-3.14-5.08-7.29-9.1-12.45-12.07-5.17-2.96-11.05-5.04-17.66-6.22-6.61-1.18-13.38-1.78-20.32-1.78Z"/> |
371 | + <path d="m1385.07,216.31c5.42,0,10.54.42,15.37,1.27,4.83.85,8.17,1.7,10.04,2.54l-3.3,14.23c-1.36-.67-4.11-1.4-8.26-2.16-4.15-.76-9.62-1.14-16.39-1.14-7.12,0-12.83.51-17.15,1.52-4.32,1.02-7.16,1.87-8.51,2.54v115.09h-16.51v-125.25c4.23-1.86,10.08-3.77,17.53-5.72,7.45-1.95,16.51-2.92,27.18-2.92Z"/> |
372 | + <path d="m1538.85,284.65c0,10.33-1.48,19.73-4.45,28.2-2.96,8.47-7.11,15.67-12.45,21.6-5.34,5.93-11.65,10.54-18.93,13.85-7.29,3.3-15.33,4.95-24.14,4.95s-16.86-1.65-24.13-4.95c-7.29-3.3-13.59-7.92-18.93-13.85-5.34-5.93-9.49-13.12-12.45-21.6-2.97-8.47-4.45-17.87-4.45-28.2s1.48-19.73,4.45-28.2c2.96-8.47,7.11-15.71,12.45-21.72,5.33-6.01,11.64-10.67,18.93-13.97,7.28-3.3,15.33-4.95,24.13-4.95s16.85,1.65,24.14,4.95c7.28,3.3,13.59,7.96,18.93,13.97,5.34,6.01,9.48,13.25,12.45,21.72,2.96,8.47,4.45,17.87,4.45,28.2Zm-17.53,0c0-16.43-3.81-29.51-11.43-39.25-7.62-9.74-17.96-14.61-31-14.61s-23.37,4.87-31,14.61c-7.62,9.74-11.43,22.83-11.43,39.25s3.81,29.47,11.43,39.13c7.62,9.65,17.95,14.48,31,14.48s23.38-4.83,31-14.48,11.43-22.69,11.43-39.13Z"/> |
373 | + </g> |
374 | + <g> |
375 | + <rect fill="#e95420" x="0" y="0" width="254.06" height="400"/> |
376 | + <rect fill="#e95420" x="30.25" y="169.38" width="193.57" height="193.57"/> |
377 | + <circle fill="white" cx="58.09" cy="255.92" r="26.3"/> |
378 | + <circle fill="white" cx="167.63" cy="198.25" r="26.3"/> |
379 | + <path fill="white" d="m117.41,323.61c-18.95-4.06-34.78-16.16-43.68-33.32-7.01,3.19-14.9,4.16-22.49,2.76,10.77,26.45,33.61,45.66,61.65,51.67,6.15,1.32,12.42,1.96,18.68,1.92-4.83-6.35-7.52-14.01-7.7-21.99-2.17-.24-4.33-.59-6.45-1.05Z"/> |
380 | + <circle fill="white" cx="161.71" cy="323.76" r="26.3"/> |
381 | + <path fill="white" d="m198.31,314.1c8.18-10.31,13.94-22.5,16.71-35.45,4.84-22.59.32-46.29-12.4-65.51-3.03,7.14-8.17,13.17-14.79,17.32,7.1,13.38,9.26,28.82,6.08,43.67-1.56,7.27-4.31,14.12-8.18,20.38,6.19,5.08,10.56,11.91,12.59,19.6Z"/> |
382 | + <path fill="white" d="m56.06,218.2c.67-.04,1.34-.05,2-.05,2.66,0,5.31.28,7.94.85,4.29.92,8.32,2.54,12.01,4.84,11.84-17.03,30.95-27.25,51.65-27.63.11-1.99.38-3.97.79-5.92,1.21-5.63,3.67-10.9,7.19-15.41-33.08-2.62-65.22,14.45-81.59,43.33Z"/> |
383 | + </g> |
384 | +</svg> |
385 | +>>>>>>> data/ubuntu-pro-logo.svg |
386 | diff --git a/debian/changelog b/debian/changelog |
387 | index af14a7c..e284ee7 100644 |
388 | --- a/debian/changelog |
389 | +++ b/debian/changelog |
390 | @@ -1,3 +1,4 @@ |
391 | +<<<<<<< debian/changelog |
392 | software-properties (0.99.40) noble; urgency=medium |
393 | |
394 | * cloudarchive: Enable support for the Caracal Ubuntu Cloud Archive on |
395 | @@ -283,12 +284,28 @@ software-properties (0.99.4) hirsute; urgency=medium |
396 | -- Corey Bryant <corey.bryant@canonical.com> Tue, 03 Nov 2020 08:58:47 -0500 |
397 | |
398 | software-properties (0.99.3) groovy; urgency=medium |
399 | +======= |
400 | +software-properties (0.96.20.12) xenial; urgency=medium |
401 | + |
402 | + * Fix invalid syntax for old Python and unused import. |
403 | + |
404 | + -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Wed, 15 Nov 2023 15:24:09 +0100 |
405 | + |
406 | +software-properties (0.96.20.11) xenial; urgency=medium |
407 | + |
408 | + * Backport of the Ubuntu Pro tab (lp: #2029473) |
409 | + |
410 | + -- Nathan Pratta Teodosio <nathan.teodosio@canonical.com> Wed, 30 Aug 2023 11:29:36 +0200 |
411 | + |
412 | +software-properties (0.96.20.10) xenial-security; urgency=medium |
413 | +>>>>>>> debian/changelog |
414 | |
415 | * SECURITY UPDATE: malicious repo could send ANSI sequences to terminal |
416 | (LP: #1890286) |
417 | - add-apt-repository: strip ANSI sequences from the description. |
418 | - CVE-2020-15709 |
419 | |
420 | +<<<<<<< debian/changelog |
421 | -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Mon, 17 Aug 2020 10:19:34 -0400 |
422 | |
423 | software-properties (0.99.2) groovy; urgency=medium |
424 | @@ -374,10 +391,16 @@ software-properties (0.98.6) focal; urgency=medium |
425 | -- Corey Bryant <corey.bryant@canonical.com> Wed, 13 Nov 2019 16:00:59 -0500 |
426 | |
427 | software-properties (0.98.5) eoan; urgency=medium |
428 | +======= |
429 | + -- Marc Deslauriers <marc.deslauriers@ubuntu.com> Fri, 07 Aug 2020 10:08:35 -0400 |
430 | + |
431 | +software-properties (0.96.20.9) xenial; urgency=medium |
432 | +>>>>>>> debian/changelog |
433 | |
434 | * cloudarchive: Update outdated WEB_LINK that is presented when |
435 | cloud archive is enabled (LP: #1836258). |
436 | |
437 | +<<<<<<< debian/changelog |
438 | -- Corey Bryant <corey.bryant@canonical.com> Fri, 12 Jul 2019 10:02:43 -0400 |
439 | |
440 | software-properties (0.98.4) eoan; urgency=medium |
441 | @@ -546,10 +569,16 @@ software-properties (0.96.30) disco; urgency=medium |
442 | -- Sebastien Bacher <seb128@ubuntu.com> Tue, 15 Jan 2019 10:48:27 +0100 |
443 | |
444 | software-properties (0.96.29) disco; urgency=medium |
445 | +======= |
446 | + -- Corey Bryant <corey.bryant@canonical.com> Fri, 12 Jul 2019 10:15:23 -0400 |
447 | + |
448 | +software-properties (0.96.20.8) xenial; urgency=medium |
449 | +>>>>>>> debian/changelog |
450 | |
451 | * SoftwarePropertiesGtk.py: when checking a package's depends for DKMS also |
452 | pass on an AttributeError (LP: #1807373) |
453 | |
454 | +<<<<<<< debian/changelog |
455 | -- Brian Murray <brian@ubuntu.com> Tue, 11 Dec 2018 14:35:40 -0800 |
456 | |
457 | software-properties (0.96.28) disco; urgency=medium |
458 | @@ -863,18 +892,45 @@ software-properties (0.96.24.10) zesty; urgency=medium |
459 | |
460 | software-properties (0.96.24.9) zesty; urgency=medium |
461 | |
462 | +======= |
463 | + -- Brian Murray <brian@ubuntu.com> Mon, 17 Dec 2018 11:21:26 -0800 |
464 | + |
465 | +software-properties (0.96.20.7) xenial; urgency=medium |
466 | + |
467 | + * software-properties-gtk: |
468 | + - fix the backend code to set the gnome debconf frontend, without which |
469 | + libgtk2-perl goes unused. |
470 | + - depend on libgtk2-perl to ensure it's available, since it was not seeded |
471 | + on the desktop at release time. This is only a Recommends: in zesty, |
472 | + but we need to ensure this isn't ignored on upgrade. |
473 | + LP: #1679784. |
474 | + |
475 | + -- Steve Langasek <steve.langasek@ubuntu.com> Thu, 27 Apr 2017 16:21:42 -0700 |
476 | + |
477 | +software-properties (0.96.20.6) xenial; urgency=medium |
478 | + |
479 | + * Add knowledge of OpenStack releases Pike and Queens. (LP: #1670385) |
480 | + |
481 | +>>>>>>> debian/changelog |
482 | [ Scott Moser & Dimitri John Ledkov ] |
483 | * When failing to retrieve a GPG key, raise an exception such that |
484 | e.g. add-apt-repository can fail when it did not manage to retrieve a |
485 | GPG key for the shortcut repository. LP: #1532855 |
486 | |
487 | +<<<<<<< debian/changelog |
488 | -- Dimitri John Ledkov <xnox@ubuntu.com> Wed, 01 Mar 2017 17:38:45 +0000 |
489 | |
490 | software-properties (0.96.24.8) zesty; urgency=medium |
491 | +======= |
492 | + -- Scott Moser <smoser@ubuntu.com> Mon, 06 Mar 2017 16:56:40 -0500 |
493 | + |
494 | +software-properties (0.96.20.5) xenial; urgency=medium |
495 | +>>>>>>> debian/changelog |
496 | |
497 | * cloudarchive: Enable support for the Ocata Ubuntu Cloud Archive on |
498 | 16.04 (LP: #1645827). |
499 | |
500 | +<<<<<<< debian/changelog |
501 | -- Corey Bryant <corey.bryant@canonical.com> Tue, 29 Nov 2016 13:29:35 -0500 |
502 | |
503 | software-properties (0.96.24.7) yakkety; urgency=medium |
504 | @@ -935,6 +991,11 @@ software-properties (0.96.24.3) yakkety; urgency=medium |
505 | -- Sebastien Bacher <seb128@ubuntu.com> Wed, 17 Aug 2016 11:34:26 +0200 |
506 | |
507 | software-properties (0.96.24.2) yakkety; urgency=medium |
508 | +======= |
509 | + -- Corey Bryant <corey.bryant@canonical.com> Tue, 29 Nov 2016 13:49:16 -0500 |
510 | + |
511 | +software-properties (0.96.20.4) xenial; urgency=medium |
512 | +>>>>>>> debian/changelog |
513 | |
514 | * Do not assume that a distribution adding the PPA of another distribution |
515 | will want the latest series all the time. Instead check if the requested |
516 | @@ -944,6 +1005,7 @@ software-properties (0.96.24.2) yakkety; urgency=medium |
517 | use the same series name. As long as launchpad knows about the series we |
518 | should be fine even if the constraints are a bit lax. |
519 | |
520 | +<<<<<<< debian/changelog |
521 | -- Harald Sitter <sitter@kde.org> Fri, 12 Aug 2016 13:52:41 +0200 |
522 | |
523 | software-properties (0.96.24.1) yakkety; urgency=medium |
524 | @@ -959,6 +1021,11 @@ software-properties (0.96.24) yakkety; urgency=medium |
525 | -- Brian Murray <brian@ubuntu.com> Thu, 23 Jun 2016 10:33:47 -0700 |
526 | |
527 | software-properties (0.96.23) yakkety; urgency=medium |
528 | +======= |
529 | + -- Harald Sitter <sitter@kde.org> Fri, 12 Aug 2016 16:12:07 +0200 |
530 | + |
531 | +software-properties (0.96.20.3) xenial; urgency=medium |
532 | +>>>>>>> debian/changelog |
533 | |
534 | * softwareproperties/ppa.py: |
535 | - fix exception output when `add-apt-repository` is called with |
536 | @@ -967,23 +1034,39 @@ software-properties (0.96.23) yakkety; urgency=medium |
537 | - add network check for tests that require talking to launchpad |
538 | or the cloud archives |
539 | |
540 | +<<<<<<< debian/changelog |
541 | -- Michael Vogt <michael.vogt@ubuntu.com> Wed, 22 Jun 2016 15:42:14 +0200 |
542 | |
543 | software-properties (0.96.22) yakkety; urgency=medium |
544 | +======= |
545 | + -- Brian Murray <brian@ubuntu.com> Fri, 22 Jul 2016 15:27:26 -0700 |
546 | + |
547 | +software-properties (0.96.20.2) xenial; urgency=medium |
548 | +>>>>>>> debian/changelog |
549 | |
550 | * SoftwarePropertiesGtk.py: only add mirror choices if there are mirrors |
551 | available from which to choose. (LP: #1101881) |
552 | * DialogMirror.py: guard against a traceback when get cursor returns None. |
553 | (LP: #1101881) |
554 | |
555 | +<<<<<<< debian/changelog |
556 | -- Brian Murray <brian@ubuntu.com> Mon, 20 Jun 2016 11:08:28 -0700 |
557 | |
558 | software-properties (0.96.21) yakkety; urgency=medium |
559 | +======= |
560 | + -- Brian Murray <brian@ubuntu.com> Tue, 21 Jun 2016 12:22:08 -0700 |
561 | + |
562 | +software-properties (0.96.20.1) xenial; urgency=medium |
563 | +>>>>>>> debian/changelog |
564 | |
565 | * cloudarchive: Enable support for the Newton Ubuntu Cloud Archive on |
566 | 16.04 (LP: #1591382). |
567 | |
568 | +<<<<<<< debian/changelog |
569 | -- Corey Bryant <corey.bryant@canonical.com> Fri, 10 Jun 2016 17:22:43 -0400 |
570 | +======= |
571 | + -- Corey Bryant <corey.bryant@canonical.com> Fri, 10 Jun 2016 17:32:35 -0400 |
572 | +>>>>>>> debian/changelog |
573 | |
574 | software-properties (0.96.20) xenial; urgency=medium |
575 | |
576 | diff --git a/debian/control b/debian/control |
577 | index fcb6123..4690b5b 100644 |
578 | --- a/debian/control |
579 | +++ b/debian/control |
580 | @@ -33,6 +33,7 @@ XS-Testsuite: autopkgtest |
581 | Package: python3-software-properties |
582 | Section: python |
583 | Architecture: all |
584 | +<<<<<<< debian/control |
585 | Depends: gpg, |
586 | iso-codes, |
587 | lsb-release, |
588 | @@ -42,6 +43,12 @@ Depends: gpg, |
589 | python3-launchpadlib, |
590 | ${misc:Depends}, |
591 | ${python3:Depends} |
592 | +======= |
593 | +Depends: ${python3:Depends}, ${misc:Depends}, python3, python3-apt (>= |
594 | + 0.6.20ubuntu16), python3-pycurl, lsb-release, iso-codes, python3-distro-info |
595 | + (>= 0.14ubuntu0.3), ubuntu-advantage-tools (>=27.11~), |
596 | + ubuntu-advantage-desktop-daemon |
597 | +>>>>>>> debian/control |
598 | Recommends: unattended-upgrades |
599 | Description: manage the repositories that you install software from |
600 | This software provides an abstraction of the used apt repositories. |
601 | @@ -75,6 +82,7 @@ Description: manage the repositories that you install software from (common) |
602 | |
603 | Package: software-properties-gtk |
604 | Architecture: all |
605 | +<<<<<<< debian/control |
606 | Depends: gir1.2-goa-1.0 (>= 3.27.92-1ubuntu1), |
607 | gir1.2-gtk-3.0, |
608 | gir1.2-handy-1, |
609 | @@ -92,6 +100,17 @@ Depends: gir1.2-goa-1.0 (>= 3.27.92-1ubuntu1), |
610 | ${python3:Depends} |
611 | Recommends: gnome-keyring, |
612 | gnome-session-bin | xfce4-session | mate-session-manager |
613 | +======= |
614 | +Depends: ${python3:Depends}, ${misc:Depends}, python3, |
615 | + python3-software-properties (= ${binary:Version}), |
616 | + python3-gi, |
617 | + gir1.2-gtk-3.0, |
618 | + python3-aptdaemon.gtk3widgets, |
619 | + software-properties-common, |
620 | + ubuntu-drivers-common (>= 1:0.2.75), |
621 | + python3-gi, |
622 | + libgtk2-perl, |
623 | +>>>>>>> debian/control |
624 | Description: manage the repositories that you install software from (gtk) |
625 | This software provides an abstraction of the used apt repositories. |
626 | It allows you to easily manage your distribution and independent software |
627 | diff --git a/debian/software-properties-gtk.install b/debian/software-properties-gtk.install |
628 | index be53144..fbaac36 100644 |
629 | --- a/debian/software-properties-gtk.install |
630 | +++ b/debian/software-properties-gtk.install |
631 | @@ -2,6 +2,7 @@ |
632 | debian/tmp/usr/bin/software-properties-gtk |
633 | debian/tmp/usr/lib/python3*/*-packages/softwareproperties/gtk/*.py |
634 | debian/tmp/usr/share/applications/software-properties-drivers.desktop |
635 | +<<<<<<< debian/software-properties-gtk.install |
636 | debian/tmp/usr/share/applications/software-properties-gtk.desktop |
637 | debian/tmp/usr/share/applications/software-properties-livepatch.desktop |
638 | debian/tmp/usr/share/glib-2.0/schemas |
639 | @@ -11,3 +12,7 @@ debian/tmp/usr/share/mime/packages |
640 | debian/tmp/usr/share/software-properties/gtkbuilder |
641 | debian/tmp/usr/share/software-properties/ubuntu-pro-logo.svg |
642 | debian/tmp/usr/share/software-properties/ubuntu-pro-logo-dark.svg |
643 | +======= |
644 | +debian/tmp/usr/share/software-properties/ubuntu-pro-logo.svg |
645 | +#debian/tmp/usr/share/gnome/help/software-properties |
646 | +>>>>>>> debian/software-properties-gtk.install |
647 | diff --git a/po/POTFILES.in b/po/POTFILES.in |
648 | index 97ce1bf..ff745a1 100644 |
649 | --- a/po/POTFILES.in |
650 | +++ b/po/POTFILES.in |
651 | @@ -54,3 +54,7 @@ softwareproperties/sourceslist.py |
652 | [type: gettext/glade]data/gtkbuilder/dialog-ua-attach.ui |
653 | [type: gettext/glade]data/gtkbuilder/dialog-ua-detach.ui |
654 | [type: gettext/glade]data/gtkbuilder/dialog-ua-fips-enable.ui |
655 | +<<<<<<< po/POTFILES.in |
656 | +======= |
657 | + |
658 | +>>>>>>> po/POTFILES.in |
659 | diff --git a/softwareproperties/SoftwareProperties.py b/softwareproperties/SoftwareProperties.py |
660 | index d8f7435..d901f54 100644 |
661 | --- a/softwareproperties/SoftwareProperties.py |
662 | +++ b/softwareproperties/SoftwareProperties.py |
663 | @@ -128,7 +128,8 @@ class SoftwareProperties(object): |
664 | " wait for all running threads (PPA key fetchers) to exit " |
665 | for t in threading.enumerate(): |
666 | if t.ident != threading.current_thread().ident: |
667 | - t.join() |
668 | + if not t.daemon: |
669 | + t.join() |
670 | |
671 | def backup_apt_conf(self): |
672 | """Backup all apt configuration options""" |
673 | @@ -682,8 +683,29 @@ class SoftwareProperties(object): |
674 | if channel: |
675 | keyp = "%s/%s.key" % (self.CHANNEL_PATH, channel) |
676 | self.add_key(keyp) |
677 | +<<<<<<< softwareproperties/SoftwareProperties.py |
678 | return True |
679 | return False |
680 | +======= |
681 | + |
682 | + cdata = (shortcut.add_key, {'keyserver': (self.options and |
683 | + self.options.keyserver)}) |
684 | + def addkey_func(): |
685 | + func, kwargs = cdata |
686 | + msg = "Added key." |
687 | + try: |
688 | + ret = func(**kwargs) |
689 | + if not ret: |
690 | + msg = "Failed to add key." |
691 | + except Exception as e: |
692 | + ret = False |
693 | + msg = str(e) |
694 | + self.myqueue.put([ret, msg]) |
695 | + |
696 | + worker = threading.Thread(target=addkey_func) |
697 | + worker.start() |
698 | + return worker |
699 | +>>>>>>> softwareproperties/SoftwareProperties.py |
700 | |
701 | def update_interface(self): |
702 | " abstract interface to keep the UI alive " |
703 | @@ -748,6 +770,19 @@ class SoftwareProperties(object): |
704 | file=new_debsrc_entry.file, |
705 | architectures=new_debsrc_entry.architectures) |
706 | self.set_modified_sourceslist() |
707 | +<<<<<<< softwareproperties/SoftwareProperties.py |
708 | +======= |
709 | + if worker: |
710 | + # wait for GPG key to be downloaded |
711 | + worker.join(30) |
712 | + if worker.isAlive(): |
713 | + # thread timed out. |
714 | + raise shortcuts.ShortcutException("Error: retrieving gpg key timed out.") |
715 | + result, msg = self.myqueue.get() |
716 | + if not result: |
717 | + raise shortcuts.ShortcutException(msg) |
718 | + |
719 | +>>>>>>> softwareproperties/SoftwareProperties.py |
720 | if self.options and self.options.update: |
721 | import apt |
722 | cache = apt.Cache() |
723 | diff --git a/softwareproperties/cloudarchive.py b/softwareproperties/cloudarchive.py |
724 | index 3cbc5f3..ebeabdf 100644 |
725 | --- a/softwareproperties/cloudarchive.py |
726 | +++ b/softwareproperties/cloudarchive.py |
727 | @@ -45,6 +45,7 @@ RELEASE_MAP = { |
728 | 'ocata': 'xenial', |
729 | 'pike': 'xenial', |
730 | 'queens': 'xenial', |
731 | +<<<<<<< softwareproperties/cloudarchive.py |
732 | 'rocky': 'bionic', |
733 | 'stein': 'bionic', |
734 | 'train': 'bionic', |
735 | @@ -57,9 +58,12 @@ RELEASE_MAP = { |
736 | 'antelope': 'jammy', |
737 | 'bobcat': 'jammy', |
738 | 'caracal': 'jammy', |
739 | +======= |
740 | +>>>>>>> softwareproperties/cloudarchive.py |
741 | } |
742 | UCA = "Ubuntu Cloud Archive" |
743 | WEB_LINK = 'https://wiki.ubuntu.com/OpenStack/CloudArchive' |
744 | +<<<<<<< softwareproperties/cloudarchive.py |
745 | |
746 | UCA_ARCHIVE = "http://ubuntu-cloud.archive.canonical.com/ubuntu" |
747 | UCA_PREFIXES = ['cloud-archive', 'uca'] |
748 | @@ -93,6 +97,23 @@ class CloudArchiveShortcutHandler(ShortcutHandler): |
749 | if not self.caname in RELEASE_MAP: |
750 | msg = (_("not a valid cloud-archive: '%s'") % self.caname) |
751 | raise ShortcutException(msg) |
752 | +======= |
753 | +APT_INSTALL_KEY = ['apt-get', '--quiet', '--assume-yes', 'install', |
754 | + 'ubuntu-cloud-keyring'] |
755 | + |
756 | +ALIASES = {'tools-updates': 'tools'} |
757 | +for _r in RELEASE_MAP: |
758 | + ALIASES["%s-updates" % _r] = _r |
759 | + |
760 | +MAP = { |
761 | + 'tools': { |
762 | + 'sldfmt': '%(codename)s-updates/cloud-tools', |
763 | + 'description': UCA + " for cloud-tools (JuJu and MAAS)"}, |
764 | + 'tools-proposed': { |
765 | + 'sldfmt': '%(codename)s-proposed/cloud-tools', |
766 | + 'description': UCA + " for cloud-tools (JuJu and MAAS) [proposed]"} |
767 | +} |
768 | +>>>>>>> softwareproperties/cloudarchive.py |
769 | |
770 | codename = RELEASE_MAP[self.caname] |
771 | validnames = set((codename, os.getenv("CA_ALLOW_CODENAME") or codename)) |
772 | diff --git a/softwareproperties/gtk/DialogUaAttach.py b/softwareproperties/gtk/DialogUaAttach.py |
773 | index d029e64..84d93dc 100644 |
774 | --- a/softwareproperties/gtk/DialogUaAttach.py |
775 | +++ b/softwareproperties/gtk/DialogUaAttach.py |
776 | @@ -25,6 +25,10 @@ from softwareproperties.gtk.utils import setup_ui |
777 | from uaclient.api.u.pro.attach.magic.initiate.v1 import initiate |
778 | from uaclient.api.u.pro.attach.magic.wait.v1 import MagicAttachWaitOptions, wait |
779 | from uaclient.exceptions import MagicAttachTokenError |
780 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
781 | +======= |
782 | +import threading |
783 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
784 | |
785 | class DialogUaAttach: |
786 | def __init__(self, parent, datadir, ua_object): |
787 | @@ -139,8 +143,11 @@ class DialogUaAttach: |
788 | self.attach() |
789 | |
790 | def on_cancel_clicked(self, button): |
791 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
792 | if self.poll: |
793 | GLib.Thread.unref(self.poll) |
794 | +======= |
795 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
796 | self.dialog.response(Gtk.ResponseType.CANCEL) |
797 | |
798 | def poll_for_magic_token(self): |
799 | @@ -148,6 +155,7 @@ class DialogUaAttach: |
800 | try: |
801 | response = wait(options) |
802 | self.contract_token = response.contract_token |
803 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
804 | if self.magic_radio.get_active(): |
805 | GLib.idle_add(self.update_state, "pin_validated") |
806 | except MagicAttachTokenError: |
807 | @@ -155,6 +163,13 @@ class DialogUaAttach: |
808 | GLib.idle_add(self.update_state, "expired") |
809 | except Exception as e: |
810 | print("Error getting the Ubuntu Pro token: ", e, flush = True) |
811 | +======= |
812 | + GLib.idle_add(self.update_state, 'pin_validated') |
813 | + except MagicAttachTokenError: |
814 | + GLib.idle_add(self.update_state, 'expired') |
815 | + except Exception as e: |
816 | + print("Error getting the Ubuntu Pro token: ", e) |
817 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
818 | finally: |
819 | self.poll = None |
820 | |
821 | @@ -163,6 +178,11 @@ class DialogUaAttach: |
822 | if self.poll != None or self.contract_token != None: |
823 | return |
824 | |
825 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
826 | +======= |
827 | + self.contract_token = None |
828 | + |
829 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
830 | # Request a magic attachment and parse relevants fields from response. |
831 | # userCode: The pin the user has to type in <ubuntu.com/pro/attach>; |
832 | # token: Identifies the request (used for polling for it). |
833 | @@ -174,6 +194,7 @@ class DialogUaAttach: |
834 | print("Error retrieving magic token: ", e) |
835 | return |
836 | self.update_state() |
837 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
838 | self.poll = GLib.Thread.new("poll", self.poll_for_magic_token) |
839 | |
840 | def on_radio_toggled(self, button): |
841 | @@ -181,6 +202,13 @@ class DialogUaAttach: |
842 | self.update_state("pin_validated") |
843 | else: |
844 | self.update_state() |
845 | +======= |
846 | + self.poll = threading.Thread(target=self.poll_for_magic_token, daemon=True) |
847 | + self.poll.start() |
848 | + |
849 | + def on_radio_toggled(self, button): |
850 | + self.update_state() |
851 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
852 | |
853 | def on_magic_radio_clicked(self, button): |
854 | self.start_magic_attach() |
855 | @@ -197,7 +225,12 @@ class DialogUaAttach: |
856 | self.start_magic_attach() |
857 | elif self.poll == None: |
858 | # wait() timed out without internet; Restart polling. |
859 | +<<<<<<< softwareproperties/gtk/DialogUaAttach.py |
860 | self.poll = GLib.Thread.new("poll", self.poll_for_magic_token) |
861 | +======= |
862 | + self.poll = threading.Thread(target=self.poll_for_magic_token, daemon=True) |
863 | + self.poll.start() |
864 | +>>>>>>> softwareproperties/gtk/DialogUaAttach.py |
865 | |
866 | def finish(self): |
867 | self.dialog.response(Gtk.ResponseType.OK) |
868 | diff --git a/softwareproperties/gtk/SoftwarePropertiesGtk.py b/softwareproperties/gtk/SoftwarePropertiesGtk.py |
869 | index 0cced00..847f3dc 100644 |
870 | --- a/softwareproperties/gtk/SoftwarePropertiesGtk.py |
871 | +++ b/softwareproperties/gtk/SoftwarePropertiesGtk.py |
872 | @@ -46,7 +46,13 @@ gi.require_version("PackageKitGlib", "1.0") |
873 | from gi.repository import PackageKitGlib as packagekit |
874 | from gi.repository import GObject, Gdk, Gtk, Gio, GLib, Handy |
875 | |
876 | +<<<<<<< softwareproperties/gtk/SoftwarePropertiesGtk.py |
877 | from aptsources.sourceslist import Deb822SourceEntry |
878 | +======= |
879 | +import gi |
880 | +gi.require_version("Gdk", "3.0") |
881 | +from gi.repository import GObject, Gdk, Gtk, Gio, GLib |
882 | +>>>>>>> softwareproperties/gtk/SoftwarePropertiesGtk.py |
883 | |
884 | from .SimpleGtkbuilderApp import SimpleGtkbuilderApp |
885 | from .DialogAdd import DialogAdd |
886 | @@ -252,9 +258,14 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
887 | self.show_distro() |
888 | # Setup and show the Additonal Drivers tab |
889 | self.init_drivers() |
890 | +<<<<<<< softwareproperties/gtk/SoftwarePropertiesGtk.py |
891 | # Setup and show the Ubuntu Pro tab if the serie is a LTS |
892 | if is_current_distro_lts(): |
893 | self.init_ubuntu_pro() |
894 | +======= |
895 | + # Setup and show the Ubuntu Pro tab |
896 | + self.init_ubuntu_pro() |
897 | +>>>>>>> softwareproperties/gtk/SoftwarePropertiesGtk.py |
898 | |
899 | # Connect to switch-page before setting initial tab. Otherwise the |
900 | # first switch goes unnoticed. |
901 | @@ -489,6 +500,57 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
902 | self.handlers[combobox] = combobox.connect( |
903 | "changed", self.on_combobox_updates_subscription_changed) |
904 | |
905 | + status = get_ua_status() |
906 | + if not is_current_distro_lts(): |
907 | + esm_available = False |
908 | + esm_enabled = False |
909 | + else: |
910 | + (infra_available, infra_status) = get_ua_service_status("esm-infra", status=status) |
911 | + (apps_available, apps_status) = get_ua_service_status("esm-apps", status=status) |
912 | + esm_available = bool(infra_available or apps_available) |
913 | + esm_enabled = "enabled" in (infra_status, apps_status) |
914 | + distro = current_distro() |
915 | + if esm_enabled: |
916 | + eol_text = _("Extended Security Maintenance") |
917 | + # EOL date should probably be UA contract expiry. |
918 | + # This is probably sooner than ESM EOL for the distro and |
919 | + # gives software properties dialogs a chance to interact about |
920 | + # renewals if needed. |
921 | + try: |
922 | + # Ignore timezone to simplify formatting python < 3.7 |
923 | + # 3.7 has datetime.fromisoformat() |
924 | + dt, _sep, _tz = status.get("expires", "").partition("+") |
925 | + eol_date = datetime.datetime.strptime( |
926 | + dt, "%Y-%m-%dT%H:%M:%S" |
927 | + ).date() |
928 | + except ValueError: |
929 | + print("Unable to determine UA contract expiry") |
930 | + eol_date = distro.eol |
931 | + else: |
932 | + eol_text = _("Basic Security Maintenance") |
933 | + eol_date = distro.eol |
934 | + self.label_esm_status.set_markup(eol_text) |
935 | + esm_url = "https://ubuntu.com/esm" # Non-EOL LTS generic ESM |
936 | + today = datetime.datetime.now().date() |
937 | + if today >= eol_date: |
938 | + if esm_available: |
939 | + # EOL LTS uses release-specific ESM ubuntu.com/XX-YY |
940 | + distro_ver = distro.version.replace(' LTS', '') |
941 | + esm_url = "https://ubuntu.com/%s" % distro_ver.replace(".", "-") |
942 | + eol_expiry_text = _("Ended %s - extend or upgrade now") % eol_date.strftime("%x") |
943 | + elif today >= eol_date - datetime.timedelta(days=60): |
944 | + eol_expiry_text = _("Ends %s - extend or upgrade soon") % eol_date.strftime("%x") |
945 | + else: |
946 | + eol_expiry_text = _("Active until %s") % eol_date.strftime("%x") |
947 | + self.label_eol.set_label(eol_expiry_text) |
948 | + self.label_esm_subscribe.set_markup( |
949 | + "<a href=\"%s\">%s</a>" % (esm_url, _("Extend…")) |
950 | + ) |
951 | + self.label_esm_subscribe.set_visible( |
952 | + esm_available and not esm_enabled |
953 | + ) |
954 | + eol_expiry_text = _("Ended %s") % eol_date.strftime("%x") |
955 | + |
956 | # setup the server chooser |
957 | cell = Gtk.CellRendererText() |
958 | self.combobox_server.pack_start(cell, True) |
959 | @@ -1281,6 +1343,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
960 | |
961 | self.cancellable = Gio.Cancellable() |
962 | try: |
963 | +<<<<<<< softwareproperties/gtk/SoftwarePropertiesGtk.py |
964 | if removals: |
965 | installs_pending = False |
966 | if installs: |
967 | @@ -1308,6 +1371,16 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
968 | False # ready data |
969 | ) |
970 | |
971 | +======= |
972 | + self.transaction = self.apt_client.commit_packages(install=installs, remove=removals, |
973 | + reinstall=[], purge=[], upgrade=[], downgrade=[]) |
974 | + self.transaction.connect("progress-changed", self.on_driver_changes_progress) |
975 | + self.transaction.connect("cancellable-changed", self.on_driver_changes_cancellable_changed) |
976 | + self.transaction.connect("finished", self.on_driver_changes_finish) |
977 | + self.transaction.connect("error", self.on_driver_changes_error) |
978 | + self.transaction.set_debconf_frontend("gnome") |
979 | + self.transaction.run() |
980 | +>>>>>>> softwareproperties/gtk/SoftwarePropertiesGtk.py |
981 | self.button_driver_revert.set_sensitive(False) |
982 | self.button_driver_apply.set_sensitive(False) |
983 | self.scrolled_window_drivers.set_sensitive(False) |
984 | @@ -1425,6 +1498,7 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
985 | return |
986 | |
987 | pkg = None |
988 | +<<<<<<< softwareproperties/gtk/SoftwarePropertiesGtk.py |
989 | if pkg_name: |
990 | pkg = self.apt_cache[pkg_name] |
991 | # Add the matching linux modules package when available |
992 | @@ -1435,6 +1509,24 @@ class SoftwarePropertiesGtk(SoftwareProperties, SimpleGtkbuilderApp): |
993 | self.driver_changes.append(modules_package_obj) |
994 | except (KeyError, TypeError): |
995 | pass |
996 | +======= |
997 | + try: |
998 | + if pkg_name: |
999 | + pkg = self.apt_cache[pkg_name] |
1000 | + # If the package depends on dkms |
1001 | + # we need to install the correct linux metapackage |
1002 | + # so that users get the latest headers |
1003 | + if 'dkms' in pkg.candidate.record['Depends']: |
1004 | + linux_meta = detect.get_linux(self.apt_cache) |
1005 | + if (linux_meta and |
1006 | + linux_meta not in self.driver_changes): |
1007 | + # Install the linux metapackage |
1008 | + lmp = self.apt_cache[linux_meta] |
1009 | + if not lmp.is_installed: |
1010 | + self.driver_changes.append(lmp) |
1011 | + except (AttributeError, KeyError): |
1012 | + pass |
1013 | +>>>>>>> softwareproperties/gtk/SoftwarePropertiesGtk.py |
1014 | |
1015 | if button.get_active(): |
1016 | if pkg in self.driver_changes: |
1017 | diff --git a/softwareproperties/gtk/UbuntuProPage.py b/softwareproperties/gtk/UbuntuProPage.py |
1018 | index 113fed0..4cf4cf4 100644 |
1019 | --- a/softwareproperties/gtk/UbuntuProPage.py |
1020 | +++ b/softwareproperties/gtk/UbuntuProPage.py |
1021 | @@ -22,7 +22,11 @@ from gettext import gettext as _ |
1022 | import gi |
1023 | gi.require_version("Gtk", "3.0") |
1024 | from gi.repository import GdkPixbuf, Gio, Gtk |
1025 | +<<<<<<< softwareproperties/gtk/UbuntuProPage.py |
1026 | from softwareproperties.gtk.utils import current_distro, is_dark_theme |
1027 | +======= |
1028 | +from softwareproperties.gtk.utils import current_distro |
1029 | +>>>>>>> softwareproperties/gtk/UbuntuProPage.py |
1030 | |
1031 | from .DialogUaAttach import DialogUaAttach |
1032 | from .DialogUaDetach import DialogUaDetach |
1033 | @@ -77,6 +81,7 @@ class UbuntuProPage(object): |
1034 | self.label_ua_usg_status = parent.label_ua_usg_status |
1035 | self.label_ua_usg_description = parent.label_ua_usg_description |
1036 | |
1037 | +<<<<<<< softwareproperties/gtk/UbuntuProPage.py |
1038 | if is_dark_theme(self.stack_ua_attach): |
1039 | ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo-dark.svg'), -1, 50, True) |
1040 | else: |
1041 | @@ -86,6 +91,11 @@ class UbuntuProPage(object): |
1042 | # Display the tab on init which is only on LTS series |
1043 | self.stack_ua_main.set_visible(True) |
1044 | |
1045 | +======= |
1046 | + ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo.svg'), -1, 50, True) |
1047 | + parent.image_ubuntu_pro_logo.set_from_pixbuf(ubuntu_pro_logo) |
1048 | + |
1049 | +>>>>>>> softwareproperties/gtk/UbuntuProPage.py |
1050 | parent.button_ua_attach.connect('clicked', self.on_button_ua_attach_clicked) |
1051 | parent.button_ua_detach.connect('clicked', self.on_button_ua_detach_clicked) |
1052 | self.on_ua_esm_infra_changed_handler = self.switch_ua_esm_infra.connect('notify::active', self.on_ua_esm_infra_changed) |
1053 | diff --git a/softwareproperties/gtk/utils.py b/softwareproperties/gtk/utils.py |
1054 | index 6f67f33..d7c7995 100644 |
1055 | --- a/softwareproperties/gtk/utils.py |
1056 | +++ b/softwareproperties/gtk/utils.py |
1057 | @@ -28,11 +28,24 @@ import json |
1058 | import os |
1059 | import subprocess |
1060 | |
1061 | +<<<<<<< softwareproperties/gtk/utils.py |
1062 | import logging |
1063 | LOG=logging.getLogger(__name__) |
1064 | |
1065 | import time |
1066 | |
1067 | +======= |
1068 | +from gi.repository import Gtk |
1069 | +import aptsources.distro |
1070 | +import distro_info |
1071 | +import json |
1072 | +import os |
1073 | +import subprocess |
1074 | + |
1075 | +import logging |
1076 | +LOG=logging.getLogger(__name__) |
1077 | + |
1078 | +>>>>>>> softwareproperties/gtk/utils.py |
1079 | UA_STATUS_JSON = "/var/lib/ubuntu-advantage/status.json" |
1080 | |
1081 | def setup_ui(self, path, domain): |
1082 | @@ -47,6 +60,7 @@ def setup_ui(self, path, domain): |
1083 | setattr(self, name, o) |
1084 | else: |
1085 | logging.debug("can not get name for object '%s'" % o) |
1086 | +<<<<<<< softwareproperties/gtk/utils.py |
1087 | |
1088 | def has_gnome_online_accounts(): |
1089 | try: |
1090 | @@ -55,16 +69,21 @@ def has_gnome_online_accounts(): |
1091 | except Exception: |
1092 | return False |
1093 | |
1094 | +======= |
1095 | +>>>>>>> softwareproperties/gtk/utils.py |
1096 | def is_current_distro_lts(): |
1097 | distro = aptsources.distro.get_distro() |
1098 | di = distro_info.UbuntuDistroInfo() |
1099 | return di.is_lts(distro.codename) |
1100 | |
1101 | +<<<<<<< softwareproperties/gtk/utils.py |
1102 | def is_current_distro_supported(): |
1103 | distro = aptsources.distro.get_distro() |
1104 | di = distro_info.UbuntuDistroInfo() |
1105 | return distro.codename in di.supported(datetime.now().date()) |
1106 | |
1107 | +======= |
1108 | +>>>>>>> softwareproperties/gtk/utils.py |
1109 | def current_distro(): |
1110 | distro = aptsources.distro.get_distro() |
1111 | di = distro_info.UbuntuDistroInfo() |
1112 | @@ -100,7 +119,12 @@ def get_ua_status(): |
1113 | "Ubuntu Advantage client returned code %d" % result.returncode |
1114 | ) |
1115 | return {} |
1116 | +<<<<<<< softwareproperties/gtk/utils.py |
1117 | status_json = result.stdout |
1118 | +======= |
1119 | + # result.stdout is type bytes, but json.loads only accepts str in <3.6. |
1120 | + status_json = result.stdout.decode('utf-8') |
1121 | +>>>>>>> softwareproperties/gtk/utils.py |
1122 | if not status_json: |
1123 | print( |
1124 | "Warning: no Ubuntu Advantage status found." |
1125 | @@ -146,6 +170,7 @@ def get_ua_service_status(service_name='esm-infra', status=None): |
1126 | if "status" in service: |
1127 | service_status = service["status"] # enabled, disabled or n/a |
1128 | return (available, service_status) |
1129 | +<<<<<<< softwareproperties/gtk/utils.py |
1130 | |
1131 | |
1132 | def retry(exceptions, tries=10, delay=0.1, backoff=2): |
1133 | @@ -185,3 +210,5 @@ def is_dark_theme(widget): |
1134 | if env_gtk_theme != None: |
1135 | return GLib.str_has_suffix(env_gtk_theme, "dark") |
1136 | return Handy.StyleManager.get_default().get_dark() |
1137 | +======= |
1138 | +>>>>>>> softwareproperties/gtk/utils.py |
1139 | diff --git a/softwareproperties/ppa.py b/softwareproperties/ppa.py |
1140 | index 4ec6cb2..8b4cfff 100644 |
1141 | --- a/softwareproperties/ppa.py |
1142 | +++ b/softwareproperties/ppa.py |
1143 | @@ -25,6 +25,7 @@ from gettext import gettext as _ |
1144 | from launchpadlib.launchpad import Launchpad |
1145 | from lazr.restfulclient.errors import (NotFound, BadRequest, Unauthorized) |
1146 | |
1147 | +<<<<<<< softwareproperties/ppa.py |
1148 | from softwareproperties.shortcuthandler import (ShortcutHandler, ShortcutException, |
1149 | InvalidShortcutException) |
1150 | from softwareproperties.sourceslist import SourcesListShortcutHandler |
1151 | @@ -182,8 +183,208 @@ class PPAShortcutHandler(ShortcutHandler): |
1152 | def _match_ppa(self, shortcut): |
1153 | (prefix, _, ppa) = shortcut.rpartition(':') |
1154 | if not prefix.lower() == 'ppa': |
1155 | +======= |
1156 | +from gettext import gettext as _ |
1157 | +from threading import Thread |
1158 | + |
1159 | +from softwareproperties.shortcuts import ShortcutException |
1160 | + |
1161 | +try: |
1162 | + import urllib.request |
1163 | + from urllib.error import HTTPError, URLError |
1164 | + import urllib.parse |
1165 | + from http.client import HTTPException |
1166 | + NEED_PYCURL = False |
1167 | +except ImportError: |
1168 | + NEED_PYCURL = True |
1169 | + import pycurl |
1170 | + HTTPError = pycurl.error |
1171 | + |
1172 | + |
1173 | +DEFAULT_KEYSERVER = "hkp://keyserver.ubuntu.com:80/" |
1174 | +# maintained until 2015 |
1175 | +LAUNCHPAD_PPA_API = 'https://launchpad.net/api/1.0/%s/+archive/%s' |
1176 | +LAUNCHPAD_USER_API = 'https://launchpad.net/api/1.0/%s' |
1177 | +LAUNCHPAD_USER_PPAS_API = 'https://launchpad.net/api/1.0/%s/ppas' |
1178 | +LAUNCHPAD_DISTRIBUTION_API = 'https://launchpad.net/api/1.0/%s' |
1179 | +LAUNCHPAD_DISTRIBUTION_SERIES_API = 'https://launchpad.net/api/1.0/%s/%s' |
1180 | +# Specify to use the system default SSL store; change to a different path |
1181 | +# to test with custom certificates. |
1182 | +LAUNCHPAD_PPA_CERT = "/etc/ssl/certs/ca-certificates.crt" |
1183 | + |
1184 | + |
1185 | +class CurlCallback: |
1186 | + def __init__(self): |
1187 | + self.contents = '' |
1188 | + |
1189 | + def body_callback(self, buf): |
1190 | + self.contents = self.contents + buf |
1191 | + |
1192 | + |
1193 | +class PPAException(Exception): |
1194 | + |
1195 | + def __init__(self, value, original_error=None): |
1196 | + self.value = value |
1197 | + self.original_error = original_error |
1198 | + |
1199 | + def __str__(self): |
1200 | + return repr(self.value) |
1201 | + |
1202 | + |
1203 | +def encode(s): |
1204 | + return re.sub("[^a-zA-Z0-9_-]", "_", s) |
1205 | + |
1206 | +def get_info_from_lp(lp_url): |
1207 | + if NEED_PYCURL: |
1208 | + # python2 has no cert verification so we need pycurl |
1209 | + return _get_https_content_pycurl(lp_url) |
1210 | + else: |
1211 | + # python3 has cert verification so we can use the buildin urllib |
1212 | + return _get_https_content_py3(lp_url) |
1213 | + |
1214 | +def get_ppa_info_from_lp(owner_name, ppa): |
1215 | + lp_url = LAUNCHPAD_PPA_API % (owner_name, ppa) |
1216 | + return get_info_from_lp(lp_url) |
1217 | + |
1218 | +def series_valid_for_distro(distribution, series): |
1219 | + lp_url = LAUNCHPAD_DISTRIBUTION_SERIES_API % (distribution, series) |
1220 | + try: |
1221 | + get_info_from_lp(lp_url) |
1222 | + return True |
1223 | + except PPAException: |
1224 | + return False |
1225 | + |
1226 | +def get_current_series_from_lp(distribution): |
1227 | + lp_url = LAUNCHPAD_DISTRIBUTION_API % distribution |
1228 | + return os.path.basename(get_info_from_lp(lp_url)["current_series_link"]) |
1229 | + |
1230 | + |
1231 | +def _get_https_content_py3(lp_url): |
1232 | + try: |
1233 | + request = urllib.request.Request(str(lp_url), headers={"Accept":" application/json"}) |
1234 | + lp_page = urllib.request.urlopen(request, cafile=LAUNCHPAD_PPA_CERT) |
1235 | + json_data = lp_page.read().decode("utf-8", "strict") |
1236 | + except (URLError, HTTPException) as e: |
1237 | + # HTTPException doesn't have a reason but might have a string |
1238 | + # representation |
1239 | + reason = hasattr(e, "reason") and e.reason or e |
1240 | + raise PPAException("Error reading %s: %s" % (lp_url, reason), e) |
1241 | + return json.loads(json_data) |
1242 | + |
1243 | +def _get_https_content_pycurl(lp_url): |
1244 | + # this is the fallback code for python2 |
1245 | + try: |
1246 | + callback = CurlCallback() |
1247 | + curl = pycurl.Curl() |
1248 | + curl.setopt(pycurl.SSL_VERIFYPEER, 1) |
1249 | + curl.setopt(pycurl.SSL_VERIFYHOST, 2) |
1250 | + curl.setopt(pycurl.WRITEFUNCTION, callback.body_callback) |
1251 | + if LAUNCHPAD_PPA_CERT: |
1252 | + curl.setopt(pycurl.CAINFO, LAUNCHPAD_PPA_CERT) |
1253 | + curl.setopt(pycurl.URL, str(lp_url)) |
1254 | + curl.setopt(pycurl.HTTPHEADER, ["Accept: application/json"]) |
1255 | + curl.perform() |
1256 | + curl.close() |
1257 | + json_data = callback.contents |
1258 | + except pycurl.error as e: |
1259 | + raise PPAException("Error reading %s: %s" % (lp_url, e), e) |
1260 | + return json.loads(json_data) |
1261 | + |
1262 | + |
1263 | +def mangle_ppa_shortcut(shortcut): |
1264 | + ppa_shortcut = shortcut.split(":")[1] |
1265 | + if ppa_shortcut.startswith("/"): |
1266 | + ppa_shortcut = ppa_shortcut.lstrip("/") |
1267 | + user = ppa_shortcut.split("/")[0] |
1268 | + if (user[0] == "~"): |
1269 | + user = user[1:] |
1270 | + ppa_path_objs = ppa_shortcut.split("/")[1:] |
1271 | + ppa_path = [] |
1272 | + if (len(ppa_path_objs) < 1): |
1273 | + ppa_path = ['ubuntu', 'ppa'] |
1274 | + elif (len(ppa_path_objs) == 1): |
1275 | + ppa_path.insert(0, "ubuntu") |
1276 | + ppa_path.extend(ppa_path_objs) |
1277 | + else: |
1278 | + ppa_path = ppa_path_objs |
1279 | + ppa = "~%s/%s" % (user, "/".join(ppa_path)) |
1280 | + return ppa |
1281 | + |
1282 | +def verify_keyid_is_v4(signing_key_fingerprint): |
1283 | + """Verify that the keyid is a v4 fingerprint with at least 160bit""" |
1284 | + return len(signing_key_fingerprint) >= 160/8 |
1285 | + |
1286 | + |
1287 | +class AddPPASigningKey(object): |
1288 | + " thread class for adding the signing key in the background " |
1289 | + |
1290 | + GPG_DEFAULT_OPTIONS = ["gpg", "--no-default-keyring", "--no-options"] |
1291 | + |
1292 | + def __init__(self, ppa_path, keyserver=None): |
1293 | + self.ppa_path = ppa_path |
1294 | + self.keyserver = (keyserver if keyserver is not None |
1295 | + else DEFAULT_KEYSERVER) |
1296 | + |
1297 | + def _recv_key(self, keyring, secret_keyring, signing_key_fingerprint, keyring_dir): |
1298 | + try: |
1299 | + # double check that the signing key is a v4 fingerprint (160bit) |
1300 | + if not verify_keyid_is_v4(signing_key_fingerprint): |
1301 | + print("Error: signing key fingerprint '%s' too short" % |
1302 | + signing_key_fingerprint) |
1303 | + return False |
1304 | + except TypeError: |
1305 | + print("Error: signing key fingerprint does not exist") |
1306 | return False |
1307 | + # then get it |
1308 | + res = subprocess.call(self.GPG_DEFAULT_OPTIONS + [ |
1309 | + "--homedir", keyring_dir, |
1310 | + "--secret-keyring", secret_keyring, |
1311 | + "--keyring", keyring, |
1312 | + "--keyserver", self.keyserver, |
1313 | + "--recv", signing_key_fingerprint, |
1314 | + ]) |
1315 | + return (res == 0) |
1316 | + |
1317 | + def _export_key(self, keyring, export_keyring, signing_key_fingerprint, keyring_dir): |
1318 | + res = subprocess.call(self.GPG_DEFAULT_OPTIONS + [ |
1319 | + "--homedir", keyring_dir, |
1320 | + "--keyring", keyring, |
1321 | + "--output", export_keyring, |
1322 | + "--export", signing_key_fingerprint, |
1323 | + ]) |
1324 | + if res != 0: |
1325 | + return False |
1326 | + return True |
1327 | |
1328 | + def _get_fingerprints(self, keyring, keyring_dir): |
1329 | + cmd = self.GPG_DEFAULT_OPTIONS + [ |
1330 | + "--homedir", keyring_dir, |
1331 | + "--keyring", keyring, |
1332 | + "--fingerprint", |
1333 | + "--batch", |
1334 | + "--with-colons", |
1335 | + ] |
1336 | + output = subprocess.check_output(cmd, universal_newlines=True) |
1337 | + fingerprints = [] |
1338 | + for line in output.splitlines(): |
1339 | + if line.startswith("fpr:"): |
1340 | + fingerprints.append(line.split(":")[9]) |
1341 | + return fingerprints |
1342 | + |
1343 | + def _verify_fingerprint(self, keyring, expected_fingerprint, keyring_dir): |
1344 | + got_fingerprints = self._get_fingerprints(keyring, keyring_dir) |
1345 | + if len(got_fingerprints) > 1: |
1346 | + print("Got '%s' fingerprints, expected only one" % |
1347 | + len(got_fingerprints)) |
1348 | + return False |
1349 | + got_fingerprint = got_fingerprints[0] |
1350 | + if got_fingerprint != expected_fingerprint: |
1351 | + print("Fingerprints do not match, not importing: '%s' != '%s'" % ( |
1352 | + expected_fingerprint, got_fingerprint)) |
1353 | +>>>>>>> softwareproperties/ppa.py |
1354 | + return False |
1355 | + |
1356 | +<<<<<<< softwareproperties/ppa.py |
1357 | (teamname, _, ppaname) = ppa.partition('/') |
1358 | teamname = teamname.lstrip('~') |
1359 | if '/' in ppaname: |
1360 | @@ -194,6 +395,16 @@ class PPAShortcutHandler(ShortcutHandler): |
1361 | if '/' in ppaname: |
1362 | # Path is too long for valid ppa |
1363 | return False |
1364 | +======= |
1365 | + def add_ppa_signing_key(self, ppa_path=None): |
1366 | + """Query and add the corresponding PPA signing key. |
1367 | + |
1368 | + The signing key fingerprint is obtained from the Launchpad PPA page, |
1369 | + via a secure channel, so it can be trusted. |
1370 | + """ |
1371 | + if ppa_path is None: |
1372 | + ppa_path = self.ppa_path |
1373 | +>>>>>>> softwareproperties/ppa.py |
1374 | |
1375 | self.teamname = teamname |
1376 | self.ppaname = ppaname or 'ppa' |
1377 | @@ -221,8 +432,135 @@ class PPAShortcutHandler(ShortcutHandler): |
1378 | path = parsed.path.strip().strip('/').split('/') |
1379 | if len(path) < 2: |
1380 | return False |
1381 | +<<<<<<< softwareproperties/ppa.py |
1382 | self.teamname = path[0] |
1383 | self.ppaname = path[1] |
1384 | +======= |
1385 | + # and add it |
1386 | + trustedgpgd = apt_pkg.config.find_dir("Dir::Etc::trustedparts") |
1387 | + apt_keyring = os.path.join(trustedgpgd, "%s.gpg" % ( |
1388 | + encode(ppa_info["reference"][1:]))) |
1389 | + res = subprocess.call(["apt-key", "--keyring", apt_keyring, "add", |
1390 | + tmp_keyring]) |
1391 | + # cleanup |
1392 | + cleanup(tmp_keyring_dir) |
1393 | + return (res == 0) |
1394 | + |
1395 | + |
1396 | +class AddPPASigningKeyThread(Thread, AddPPASigningKey): |
1397 | + # This class is legacy. There are no users inside the software-properties |
1398 | + # codebase other than a test case. It was left in case there were outside |
1399 | + # users. Internally, we've changed from having a class implement the |
1400 | + # tread to explicitly launching a thread and invoking a method in it |
1401 | + # see check_and_add_key_for_whitelisted_shortcut for how. |
1402 | + def __init__(self, ppa_path, keyserver=None): |
1403 | + Thread.__init__(self) |
1404 | + AddPPASigningKey.__init__(self, ppa_path=ppa_path, keyserver=keyserver) |
1405 | + |
1406 | + def run(self): |
1407 | + self.add_ppa_signing_key(self.ppa_path) |
1408 | + |
1409 | + |
1410 | +def _get_suggested_ppa_message(user, ppa_name): |
1411 | + try: |
1412 | + msg = [] |
1413 | + try: |
1414 | + try: |
1415 | + lp_user = get_info_from_lp(LAUNCHPAD_USER_API % user) |
1416 | + except PPAException: |
1417 | + return _("ERROR: '{user}' user or team does not exist.").format(user=user) |
1418 | + lp_ppas = get_info_from_lp(LAUNCHPAD_USER_PPAS_API % user) |
1419 | + entity_name = _("team") if lp_user["is_team"] else _("user") |
1420 | + if lp_ppas["total_size"] > 0: |
1421 | + # Translators: %(entity)s is either "team" or "user" |
1422 | + msg.append(_("The %(entity)s named '%(user)s' has no PPA named '%(ppa)s'") % { |
1423 | + 'entity' : entity_name, |
1424 | + 'user' : user, |
1425 | + 'ppa' : ppa_name}) |
1426 | + msg.append(_("Please choose from the following available PPAs:")) |
1427 | + for ppa in lp_ppas["entries"]: |
1428 | + msg.append(_(" * '%(name)s': %(displayname)s") % { |
1429 | + 'name' : ppa["name"], |
1430 | + 'displayname' : ppa["displayname"]}) |
1431 | + else: |
1432 | + # Translators: %(entity)s is either "team" or "user" |
1433 | + msg.append(_("The %(entity)s named '%(user)s' does not have any PPA") % { |
1434 | + 'entity' : entity_name, 'user' : user}) |
1435 | + return '\n'.join(msg) |
1436 | + except KeyError: |
1437 | + return '' |
1438 | + except ImportError: |
1439 | + return _("Please check that the PPA name or format is correct.") |
1440 | + |
1441 | + |
1442 | +def get_ppa_info(shortcut): |
1443 | + user = shortcut.split("/")[0] |
1444 | + ppa = "/".join(shortcut.split("/")[1:]) |
1445 | + try: |
1446 | + ret = get_ppa_info_from_lp(user, ppa) |
1447 | + ret["distribution"] = ret["distribution_link"].split('/')[-1] |
1448 | + ret["owner"] = ret["owner_link"].split('/')[-1] |
1449 | + return ret |
1450 | + except (HTTPError, Exception): |
1451 | + msg = [] |
1452 | + msg.append(_("Cannot add PPA: 'ppa:%s/%s'.") % ( |
1453 | + user, ppa)) |
1454 | + |
1455 | + # If the PPA does not exist, then try to find if the user/team |
1456 | + # exists. If it exists, list down the PPAs |
1457 | + raise ShortcutException('\n'.join(msg) + "\n" + |
1458 | + _get_suggested_ppa_message(user, ppa)) |
1459 | + |
1460 | + except (ValueError, PPAException): |
1461 | + raise ShortcutException( |
1462 | + _("Cannot access PPA (%s) to get PPA information, " |
1463 | + "please check your internet connection.") % \ |
1464 | + (LAUNCHPAD_PPA_API % (user, ppa))) |
1465 | + |
1466 | + |
1467 | +class PPAShortcutHandler(object): |
1468 | + def __init__(self, shortcut): |
1469 | + super(PPAShortcutHandler, self).__init__() |
1470 | + try: |
1471 | + self.shortcut = mangle_ppa_shortcut(shortcut) |
1472 | + except: |
1473 | + raise ShortcutException(_("ERROR: '{shortcut}' is not a valid ppa format") |
1474 | + .format(shortcut=shortcut)) |
1475 | + info = get_ppa_info(self.shortcut) |
1476 | + |
1477 | + if "private" in info and info["private"]: |
1478 | + raise ShortcutException( |
1479 | + _("Adding private PPAs is not supported currently")) |
1480 | + |
1481 | + self._info = info |
1482 | + |
1483 | + def info(self): |
1484 | + return self._info |
1485 | + |
1486 | + def expand(self, codename, distro=None): |
1487 | + if (distro is not None |
1488 | + and distro != self._info["distribution"] |
1489 | + and not series_valid_for_distro(self._info["distribution"], codename)): |
1490 | + # The requested PPA is for a foreign distribution. Guess that |
1491 | + # the user wants that distribution's current series. |
1492 | + # This only applies if the local distribution is not the same |
1493 | + # distribution the remote PPA is associated with AND the local |
1494 | + # codename is not equal to the PPA's series. |
1495 | + # e.g. local:Foobar/xenial and ppa:Ubuntu/xenial will use 'xenial' |
1496 | + # local:Foobar/fluffy and ppa:Ubuntu/xenial will use '$latest' |
1497 | + codename = get_current_series_from_lp(self._info["distribution"]) |
1498 | + debline = "deb http://ppa.launchpad.net/%s/%s/%s %s main" % ( |
1499 | + self._info["owner"][1:], self._info["name"], |
1500 | + self._info["distribution"], codename) |
1501 | + sourceslistd = apt_pkg.config.find_dir("Dir::Etc::sourceparts") |
1502 | + filename = os.path.join(sourceslistd, "%s-%s-%s-%s.list" % ( |
1503 | + encode(self._info["owner"][1:]), encode(self._info["distribution"]), |
1504 | + encode(self._info["name"]), codename)) |
1505 | + return (debline, filename) |
1506 | + |
1507 | + def should_confirm(self): |
1508 | + return True |
1509 | +>>>>>>> softwareproperties/ppa.py |
1510 | |
1511 | self._username = handler.username |
1512 | self._password = handler.password |
1513 | @@ -230,9 +568,16 @@ class PPAShortcutHandler(ShortcutHandler): |
1514 | self._set_source_entry(handler.SourceEntry().line) |
1515 | return True |
1516 | |
1517 | +<<<<<<< softwareproperties/ppa.py |
1518 | def _set_auth(self): |
1519 | if self._lp_anon or not self.lpppa.private: |
1520 | return |
1521 | +======= |
1522 | +def shortcut_handler(shortcut): |
1523 | + if not shortcut.startswith("ppa:"): |
1524 | + return None |
1525 | + return PPAShortcutHandler(shortcut) |
1526 | +>>>>>>> softwareproperties/ppa.py |
1527 | |
1528 | if self._username and self._password: |
1529 | return |
1530 | diff --git a/softwareproperties/shortcuts.py b/softwareproperties/shortcuts.py |
1531 | index a6bc034..f0f81cc 100644 |
1532 | --- a/softwareproperties/shortcuts.py |
1533 | +++ b/softwareproperties/shortcuts.py |
1534 | @@ -33,6 +33,11 @@ SHORTCUT_HANDLERS = [ |
1535 | URIShortcutHandler, |
1536 | ] |
1537 | |
1538 | +<<<<<<< softwareproperties/shortcuts.py |
1539 | +======= |
1540 | + def add_key(self, keyserver=None): |
1541 | + return True |
1542 | +>>>>>>> softwareproperties/shortcuts.py |
1543 | |
1544 | def shortcut_handler(shortcut, **kwargs): |
1545 | for handler in SHORTCUT_HANDLERS: |
1546 | diff --git a/tests/test_shortcuts.py b/tests/test_shortcuts.py |
1547 | index f518d69..80f81bb 100644 |
1548 | --- a/tests/test_shortcuts.py |
1549 | +++ b/tests/test_shortcuts.py |
1550 | @@ -5,6 +5,7 @@ import apt |
1551 | from functools import partial |
1552 | import unittest |
1553 | import sys |
1554 | +<<<<<<< tests/test_shortcuts.py |
1555 | import os |
1556 | |
1557 | from aptsources.distro import get_distro |
1558 | @@ -115,7 +116,31 @@ def mock_login_with(*args, **kwargs): |
1559 | |
1560 | lp.people = mock_people |
1561 | return lp |
1562 | +======= |
1563 | +try: |
1564 | + from urllib.request import urlopen |
1565 | + from urllib.error import HTTPError, URLError |
1566 | +except ImportError: |
1567 | + from urllib2 import HTTPError, URLError, urlopen |
1568 | +try: |
1569 | + from http.client import HTTPException |
1570 | +except ImportError: |
1571 | + from httplib import HTTPException |
1572 | |
1573 | +sys.path.insert(0, "..") |
1574 | + |
1575 | +from softwareproperties.SoftwareProperties import shortcut_handler |
1576 | +from softwareproperties.shortcuts import ShortcutException |
1577 | +from mock import patch |
1578 | +>>>>>>> tests/test_shortcuts.py |
1579 | + |
1580 | +def has_network(): |
1581 | + try: |
1582 | + network = urlopen("https://launchpad.net/") |
1583 | + network |
1584 | + except (URLError, HTTPException): |
1585 | + return False |
1586 | + return True |
1587 | |
1588 | class ShortcutsTestcase(unittest.TestCase): |
1589 | enable_source = False |
1590 | @@ -138,6 +163,7 @@ class ShortcutsTestcase(unittest.TestCase): |
1591 | def create_handler(self, line, handler, *args, **kwargs): |
1592 | return handler(line, *args, enable_source=self.enable_source, **kwargs) |
1593 | |
1594 | +<<<<<<< tests/test_shortcuts.py |
1595 | def create_handlers(self, line, handler, *args, **kwargs): |
1596 | handlers = handler if isinstance(handler, list) else [handler] |
1597 | # note, always appends shortcut_handler |
1598 | @@ -205,6 +231,8 @@ class ShortcutsTestcase(unittest.TestCase): |
1599 | for shortcut in self.create_handlers(uri, URIShortcutHandler): |
1600 | self.check_shortcut(shortcut, line, sourcefile=URI_SOURCEFILE) |
1601 | |
1602 | +======= |
1603 | +>>>>>>> tests/test_shortcuts.py |
1604 | @unittest.skipUnless(has_network(), "requires network") |
1605 | def test_shortcut_ppa(self): |
1606 | for ppa in VALID_PPAS: |
1607 | @@ -249,7 +277,9 @@ class ShortcutsTestcase(unittest.TestCase): |
1608 | else: |
1609 | os.environ.pop(key, None) |
1610 | |
1611 | + @unittest.skipUnless(has_network(), "requires network") |
1612 | def test_shortcut_cloudarchive(self): |
1613 | +<<<<<<< tests/test_shortcuts.py |
1614 | for uca in VALID_UCAS: |
1615 | line = UCA_LINE_PROPOSED if 'proposed' in uca else UCA_LINE |
1616 | with self.ca_allow_codename(CODENAME): |
1617 | @@ -276,6 +306,22 @@ class ShortcutsTestcase(unittest.TestCase): |
1618 | |
1619 | class EnableSourceShortcutsTestcase(ShortcutsTestcase): |
1620 | enable_source = True |
1621 | +======= |
1622 | + line = "cloud-archive:folsom" |
1623 | + handler = shortcut_handler(line) |
1624 | + self.assertEqual( |
1625 | + ('deb http://ubuntu-cloud.archive.canonical.com/ubuntu '\ |
1626 | + 'precise-updates/folsom main', |
1627 | + '/etc/apt/sources.list.d/cloudarchive-folsom.list'), |
1628 | + handler.expand("precise", distro="ubuntu")) |
1629 | + |
1630 | + def test_shortcut_exception(self): |
1631 | + with self.assertRaises(ShortcutException): |
1632 | + with patch('softwareproperties.ppa.get_ppa_info_from_lp', |
1633 | + side_effect=lambda *args: HTTPError("url", 404, "not found", [], None)): |
1634 | + shortcut_handler("ppa:mvo") |
1635 | + |
1636 | +>>>>>>> tests/test_shortcuts.py |
1637 | |
1638 | |
1639 | if __name__ == "__main__": |