Merge ~seb128/software-properties:ubuntu-pro-jammy into ~robert-ancell/software-properties:ubuntu-pro-jammy

Proposed by Sebastien Bacher
Status: Merged
Merged at revision: ad71f6cb820c7d867688c64320f2ec985b7c760a
Proposed branch: ~seb128/software-properties:ubuntu-pro-jammy
Merge into: ~robert-ancell/software-properties:ubuntu-pro-jammy
Diff against target: 823 lines (+442/-116)
11 files modified
.gitignore (+2/-0)
data/gtkbuilder/dialog-ua-attach.ui (+152/-75)
data/gtkbuilder/main.ui (+1/-4)
data/ubuntu-pro-logo-dark.svg (+116/-0)
debian/changelog (+9/-2)
debian/control (+1/-0)
debian/software-properties-gtk.install (+1/-0)
softwareproperties/cloudarchive.py (+1/-0)
softwareproperties/gtk/DialogUaAttach.py (+120/-24)
softwareproperties/gtk/UbuntuProPage.py (+27/-10)
softwareproperties/gtk/utils.py (+12/-1)
Reviewer Review Type Date Requested Status
Robert Ancell Pending
Review via email: mp+434789@code.launchpad.net

Description of the change

Updated version include the work for Nathan on the magic attach workflow

To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote :

Uploaded also to https://launchpad.net/~ubuntu-desktop/+archive/ubuntu/ppa since you are on holidays and I don't have upload rights for the existing ppa

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.gitignore b/.gitignore
2index 6f5f004..d55034a 100644
3--- a/.gitignore
4+++ b/.gitignore
5@@ -1,2 +1,4 @@
6 debian/files
7 tests/aptroot/
8+__pycache__
9+software_properties.egg-info
10diff --git a/data/gtkbuilder/dialog-ua-attach.ui b/data/gtkbuilder/dialog-ua-attach.ui
11index 3ae3b1b..b709fd6 100644
12--- a/data/gtkbuilder/dialog-ua-attach.ui
13+++ b/data/gtkbuilder/dialog-ua-attach.ui
14@@ -1,119 +1,196 @@
15-<?xml version="1.0"?>
16+<?xml version="1.0" encoding="UTF-8"?>
17 <interface>
18+ <requires lib="gtk+" version="3.16"/>
19 <object class="GtkDialog" id="dialog_ua_attach">
20- <property name="border_width">18</property>
21+ <property name="can-focus">False</property>
22+ <property name="border-width">18</property>
23 <property name="title" translatable="yes">Enable Ubuntu Pro</property>
24 <property name="resizable">False</property>
25 <property name="modal">True</property>
26- <property name="type_hint">dialog</property>
27- <property name="skip_taskbar_hint">True</property>
28+ <property name="type-hint">dialog</property>
29+ <property name="skip-taskbar-hint">True</property>
30+ <!-- interface-requires gtk+ 3.0 -->
31 <child internal-child="vbox">
32 <object class="GtkBox">
33+ <property name="visible">True</property>
34+ <property name="can-focus">False</property>
35+ <property name="no-show-all">True</property>
36 <property name="orientation">vertical</property>
37- <property name="spacing">18</property>
38+ <child>
39+ <object class="GtkLabel">
40+ <property name="visible">True</property>
41+ <property name="can-focus">True</property>
42+ <property name="label" translatable="yes">To upgrade to Ubuntu Pro, use your existing free personal, or company Ubuntu One account, or provide a token. &lt;a href="https://ubuntu.com/login"&gt;Register a new account&lt;/a&gt;.</property>
43+ <property name="use-markup">True</property>
44+ <property name="wrap">True</property>
45+ <property name="max-width-chars">130</property>
46+ </object>
47+ </child>
48+ <child>
49+ <object class="GtkRadioButton" id="magic_radio">
50+ <property name="label" translatable="yes">Enter code on ubuntu.com/pro/attach</property>
51+ <property name="visible">True</property>
52+ <property name="can-focus">True</property>
53+ <property name="receives-default">False</property>
54+ <property name="margin-top">30</property>
55+ <property name="xalign">0</property>
56+ <property name="group">magic_radio</property>
57+ <signal name="toggled" handler="on_radio_toggled" swapped="no"/>
58+ <signal name="clicked" handler="on_magic_radio_clicked" swapped="no"/>
59+ </object>
60+ </child>
61 <child>
62 <object class="GtkBox">
63 <property name="visible">True</property>
64- <property name="orientation">vertical</property>
65- <property name="spacing">18</property>
66+ <property name="can-focus">False</property>
67+ <property name="orientation">horizontal</property>
68 <child>
69- <object class="GtkLabel">
70+ <object class="GtkBox" id="pin_label_box">
71 <property name="visible">True</property>
72- <property name="label" translatable="yes">Enter your Ubuntu Pro token here.
73-From &lt;a href="https://ubuntu.com/pro"&gt;ubuntu.com/pro&lt;/a&gt; or your system administrator</property>
74- <property name="use_markup">True</property>
75- <property name="xalign">0</property>
76+ <property name="margin-left">20</property>
77+ <property name="margin-top">12</property>
78+ <property name="margin-bottom">8</property>
79+ <property name="can-focus">False</property>
80+ <child>
81+ <object class="GtkLabel" id="pin_label">
82+ <property name="label"> </property>
83+ <property name="visible">True</property>
84+ <property name="selectable">True</property>
85+ <property name="can-focus">False</property>
86+ <property name="halign">start</property>
87+ <property name="margin-left">6</property>
88+ <property name="margin-right">6</property>
89+ <property name="margin-top">4</property>
90+ <property name="margin-bottom">4</property>
91+ <attributes>
92+ <attribute name="scale" value="2"/>
93+ </attributes>
94+ </object>
95+ </child>
96 </object>
97 </child>
98 <child>
99- <object class="GtkGrid">
100+ <object class="GtkFixed">
101 <property name="visible">True</property>
102- <property name="row_spacing">6</property>
103- <property name="column_spacing">12</property>
104+ <property name="valign">center</property>
105+ <property name="margin">3</property>
106+ <property name="margin-left">9</property>
107 <child>
108- <object class="GtkLabel">
109+ <object class="GtkSpinner" id="pin_spinner">
110 <property name="visible">True</property>
111- <property name="label" translatable="yes">Token:</property>
112+ <property name="valign">center</property>
113 </object>
114- <packing>
115- <property name="left_attach">0</property>
116- <property name="top_attach">0</property>
117- </packing>
118 </child>
119 <child>
120- <object class="GtkBox">
121- <property name="visible">True</property>
122- <property name="spacing">12</property>
123- <child>
124- <object class="GtkEntry" id="entry_token">
125- <property name="visible">True</property>
126- <property name="max-width-chars">30</property>
127- <signal name="changed" handler="on_token_entry_changed"/>
128- <signal name="activate" handler="on_token_entry_activate"/>
129- </object>
130- </child>
131- <child>
132- <object class="GtkSpinner" id="spinner">
133- <property name="visible">True</property>
134- </object>
135- </child>
136+ <object class="GtkImage" id="pin_status_icon">
137+ <property name="visible">False</property>
138+ <property name="valign">center</property>
139 </object>
140- <packing>
141- <property name="left_attach">1</property>
142- <property name="top_attach">0</property>
143- </packing>
144 </child>
145+ </object>
146+ </child>
147+ <child>
148+ <object class="GtkLabel" id="pin_status">
149+ <property name="margin">3</property>
150+ <property name="visible">True</property>
151+ <property name="valign">center</property>
152+ <property name="use-markup">True</property>
153+ </object>
154+ </child>
155+ </object>
156+ </child>
157+ <child>
158+ <object class="GtkRadioButton" id="token_radio">
159+ <property name="label" translatable="yes">Or add token manually</property>
160+ <property name="visible">True</property>
161+ <property name="can-focus">True</property>
162+ <property name="receives-default">False</property>
163+ <property name="margin-top">6</property>
164+ <property name="xalign">0</property>
165+ <property name="group">magic_radio</property>
166+ <signal name="toggled" handler="on_radio_toggled" swapped="no"/>
167+ </object>
168+ </child>
169+ <child>
170+ <object class="GtkBox">
171+ <property name="visible">True</property>
172+ <property name="can-focus">False</property>
173+ <property name="no-show-all">True</property>
174+ <child>
175+ <object class="GtkEntry" id="token_field">
176+ <property name="visible">True</property>
177+ <property name="sensitive">False</property>
178+ <property name="can-focus">True</property>
179+ <property name="margin-left">20</property>
180+ <property name="margin-top">12</property>
181+ <property name="margin-bottom">12</property>
182+ <property name="margin-right">4</property>
183+ <property name="width-chars">35</property>
184+ <property name="placeholder-text" translatable="yes">Token</property>
185+ <property name="halign">start</property>
186+ <signal name="activate" handler="on_token_entry_activate" swapped="no"/>
187+ <signal name="changed" handler="on_token_typing" swapped="no"/>
188+ </object>
189+ </child>
190+ <child>
191+ <object class="GtkFixed">
192+ <property name="visible">True</property>
193+ <property name="valign">center</property>
194+ <property name="margin">3</property>
195 <child>
196- <object class="GtkLabel">
197+ <object class="GtkSpinner" id="token_spinner">
198 <property name="visible">True</property>
199- <property name="xalign">0</property>
200- <property name="label" translatable="yes">&lt;a href="https://login.ubuntu.com"&gt;Don't have a token yet? Register&lt;/a&gt;</property>
201- <property name="use_markup">True</property>
202+ <property name="valign">center</property>
203 </object>
204- <packing>
205- <property name="left_attach">1</property>
206- <property name="top_attach">1</property>
207- </packing>
208 </child>
209 <child>
210- <object class="GtkLabel" id="label_attach_error">
211- <property name="visible">True</property>
212- <property name="xalign">0</property>
213- <attributes>
214- <attribute name="foreground" value="red"/>
215- <attribute name="scale" value="0.9"/>
216- </attributes>
217+ <object class="GtkImage" id="token_status_icon">
218+ <property name="visible">False</property>
219+ <property name="valign">center</property>
220 </object>
221- <packing>
222- <property name="left_attach">1</property>
223- <property name="top_attach">2</property>
224- </packing>
225 </child>
226 </object>
227 </child>
228+ <child>
229+ <object class="GtkLabel" id="token_status">
230+ <property name="margin">3</property>
231+ <property name="visible">True</property>
232+ <property name="valign">center</property>
233+ <property name="use-markup">True</property>
234+ </object>
235+ </child>
236 </object>
237 </child>
238- </object>
239- </child>
240- <child internal-child="action_area">
241- <object class="GtkHButtonBox">
242- <property name="visible">True</property>
243- <property name="layout_style">end</property>
244 <child>
245- <object class="GtkButton">
246+ <object class="GtkLabel">
247 <property name="visible">True</property>
248- <property name="label" translatable="yes">Cance_l</property>
249- <property name="use_underline">True</property>
250- <signal name="clicked" handler="on_cancel_clicked"/>
251+ <property name="halign">start</property>
252+ <property name="margin-left">20</property>
253+ <property name="use-markup">True</property>
254+ <property name="label" translatable="yes">From your admin, or from &lt;a href="https://ubuntu.com/pro"&gt;ubuntu.com/pro&lt;/a&gt;</property>
255 </object>
256 </child>
257 <child>
258- <object class="GtkButton" id="button_attach">
259+ <object class="GtkBox">
260 <property name="visible">True</property>
261- <property name="sensitive">False</property>
262- <property name="label" translatable="yes">_Continue</property>
263- <property name="use_underline">True</property>
264- <signal name="clicked" handler="on_attach_clicked"/>
265+ <property name="orientation">horizontal</property>
266+ <property name="halign">end</property>
267+ <child>
268+ <object class="GtkButton" id="cancel">
269+ <property name="visible">True</property>
270+ <property name="margin-right">10</property>
271+ <property name="label" translatable="yes">Cancel</property>
272+ <signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
273+ </object>
274+ </child>
275+ <child>
276+ <object class="GtkButton" id="confirm">
277+ <property name="visible">True</property>
278+ <property name="label" translatable="yes">Confirm</property>
279+ <property name="sensitive">False</property>
280+ <signal name="clicked" handler="on_confirm_clicked" swapped="no"/>
281+ </object>
282+ </child>
283 </object>
284 </child>
285 </object>
286diff --git a/data/gtkbuilder/main.ui b/data/gtkbuilder/main.ui
287index a78bfe2..f508a6c 100644
288--- a/data/gtkbuilder/main.ui
289+++ b/data/gtkbuilder/main.ui
290@@ -1285,7 +1285,7 @@
291 <object class="GtkLabel">
292 <property name="visible">True</property>
293 <property name="label" translatable="yes">&lt;b&gt;This machine is not covered by an Ubuntu Pro subscription.&lt;/b&gt;
294-Receive security updates for over 25,000 Ubuntu packages, on up to 3 machines free for personal use. &lt;a href="https://ubuntu.com/pro"&gt;Learn more&lt;/a&gt;.</property>
295+Receive security updates for over 25,000 Ubuntu packages, free for up to 5 machines. &lt;a href="https://ubuntu.com/pro"&gt;Learn more&lt;/a&gt;.</property>
296 <property name="use_markup">True</property>
297 <property name="wrap">True</property>
298 <property name="max-width-chars">90</property>
299@@ -1376,7 +1376,6 @@ Receive security updates for over 25,000 Ubuntu packages, on up to 3 machines fr
300 <child>
301 <object class="GtkLabel" id="label_ua_esm_infra_error">
302 <property name="visible">False</property>
303- <property name="label" translatable="yes">Could not enable ESM Infra. Please try again.</property>
304 <property name="valign">center</property>
305 <property name="xalign">0</property>
306 <attributes>
307@@ -1414,7 +1413,6 @@ Receive security updates for over 25,000 Ubuntu packages, on up to 3 machines fr
308 <child>
309 <object class="GtkLabel" id="label_ua_esm_apps_error">
310 <property name="visible">False</property>
311- <property name="label" translatable="yes">Could not enable ESM Apps. Please try again.</property>
312 <property name="xalign">0</property>
313 <attributes>
314 <attribute name="foreground" value="red"/>
315@@ -1452,7 +1450,6 @@ Receive security updates for over 25,000 Ubuntu packages, on up to 3 machines fr
316 <child>
317 <object class="GtkLabel" id="label_ua_livepatch_error">
318 <property name="visible">False</property>
319- <property name="label" translatable="yes">Could not enable Livepatch. Please try again.</property>
320 <property name="xalign">0</property>
321 <attributes>
322 <attribute name="foreground" value="red"/>
323diff --git a/data/ubuntu-pro-logo-dark.svg b/data/ubuntu-pro-logo-dark.svg
324new file mode 100644
325index 0000000..49215a9
326--- /dev/null
327+++ b/data/ubuntu-pro-logo-dark.svg
328@@ -0,0 +1,116 @@
329+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
330+<svg
331+ id="Layer_1"
332+ data-name="Layer 1"
333+ viewBox="0 0 1444.23 360.27"
334+ version="1.1"
335+ sodipodi:docname="ubuntu-pro-logo-dark.svg"
336+ inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
337+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
338+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
339+ xmlns="http://www.w3.org/2000/svg"
340+ xmlns:svg="http://www.w3.org/2000/svg">
341+ <sodipodi:namedview
342+ id="namedview39"
343+ pagecolor="#ffffff"
344+ bordercolor="#666666"
345+ borderopacity="1.0"
346+ inkscape:pageshadow="2"
347+ inkscape:pageopacity="0.0"
348+ inkscape:pagecheckerboard="0"
349+ showgrid="false"
350+ inkscape:zoom="1.3155799"
351+ inkscape:cx="722.49505"
352+ inkscape:cy="179.76863"
353+ inkscape:window-width="3072"
354+ inkscape:window-height="1665"
355+ inkscape:window-x="0"
356+ inkscape:window-y="0"
357+ inkscape:window-maximized="1"
358+ inkscape:current-layer="Layer_1" />
359+ <defs
360+ id="defs4">
361+ <style
362+ id="style2">.cls-1{fill:#e95420;}.cls-2{fill:#fff;}.cls-3{fill:#111;}</style>
363+ </defs>
364+ <rect
365+ class="cls-1"
366+ width="233.93"
367+ height="360.27"
368+ id="rect6" />
369+ <circle
370+ class="cls-2"
371+ cx="52.26"
372+ cy="238.51"
373+ r="24.44"
374+ id="circle8" />
375+ <circle
376+ class="cls-2"
377+ cx="154.06"
378+ cy="184.91"
379+ r="24.44"
380+ id="circle10" />
381+ <path
382+ class="cls-2"
383+ d="M107.39,301.42a59.52,59.52,0,0,1-40.6-31A35.22,35.22,0,0,1,45.89,273a80.08,80.08,0,0,0,74.65,49.8,35,35,0,0,1-7.16-20.44A60.26,60.26,0,0,1,107.39,301.42Z"
384+ id="path12" />
385+ <circle
386+ class="cls-2"
387+ cx="148.55"
388+ cy="301.55"
389+ r="24.44"
390+ id="circle14" />
391+ <path
392+ class="cls-2"
393+ d="M182.56,292.58a79.94,79.94,0,0,0,4-93.83,35.16,35.16,0,0,1-13.74,16.09,60,60,0,0,1-2,59.53A35,35,0,0,1,182.56,292.58Z"
394+ id="path16" />
395+ <path
396+ class="cls-2"
397+ d="M50.37,203.46c.62,0,1.24-.05,1.87-.05a35.36,35.36,0,0,1,7.37.78,35,35,0,0,1,11.16,4.5,59.63,59.63,0,0,1,48-25.68,36.52,36.52,0,0,1,.74-5.5,35.3,35.3,0,0,1,6.68-14.32A80.38,80.38,0,0,0,50.37,203.46Z"
398+ id="path18" />
399+ <path
400+ class="cls-3"
401+ d="M347.78,331.73q-16.27,0-27.71-5a47.72,47.72,0,0,1-18.52-13.68,54.81,54.81,0,0,1-10.26-20.41,95.22,95.22,0,0,1-3.19-25.12V164.73h16V265.45a75.46,75.46,0,0,0,3.19,23.23,44.78,44.78,0,0,0,8.84,16.16,34.55,34.55,0,0,0,13.68,9.44,54.06,54.06,0,0,0,35.86,0,34.55,34.55,0,0,0,13.68-9.44,44.78,44.78,0,0,0,8.84-16.16,75.46,75.46,0,0,0,3.19-23.23V164.73h16V267.57a95.22,95.22,0,0,1-3.19,25.12A54.81,54.81,0,0,1,394,313.1a47.76,47.76,0,0,1-18.51,13.68Q364.06,331.73,347.78,331.73Z"
402+ id="path20"
403+ style="fill:#ffffff" />
404+ <path
405+ class="cls-3"
406+ d="M460.55,213.56q4-3.06,12.85-6.49a58,58,0,0,1,20.88-3.42,55.7,55.7,0,0,1,23.47,4.72,48.76,48.76,0,0,1,17.33,13.21,58.28,58.28,0,0,1,10.74,20.17,85.49,85.49,0,0,1,3.65,25.59A76.4,76.4,0,0,1,545.11,294,57.25,57.25,0,0,1,532.84,314,52.66,52.66,0,0,1,514,326.66,65.48,65.48,0,0,1,489.56,331q-16.28,0-26.89-2.12a137.63,137.63,0,0,1-17.45-4.48V148l15.33-2.83Zm0,100.25A68.84,68.84,0,0,0,471,316.05a127.35,127.35,0,0,0,18.28,1.06q19.81,0,31.85-12.86t12-36.91a84.07,84.07,0,0,0-2.13-19.23,44.87,44.87,0,0,0-6.84-15.8,34.25,34.25,0,0,0-12.38-10.73q-7.67-4-19-4a49.31,49.31,0,0,0-10.38,1.06,61.57,61.57,0,0,0-9.19,2.71,51,51,0,0,0-12.74,7.08Z"
407+ id="path22"
408+ style="fill:#ffffff" />
409+ <path
410+ class="cls-3"
411+ d="M673.56,324q-6.84,1.89-18.4,4.24a144.38,144.38,0,0,1-28.3,2.36q-13.68,0-22.88-4a37.07,37.07,0,0,1-14.86-11.32A45.88,45.88,0,0,1,581,297.53a98.64,98.64,0,0,1-2.47-22.88v-68.4h15.33V269.7a108.25,108.25,0,0,0,1.88,21.93q1.89,9,6.14,14.51a23.86,23.86,0,0,0,11,8,47.64,47.64,0,0,0,16.39,2.48,132.49,132.49,0,0,0,18.87-1.18c5.34-.79,8.73-1.5,10.14-2.13V206.25h15.33Z"
412+ id="path24"
413+ style="fill:#ffffff" />
414+ <path
415+ class="cls-3"
416+ d="M710.26,210.49q6.84-1.87,18.4-4.24a144.38,144.38,0,0,1,28.3-2.36q13.92,0,23.24,4a35.73,35.73,0,0,1,14.86,11.44,46.84,46.84,0,0,1,7.9,17.81A103.44,103.44,0,0,1,805.32,260v68.16H790V265A115.58,115.58,0,0,0,788.22,243a36.61,36.61,0,0,0-5.9-14.62,23,23,0,0,0-10.85-8.14q-6.72-2.47-16.87-2.47A128.49,128.49,0,0,0,735.85,219q-7.9,1.17-10.26,2.12V328.19H710.26Z"
417+ id="path26"
418+ style="fill:#ffffff" />
419+ <path
420+ class="cls-3"
421+ d="M855.39,206.25H904v13H855.39v64.87A65.79,65.79,0,0,0,857.16,301a23.36,23.36,0,0,0,5.07,10,16,16,0,0,0,8,4.72,42.53,42.53,0,0,0,10.38,1.18q9.66,0,15.56-2.24a67,67,0,0,0,9.2-4.13l3.78,12.74q-3.31,2.13-11.56,4.83a57.11,57.11,0,0,1-17.93,2.72q-11.32,0-19-3a27.48,27.48,0,0,1-12.26-9,36.72,36.72,0,0,1-6.49-15,104.2,104.2,0,0,1-1.88-21.23V170.4l15.33-2.83Z"
422+ id="path28"
423+ style="fill:#ffffff" />
424+ <path
425+ class="cls-3"
426+ d="M1023.33,324q-6.86,1.89-18.4,4.24a144.49,144.49,0,0,1-28.31,2.36q-13.68,0-22.88-4a37.14,37.14,0,0,1-14.86-11.32,45.87,45.87,0,0,1-8.13-17.69,98.62,98.62,0,0,1-2.48-22.88v-68.4H943.6V269.7a108.17,108.17,0,0,0,1.89,21.93q1.89,9,6.13,14.51a23.91,23.91,0,0,0,11,8A47.64,47.64,0,0,0,979,316.64a132.49,132.49,0,0,0,18.87-1.18q8-1.18,10.14-2.13V206.25h15.34Z"
427+ id="path30"
428+ style="fill:#ffffff" />
429+ <path
430+ class="cls-3"
431+ d="M1156.68,163.32q34.68,0,51.66,13.21t17,37.5q0,13.92-5,23.71a40.35,40.35,0,0,1-14.15,15.8q-9.21,6-22.53,8.73a151.33,151.33,0,0,1-30.07,2.71h-22.17v63.21h-16V167.8a115.14,115.14,0,0,1,19.93-3.42Q1146.77,163.32,1156.68,163.32Zm.71,13.92q-9,0-15.21.59t-10.73,1.06v72.17h20.28a163.68,163.68,0,0,0,23.47-1.53,52.38,52.38,0,0,0,17.93-5.66,28.63,28.63,0,0,0,11.44-11.44q4-7.31,4-18.63,0-10.85-4.37-17.93a32.14,32.14,0,0,0-11.56-11.2,50.62,50.62,0,0,0-16.39-5.78A106.64,106.64,0,0,0,1157.39,177.24Z"
432+ id="path32"
433+ style="fill:#ffffff" />
434+ <path
435+ class="cls-3"
436+ d="M1292.85,203.89a82.18,82.18,0,0,1,14.27,1.18,43.81,43.81,0,0,1,9.32,2.36l-3.07,13.21a34.1,34.1,0,0,0-7.66-2,87.42,87.42,0,0,0-15.22-1.06,71.62,71.62,0,0,0-15.92,1.42,44.62,44.62,0,0,0-7.9,2.35V328.19h-15.33V211.91a113,113,0,0,1,16.27-5.31Q1278,203.9,1292.85,203.89Z"
437+ id="path34"
438+ style="fill:#ffffff" />
439+ <path
440+ class="cls-3"
441+ d="M1438.5,267.34a78.87,78.87,0,0,1-4.13,26.18,58.25,58.25,0,0,1-11.56,20.05,52.56,52.56,0,0,1-17.57,12.85,56.86,56.86,0,0,1-44.81,0,52.6,52.6,0,0,1-17.58-12.85,58.39,58.39,0,0,1-11.55-20.05,85,85,0,0,1,0-52.36A59.72,59.72,0,0,1,1342.85,221a51.86,51.86,0,0,1,17.58-13,56.86,56.86,0,0,1,44.81,0,51.82,51.82,0,0,1,17.57,13,59.57,59.57,0,0,1,11.56,20.17A78.87,78.87,0,0,1,1438.5,267.34Zm-16.28,0q0-22.87-10.61-36.44t-28.78-13.57q-18.16,0-28.77,13.57t-10.62,36.44q0,22.88,10.62,36.32t28.77,13.45q18.17,0,28.78-13.45T1422.22,267.34Z"
442+ id="path36"
443+ style="fill:#ffffff" />
444+</svg>
445diff --git a/debian/changelog b/debian/changelog
446index d269e9c..958decb 100644
447--- a/debian/changelog
448+++ b/debian/changelog
449@@ -1,9 +1,16 @@
450-software-properties (0.99.22.3+ubuntupro5) jammy; urgency=medium
451+software-properties (0.99.22.4+ubuntupro3) jammy; urgency=medium
452
453- * Show Ubuntu Pro settings.
454+ * Show Ubuntu Pro settings, including magic attach, thanks Nathan!
455
456 -- Robert Ancell <robert.ancell@canonical.com> Thu, 29 Sep 2022 13:50:26 +1300
457
458+software-properties (0.99.22.4) jammy; urgency=medium
459+
460+ * cloudarchive: Enable support for the Antelope Ubuntu Cloud Archive on
461+ 22.04 (LP: #1996067).
462+
463+ -- Corey Bryant <corey.bryant@canonical.com> Wed, 09 Nov 2022 09:29:26 -0500
464+
465 software-properties (0.99.22.3) jammy; urgency=medium
466
467 * Fix GPG keys are not shown in Software and Updates (LP: #1970449)
468diff --git a/debian/control b/debian/control
469index a3bace0..4b26817 100644
470--- a/debian/control
471+++ b/debian/control
472@@ -84,6 +84,7 @@ Depends: gir1.2-goa-1.0 (>= 3.27.92-1ubuntu1),
473 python3-gi,
474 python3-software-properties (= ${binary:Version}),
475 software-properties-common,
476+ ubuntu-advantage-tools (>= 27.11~),
477 ubuntu-advantage-desktop-daemon,
478 ubuntu-drivers-common (>= 1:0.9.6),
479 ${misc:Depends},
480diff --git a/debian/software-properties-gtk.install b/debian/software-properties-gtk.install
481index 35ded3e..be53144 100644
482--- a/debian/software-properties-gtk.install
483+++ b/debian/software-properties-gtk.install
484@@ -10,3 +10,4 @@ debian/tmp/usr/share/metainfo/software-properties-gtk.appdata.xml
485 debian/tmp/usr/share/mime/packages
486 debian/tmp/usr/share/software-properties/gtkbuilder
487 debian/tmp/usr/share/software-properties/ubuntu-pro-logo.svg
488+debian/tmp/usr/share/software-properties/ubuntu-pro-logo-dark.svg
489diff --git a/softwareproperties/cloudarchive.py b/softwareproperties/cloudarchive.py
490index 7252470..9f523f3 100644
491--- a/softwareproperties/cloudarchive.py
492+++ b/softwareproperties/cloudarchive.py
493@@ -56,6 +56,7 @@ RELEASE_MAP = {
494 'xena': 'focal',
495 'yoga': 'focal',
496 'zed': 'jammy',
497+ 'antelope': 'jammy',
498 }
499 UCA = "Ubuntu Cloud Archive"
500 WEB_LINK = 'https://wiki.ubuntu.com/OpenStack/CloudArchive'
501diff --git a/softwareproperties/gtk/DialogUaAttach.py b/softwareproperties/gtk/DialogUaAttach.py
502index 4649545..221def4 100644
503--- a/softwareproperties/gtk/DialogUaAttach.py
504+++ b/softwareproperties/gtk/DialogUaAttach.py
505@@ -20,11 +20,11 @@ import os
506 from gettext import gettext as _
507 import gi
508 gi.require_version("Gtk", "3.0")
509-from gi.repository import Gtk
510-
511-from softwareproperties.gtk.utils import (
512- setup_ui,
513-)
514+from gi.repository import Gtk,Gdk,GLib
515+from softwareproperties.gtk.utils import setup_ui
516+from uaclient.api.u.pro.attach.magic.initiate.v1 import initiate
517+from uaclient.api.u.pro.attach.magic.wait.v1 import MagicAttachWaitOptions, wait
518+from uaclient.exceptions import MagicAttachTokenError
519
520 class DialogUaAttach:
521 def __init__(self, parent, datadir, ua_object):
522@@ -35,50 +35,146 @@ class DialogUaAttach:
523 self.dialog = self.dialog_ua_attach
524 self.dialog.set_transient_for(parent)
525
526+ self.contract_token = None
527 self.attaching = False
528+ self.poll = None
529+ self.pin_label_box.override_background_color(Gtk.StateType.NORMAL, Gdk.RGBA(0.5, 0.5, 0.5, 0.5))
530+
531+ self.start_magic_attach()
532
533 def run(self):
534 self.dialog.run()
535 self.dialog.hide()
536
537- def update_state(self):
538- have_token = self.entry_token.get_text() != ''
539- self.button_attach.set_sensitive(have_token and not self.attaching)
540- self.entry_token.set_sensitive(not self.attaching)
541+ def update_state(self, case = None):
542+ """
543+ fail : called by the attachment callback, and it failed.
544+ success: called by the attachment callback, and it succeeded.
545+ expired: called by the token polling when the token expires.
546+ """
547+ if self.token_radio.get_active():
548+ self.pin_label.set_opacity(0)
549+ self.confirm.set_sensitive(self.token_field.get_text() != "" and
550+ not self.attaching)
551+ icon = self.token_status_icon
552+ spinner = self.token_spinner
553+ status = self.token_status
554+ else:
555+ self.pin_label.set_text(self.pin)
556+ self.pin_label.set_opacity(1)
557+ self.confirm.set_sensitive(self.contract_token != None and
558+ not self.attaching)
559+ icon = self.pin_status_icon
560+ spinner = self.pin_spinner
561+ status = self.pin_status
562+
563 if self.attaching:
564- self.spinner.start()
565+ spinner.start()
566 else:
567- self.spinner.stop()
568+ spinner.stop()
569+
570+ def lock_radio_buttons(boolean):
571+ self.token_radio.set_sensitive(not boolean)
572+ self.magic_radio.set_sensitive(not boolean)
573+
574+ lock_radio_buttons(self.attaching)
575+ self.token_field.set_sensitive(not self.attaching
576+ and self.token_radio.get_active())
577+
578+ if (case == "fail"):
579+ status.set_markup('<span foreground="red">%s</span>' % _('Invalid token'))
580+ icon.set_from_icon_name('emblem-unreadable', 1)
581+ elif (case == "success"):
582+ self.finish()
583+ elif (case == "pin_validated"):
584+ status.set_markup('<span foreground="green">%s</span>' % _('Valid token'))
585+ icon.set_from_icon_name('emblem-default', 1)
586+ lock_radio_buttons(True)
587+ elif (case == "expired"):
588+ status.set_markup(_('Code expired'))
589+ icon.set_from_icon_name('gtk-dialog-warning', 1)
590+
591+ #Only show icons/status if case is set
592+ self.token_status_icon.set_visible(False)
593+ self.token_status.set_visible(False)
594+ self.pin_status_icon.set_visible(False)
595+ self.pin_status.set_visible(False)
596+ icon.set_visible(case)
597+ status.set_visible(case)
598
599 def attach(self):
600 if self.attaching:
601 return
602
603- token = self.entry_token.get_text()
604- if token == '':
605- return
606+ if self.token_radio.get_active():
607+ token = self.token_field.get_text()
608+ else:
609+ token = self.contract_token
610
611 self.attaching = True
612- self.label_attach_error.set_text('')
613 def on_reply():
614- self.dialog.response(Gtk.ResponseType.OK)
615+ self.attaching = False
616+ self.update_state("success")
617 def on_error(error):
618- # FIXME
619- print(error)
620- self.label_attach_error.set_text(_('Failed to attach. Please try again'))
621 self.attaching = False
622- self.update_state()
623+ if self.magic_radio.get_active():
624+ self.contract_token = None
625+ self.update_state("fail")
626 self.ua_object.Attach(token, reply_handler=on_reply, error_handler=on_error, dbus_interface='com.canonical.UbuntuAdvantage.Manager', timeout=600)
627 self.update_state()
628
629- def on_token_entry_changed(self, entry):
630- self.update_state()
631+ def on_token_typing(self, entry):
632+ self.confirm.set_sensitive(self.token_field.get_text() != '')
633
634 def on_token_entry_activate(self, entry):
635- self.attach()
636+ token = self.token_field.get_text()
637+ if token != '':
638+ self.attach()
639
640- def on_attach_clicked(self, button):
641+ def on_confirm_clicked(self, button):
642 self.attach()
643
644 def on_cancel_clicked(self, button):
645+ if self.poll:
646+ GLib.Thread.unref(self.poll)
647 self.dialog.response(Gtk.ResponseType.CANCEL)
648+
649+ def poll_for_magic_token(self):
650+ options = MagicAttachWaitOptions(magic_token=self.req_id)
651+ try:
652+ response = wait(options)
653+ self.contract_token = response.contract_token
654+ GLib.idle_add(self.update_state, 'pin_validated')
655+ except MagicAttachTokenError:
656+ GLib.idle_add(self.update_state, 'expired')
657+ finally:
658+ self.poll = None
659+
660+ def start_magic_attach(self):
661+ # Already polling, don't bother the server with a new request.
662+ if self.poll != None or self.contract_token != None:
663+ return
664+
665+ self.contract_token = None
666+
667+ # Request a magic attachment and parse relevants fields from response.
668+ # userCode: The pin the user has to type in <ubuntu.com/pro/attach>;
669+ # token: Identifies the request (used for polling for it).
670+ try:
671+ response = initiate()
672+ self.pin = response.user_code
673+ self.req_id = response.token
674+ except Exception as e:
675+ print(e)
676+ return
677+ self.update_state()
678+ self.poll = GLib.Thread.new("poll", self.poll_for_magic_token)
679+
680+ def on_radio_toggled(self, button):
681+ self.update_state()
682+
683+ def on_magic_radio_clicked(self, button):
684+ self.start_magic_attach()
685+
686+ def finish(self):
687+ self.dialog.response(Gtk.ResponseType.OK)
688diff --git a/softwareproperties/gtk/UbuntuProPage.py b/softwareproperties/gtk/UbuntuProPage.py
689index 1e10c0a..3339297 100644
690--- a/softwareproperties/gtk/UbuntuProPage.py
691+++ b/softwareproperties/gtk/UbuntuProPage.py
692@@ -22,7 +22,7 @@ from gettext import gettext as _
693 import gi
694 gi.require_version("Gtk", "3.0")
695 from gi.repository import GdkPixbuf, Gio, Gtk
696-from softwareproperties.gtk.utils import current_distro
697+from softwareproperties.gtk.utils import current_distro, is_dark_theme
698
699 from .DialogUaAttach import DialogUaAttach
700 from .DialogUaDetach import DialogUaDetach
701@@ -50,13 +50,25 @@ class UbuntuProPage(object):
702 self.switch_ua_esm_infra = parent.switch_ua_esm_infra
703 self.label_ua_esm_infra = parent.label_ua_esm_infra
704 self.label_ua_esm_infra_error = parent.label_ua_esm_infra_error
705+ self.label_ua_esm_infra_error_messages = {
706+ "enable": _("Could not enable ESM Infra. Please try again."),
707+ "disable": _("Could not disable ESM Infra. Please try again."),
708+ }
709 self.switch_ua_esm_apps = parent.switch_ua_esm_apps
710 self.label_ua_esm_apps = parent.label_ua_esm_apps
711 self.label_ua_esm_apps_error = parent.label_ua_esm_apps_error
712+ self.label_ua_esm_apps_error_messages = {
713+ "enable": _("Could not enable ESM Apps. Please try again."),
714+ "disable": _("Could not disable ESM Apps. Please try again."),
715+ }
716 self.switch_ua_livepatch = parent.switch_ua_livepatch
717 self.checkbutton_livepatch_topbar = parent.checkbutton_livepatch_topbar
718 self.label_ua_livepatch = parent.label_ua_livepatch
719 self.label_ua_livepatch_error = parent.label_ua_livepatch_error
720+ self.label_ua_livepatch_error_messages = {
721+ "enable": _("Could not enable Livepatch. Please try again."),
722+ "disable": _("Could not disable Livepatch. Please try again."),
723+ }
724 self.button_ua_fips = parent.button_ua_fips
725 self.label_ua_fips_status = parent.label_ua_fips_status
726 self.label_ua_fips_description = parent.label_ua_fips_description
727@@ -65,7 +77,10 @@ class UbuntuProPage(object):
728 self.label_ua_usg_status = parent.label_ua_usg_status
729 self.label_ua_usg_description = parent.label_ua_usg_description
730
731- ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo.svg'), -1, 50, True)
732+ if is_dark_theme(self.stack_ua_attach):
733+ ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo-dark.svg'), -1, 50, True)
734+ else:
735+ ubuntu_pro_logo = GdkPixbuf.Pixbuf.new_from_file_at_scale(os.path.join(parent.datadir, 'ubuntu-pro-logo.svg'), -1, 50, True)
736 parent.image_ubuntu_pro_logo.set_from_pixbuf(ubuntu_pro_logo)
737
738 parent.button_ua_attach.connect('clicked', self.on_button_ua_attach_clicked)
739@@ -207,7 +222,7 @@ class UbuntuProPage(object):
740 dialog = DialogUaDetach(self._parent.window_main, self._parent.datadir, self.ua_object)
741 dialog.run()
742
743- def set_service_enabled(self, service_name, enabled, error_label):
744+ def set_service_enabled(self, service_name, enabled, error_label, error_label_messages):
745 if error_label is not None:
746 error_label.set_visible(False)
747 service = self.get_service(service_name)
748@@ -217,11 +232,13 @@ class UbuntuProPage(object):
749 service.request_in_progress = False
750 self.update_status()
751 def on_error(error):
752- # FIXME
753 print(error)
754 if error_label is not None:
755 error_label.set_visible(True)
756- error_label.label = error
757+ if enabled:
758+ error_label.set_label(error_label_messages["enable"])
759+ else:
760+ error_label.set_label(error_label_messages["disable"])
761 service.request_in_progress = False
762 self.update_status()
763 if enabled:
764@@ -232,13 +249,13 @@ class UbuntuProPage(object):
765 self.update_status()
766
767 def on_ua_esm_infra_changed(self, switch, param):
768- self.set_service_enabled('esm-infra', self.switch_ua_esm_infra.get_active(), self.label_ua_esm_infra_error)
769+ self.set_service_enabled('esm-infra', self.switch_ua_esm_infra.get_active(), self.label_ua_esm_infra_error, self.label_ua_esm_infra_error_messages)
770
771 def on_ua_esm_apps_changed(self, switch, param):
772- self.set_service_enabled('esm-apps', self.switch_ua_esm_apps.get_active(), self.label_ua_esm_apps_error)
773+ self.set_service_enabled('esm-apps', self.switch_ua_esm_apps.get_active(), self.label_ua_esm_apps_error, self.label_ua_esm_apps_error_messages)
774
775 def on_ua_livepatch_changed(self, switch, param):
776- self.set_service_enabled('livepatch', self.switch_ua_livepatch.get_active(), self.label_ua_livepatch_error)
777+ self.set_service_enabled('livepatch', self.switch_ua_livepatch.get_active(), self.label_ua_livepatch_error, self.label_ua_livepatch_error_messages)
778
779 def on_checkbutton_livepatch_topbar_toggled(self, button):
780 self.update_notifier_settings.handler_block(self.on_update_notifier_settings_changed_handler)
781@@ -268,12 +285,12 @@ class UbuntuProPage(object):
782 if result != Gtk.ResponseType.OK:
783 return
784
785- self.set_service_enabled(service_name, True, None)
786+ self.set_service_enabled(service_name, True, None, None)
787
788 def on_button_ua_usg_clicked(self, button):
789 service = self.get_service('usg')
790 is_enabled = service is not None and service.status == 'enabled'
791- self.set_service_enabled('usg', not is_enabled, None)
792+ self.set_service_enabled('usg', not is_enabled, None, None)
793
794 def on_compliance_and_hardening_expand_changed(self, widget, param):
795 self._parent.window_main.resize(1, 1)
796diff --git a/softwareproperties/gtk/utils.py b/softwareproperties/gtk/utils.py
797index 522faa0..e6eaff6 100644
798--- a/softwareproperties/gtk/utils.py
799+++ b/softwareproperties/gtk/utils.py
800@@ -24,7 +24,7 @@ import distro_info
801 from functools import wraps
802 import gi
803 gi.require_version("Gtk", "3.0")
804-from gi.repository import Gio, Gtk
805+from gi.repository import Gio, Gtk, GLib
806 import json
807 import os
808 import subprocess
809@@ -180,3 +180,14 @@ def retry(exceptions, tries=10, delay=0.1, backoff=2):
810 return f_retry # true decorator
811
812 return deco_retry
813+
814+def is_dark_theme(widget):
815+ env_gtk_theme = GLib.getenv("GTK_THEME")
816+ if env_gtk_theme != None:
817+ return GLib.str_has_suffix(env_gtk_theme, "dark")
818+ screen = Gtk.Widget.get_screen(widget)
819+ settings = Gtk.Settings.get_for_screen(screen)
820+ theme_name = settings.get_property("gtk-theme-name")
821+ if theme_name != None:
822+ return GLib.str_has_suffix(theme_name, "dark")
823+ return False

Subscribers

People subscribed via source and target branches